Closed mandy-chessell closed 1 year ago
thanks - will add to the list and take a look!
Taking the example given, these are the gradle dependenceis (commented out) that don't feature in the maven pom:
implementation project(':open-metadata-implementation:common-services:ffdc-services')
// implementation project(':open-metadata-implementation:common-services:gaf-metadata-management:gaf-metadata-api')
implementation project(':open-metadata-implementation:common-services:gaf-metadata-management:gaf-metadata-client')
// implementation project(':open-metadata-implementation:common-services:ocf-metadata-management:ocf-metadata-api')
implementation project(':open-metadata-implementation:common-services:ocf-metadata-management:ocf-metadata-client')
implementation project(':open-metadata-implementation:frameworks:audit-log-framework')
implementation project(':open-metadata-implementation:frameworks:open-connector-framework')
implementation project(':open-metadata-implementation:access-services:governance-program:governance-program-api')
// implementation 'org.springframework:spring-web'
// compileOnly 'com.fasterxml.jackson.core:jackson-annotations'
With these removals, the first observed failure is:
class file for org.springframework.core.ParameterizedTypeReference not found
In maven the transitive chain that needs this dependency seems to be:
[INFO] org.odpi.egeria:governance-program-client:jar:3.12-SNAPSHOT
[INFO] +- org.odpi.egeria:ffdc-services:jar:3.12-SNAPSHOT:compile
[INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.13.3:compile
[INFO] | | \- com.fasterxml.jackson.core:jackson-core:jar:2.13.3:compile
[INFO] | +- org.odpi.egeria:spring-rest-client-connector:jar:3.12-SNAPSHOT:compile
[INFO] | | +- org.springframework:spring-web:jar:5.3.22:compile
Some useful articles: https://stackoverflow.com/questions/55389699/gradle-multi-project-transitive-dependency https://docs.gradle.org/current/userguide/java_library_plugin.html#sec:java_library_separation https://discuss.gradle.org/t/transitive-project-dependencies-available-at-compile-to-the-depending-project/23981
It seems the issue here is gradle's attempts to stop transitive dependencies leaking into a consumer's classpath -- intentionally, in order to preserve the API that module offers
With maven this leakage occurs, so a consumer isn't aware of those other implementation dependencies.
Requires further analysis - looking at classpath & exploring the 'api' dependency, as well as why spring implementation is exposed, and whether it should be
Similarly for other dependencies in that list
To clarify, when using dependencies, those such as 'api' will pull in the specific dependency listed AND make all of it's dependencies available, whilst 'implementation' will pull in the specific dependency ONLY (maven allows more leakage, which is why we need extra dependencies for gradle)
api could make sense to use when a dependency uses types from another dependency for example, but mostly I think implementation is much more explicit
there are compile only/test only variations of these also
I therefore don't think we need any explicit action on this issue - closing.
I think we may need to revisit this....
Our current gradle build mostly uses 'implementation' for regular build+runtime dependencies (there are of course many other variations for restricting scope to runtime only, test compile etc)
When we build a module in this way, only the classes in the module itself are exposed to it's consumers ie NOT those of it's dependencies. In many cases this makes sense as it avoids leaking implementation detail to consumers
However in some cases dependencies are/need to be exposed publicly & form part of the interface. We see this when we try and consume a module, and HAVE to add another dependency just to get it to work. That tells us that this other module is needed by all consumers, ie it's implementation forms part of the interface (be it at build or runtime)
We have several choices at this point a) We should question why the other module is needed. What knowledge is needed of that dependency by consumers? Is it reasonable to continue requiring consumers to explicitly depend on that module? If so we can leave as is. To some extent being explicit at least makes others aware of the dependency so they can better manage it. b) After analysis we realise we are accidentally requiring this additional dependency & should do some refactoring c) We WANT to expose this additional dependency to all consumers. We therefore change the scope in our module (the one providing the capability) to 'api' (or a related variant). This can make it easier for consumers to use our libraries.
Within egeria main project itself it probably doesn't matter too much, but for those building connectors, third parties consuming our modules, it may be more relevant in terms of docs/usability
I don't think there's any particular action here. Anything to note before we close?
will close
Is there an existing issue for this?
Current Behavior
Gradle seems to need more dependencies listed in each module than Maven. Most importantly, it needs some of the interface definitions used to build a dependency. Maven just needs the single dependency.
On discussion with @planetf1 we are not sure if this is ok or needs further investigation. This issue is just to record an example.
Expected Behavior
Need to understand if this an inherent difference in the gradle build mechanism or something we can influence.
Steps To Reproduce
Compare the dependencies in the pom.xml and build.gradle files in the
governance-program-client
module.Environment
Any Further Information?
No response