Java libraries live in Maven 129 Central as JARs named group:artifact:version. Maven (maven.apache.org (https://maven.apache.org/ 129 ), Apache-2.0, 3.9.16 here; Maven 4 is still a release candidate) declares them in pom.xml; Gradle 19,597 (github.com/gradle/gradle (https://github.com/gradle/gradle 18,860 ), Apache-2.0, 9.7.1 here) in a Kotlin or Groovy script. Every JAR shares one classpath, so, like Python, Java must pick one version of each library, and the two tools pick differently. Declare the same two libraries, gson first, in both.
<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.14.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>33.7.1-jre</version>
</dependency>
</dependencies>plugins { java }
repositories { mavenCentral() }
dependencies {
implementation("com.google.code.gson:gson:2.14.0")
implementation("com.google.guava:guava:33.7.1-jre")
}
dependencyLocking { lockAllConfigurations() }cd ~/v5-ch1/java-demo && mvn -B -q dependency:tree -DoutputFile=tree.txt
grep error_prone tree.txt
cd ~/v5-ch1/gradle-demo
gradle -q dependencies --configuration runtimeClasspath --write-locks | grep error_prone| \- com.google.errorprone:error_prone_annotations:jar:2.48.0:compile
| \--- com.google.errorprone:error_prone_annotations:2.48.0 -> 2.50.0
+--- com.google.errorprone:error_prone_annotations:2.50.0gson wants error_prone_annotations 2.48.0 and guava wants 2.50.0. Maven applies nearest wins (the shallowest declaration, then the first declared), so it silently took the older 2.48.0 because gson came first. Gradle applies highest wins (2.48.0 -> 2.50.0). Reordering pom.xml changes what Maven ships, so pin key versions in <dependencyManagement>. Maven has no lockfile; Gradle's is opt-in, and --write-locks recorded 2.50.0 in gradle.lockfile.