Open spring-projects-issues opened 7 years ago
Oliver Drotbohm commented
That's good feedback and we've been thinking about splitting up Commons for quite a while already, we've just never been sure where to draw the lines as a typical Spring Data user would end up just including all of the modules again. So feedback like this is appreciated.
I am still torn on the effort this creates VS. the gain we get. On your downside, there's basically the need to manually exclude the Spring artifacts from your dependency. With the current arrangement, I don't think you can get rid off spring-core
as we heavily use the assertion types provided by Spring. On our downside, we'd have to relatively artificially keep some types in our codebase free from core Spring dependencies, which creates effort and hardly anyone cares about as people usually just use Spring Data as application level library.
What also plays into this is that an API artifact would definitely need to include core repository interfaces as well, as they are the types that make up the API of Spring Data, not Page
and Pageable
necessarily. Within those, we have a couple of references to Spring Framework that we can't easily get rid of (e.g. @Indexed
).
Is there a real practical benefit in being able to get rid off the dependencies to spring-beans
and spring-core
given the fact that the types we depend on are very unlikely to change, i.e. even using a library that depends on Spring Data Commons just for compiling and using Pageable
with a different major version of Spring shouldn't be a problem.
To round things off: the 2.0 branch already gets rid of Converter
in Page
in favor of the (now available as we compile with JDK 8 compatibility) Function
type
Benjamin Schmeling commented
To clarify the project structure. There are at least two artifacts:
A Java client which wants to consume the services should ideally just rely on the interfaces defined in Service-api.jar. The implementation can be Service-impl.jar or any other possible implementation of the interfaces defined in Service-api.jar (such as an implementation of the interfaces which will delegate the business logic to some remote cloud services). That is why we should avoid any dependent libraries introduced by the framework which was used by the implementation (in this case Spring Data).
However, when removing Page and Pageable from the service interfaces in order to get rid of the dependencies, Page and Pageable types must be replaced by some custom types holding the page data. This is especially cumbersome if you add a REST interface implemented with Spring MVC on top of your services because you would profit from using Spring Page and Pageable. In this case you would face the following:
This scenario should motivate the requirement I've described in this ticket.
So as far as I can imagine, at least for this scenario, we won't need to include any repository interface into Service-api.jar.
Good to hear that Converter is removed from Page though and many thanks for your response!
Oliver Drotbohm commented
If I get you right, your API project could just include Spring Data Commons and manually exclude spring-core
and spring-beans
and then just use Page
and Pageable
, right? So while I get what you're after and applaud the intention, I think this it's way less effort to do just that instead of a split up of the JAR. Especially as you might be perfectly fine with Page
and Pageable
but I'm pretty sure other would then like to see additional types moved into that to-be-created JAR
Benjamin Schmeling commented
Yes that would be acceptable for my scenario. To see whether it is possible we must analyse all dependencies from Page and Pageable. I've learned that with the new 2.0 branch the converter has already been removed. Furthermore, there might be other dependencies from classes referenced by Page and Pageable such as Sort and Order which we should take into consideration.
Generally, the decision of splitting your Spring Data Commons jar into implementation and api could still be an interesting option. One advantage would be to avoid the introduction of new dependencies for Pageable and Page in the future. I think it would be helpful to find other pros and cons for such a decision and to hear the oppinion from other people who faced a similar requirement like me
Benjamin Schmeling commented
I've collected a list of interfaces which would be interesting candidates for a separate api jar, to get a feeling on how many interfaces we are talking about:
Benjamin Schmeling commented
In the meantime, I've tested your "manual exclusion approach" with the new 2.0 version. I've excluded spring-core and spring-beans from the data-commons dependency in my example projects as follows:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
</exclusions>
</dependency>
The results of my test showed that I could use Pageable, Page, Slice, Sort, Order, and Direction without any compile errors. So I can finally say that it works and is sufficient for the Service-api.jar artifact case.
In summary, introducing a Spring Data Commons API project would probably cause too much overhead in this regard. As a small step into the right direction I would propose to move the above mentioned classes/interfaces in package org.springframework.data.domain to a new package org.springframework.data.domain.api. This would clarify the separation between Spring-independent classes/interfaces and their implementation/Spring-specific classes. The classes PageRequest and PageImpl, for example, would stay in the org.springframework.data.domain package. They must not be used in the Service-api.jar artifact because they depend on org.springframework.util.Assert;. It is only safe to use classes/ interfaces from the org.springframework.data.domain.api outside a Spring context.
Btw. I saw that the (unnecessary?) imports for org.springframework.core.convert.converter.Converter are still there in classes Page and Slice
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Benjamin Schmeling opened DATACMNS-1054 and commented
When using Spring Data, the Pageable and Page interfaces are often part of a project's public API. If you extract your API into a separate project in order to decouple it from the underlying implementation, you will introduce a dependency to Spring Data Commons (that's okay since it contains the aforementioned interfaces) but also to its transitive dependencies Spring Core and Spring Beans.
If you use Page and Pageable in your API project and want to avoid introducing dependencies to Spring Core and Spring Beans you would have to redefine the interfaces and transform them back and forth to Spring interfaces in order to leverage Spring Data's paging and sorting features.
Currently, if you want to use Page and Pageable in your API and want to avoid introducing dependencies to Spring Core and Spring Beans you would have to redefine the interfaces and transform the back and forth to Spring interfaces in order to leverage Spring Data's paging and sorting features.
That said, I would propose to introduce something like an additional Spring Data Commons Api project to which you could move all technology neutral interfaces of Spring Data (maybe there are other potential candidates). To move the Page interface into a future Spring Data Commons Api the dependency to org.springframework.core.convert.converter.Converter would have to be removed.
No further details from DATACMNS-1054