cloud-sql-jdbc-socket-factory icon indicating copy to clipboard operation
cloud-sql-jdbc-socket-factory copied to clipboard

The top-level pom.xml should define dependencyManagement and subprojects should use it

Open suztomo opened this issue 2 years ago • 6 comments

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

suztomo avatar Apr 18 '22 21:04 suztomo

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.

kurtisvg avatar Apr 18 '22 21:04 kurtisvg

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?

suztomo avatar Apr 18 '22 22:04 suztomo

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.

kurtisvg avatar Apr 19 '22 15:04 kurtisvg

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.)

suztomo avatar Apr 19 '22 17:04 suztomo

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.

kurtisvg avatar Apr 19 '22 19:04 kurtisvg

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 avatar Apr 19 '22 19:04 suztomo

@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.

ttosta-google avatar Jan 30 '24 21:01 ttosta-google