cloud-sql-jdbc-socket-factory
cloud-sql-jdbc-socket-factory copied to clipboard
The top-level pom.xml should define dependencyManagement and subprojects should use it
Feature Description
The top-level pom.xml should declare dependencyManagement and the subprojects should use the versions defined there.
Alternatives Considered
N/A
Additional Context
Without a single place for dependencyManagement, I would have to write duplicate configuration for a dependency in many places. Example: https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/pull/805/commits/51f5612252700ca0307fdf58e7d6883d08d8590c
I don't think we actually want to do this - many of the child artifacts have different dependencies and thus different dependency conflicts, which is why we refactored the dependency management sections into the child poms - so we could limit them to the ones needed for those child artifacts.
Declaring artifacts in the "dependencyManagement" section doesn't add new dependencies to a project. Only when a project declares new artifacts in the "dependencies" section, it adds new dependencies. The "dependencyManagement" section at the root pom.xml (the parent POM of subprojects) just helps to set consistent versions across different Maven projects.
Currently (somehow) each project defines its own dependencyManagement section and use the libraries in dependencies section. For example, the artifact "io.netty:netty-handler" currently appears in
- r2dbc/sqlserver/pom.xml's dependencyManagement section with version 4.1.75.Final
- r2dbc/sqlserver/pom.xml's dependencies section
- r2dbc/core/pom.xml's dependencyManagement section with version 4.1.75.Final
- r2dbc/core/pom.xml's dependencies section
- r2dbc/mysql/pom.xml's dependencyManagement section with version 4.1.75.Final
- r2dbc/mysql/pom.xml's dependencies section
- r2dbc/postgres/pom.xml's dependencyManagement section with version 4.1.75.Final
- r2dbc/postgres/pom.xml's dependencies section
This issue 818 proposes them to be:
- (top-level) pom.xml's dependencyManagement section with version 4.1.75.Final
- r2dbc/sqlserver/pom.xml's dependencies section
- r2dbc/core/pom.xml's dependencies section
- r2dbc/mysql/pom.xml's dependencies section
- r2dbc/postgres/pom.xml's dependencies section
It's more clear that the top-level pom.xml defines the version and the child projects reference it.
different dependency conflicts
I want to know more about the conflicts. During https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/pull/817, the only conflict I noticed was mysql-connector-java 5.1.49 for jdbc/mysql-j-5 and mysql-connector-java 8.0.17 for jdbc/mysql-j-8. This is a good example not to use dependencyManagement at the root. However, I observe that other dependencies (such as Netty, Guava, reactive-streams, Truth, JUnit etc.) are all pointing to the same versions across the subprojects. The subprojects will benefit from consistent versions of them set by the root pom.xml.
What do you think?
It's more clear that the top-level pom.xml defines the version and the child projects reference it.
I don't think it's actually more clear, because rather than being in the project itself it's in the root project that's 2 folders away. This is maybe okay if you want/care about downstream dependencies to all be the same. But that's not really necessary for us here because the child artifacts are rarely used together.
So for example, let's say there becomes some conflict in the r2dbc/postgres artifact over "Netty". If I pin the version of Netty in the parent pom, it'll be pinned for all of the children, including r2dbc/mysql. But mysql doesn't necessarily have the conflict because the r2dbc/mysql driver has different dependencies. With the dependencies in a parent pom, we're essentially forces to pin all at once or none.
Keeping them all the same isn't really an issue because Renovate handles it, or we can use the mvn versions
plugin from the root folder.
I think now I get your idea. The "dependency conflicts" you mention seems to be the errors from the dependencyConvergence enforcer rule. Currently this repository uses dependencyManagement section to control (or suppress) the errors. On the other hand, I was referencing dependencyManagement section to bring consistent dependency versions across child projects.
exclusions v.s. dependencyManagement
By the way, the dependencyConvergence rule document (https://maven.apache.org/enforcer/enforcer-rules/dependencyConvergence.html) explains that you control the errors via "exclusions" elements. In fact, this is more library user-friendly, because the "exclusions" brings the dependency convergence to library users while "dependencyManagement" doesn't. With dependencyManagement section, the users still have different versions of dependencies appearing in dependency graph. Among the versions, users' Maven chooses the closest one to the project and users' Gradle chooses the highest version, not the one specified in dependencyManagement in the child projects of this repository. (This issue 818 doesn't solve that.)
Hmm, I'll have to take a look. I believe these sections are largely for when we compile uberjars so that the dependencies added are a bit more deterministic.
Sure, take your time. If your dependencyManagement section is for uberjars (not for dependencyConvergence for library users) then the discussion of "exclusions v.s. dependencyManagement" doesn't apply, (and I believe this issue 818 helps to reduce the version declaration of dependencies).
@suztomo I agree with your suggestion, it is working #1815. Let me know if you have any concerns/suggestions.
I'm interested to hear your thoughts @kolea2.