-
Notifications
You must be signed in to change notification settings - Fork 76
Linkage Checker Enforcer Rule Tutorial
In this tutorial, you’ll learn how to use the enforcer rule to statically detect Java diamond dependency conflicts. The target audience is Java developers who already know Git, Maven command (mvn
), and JDK 8.
Checkout project via Git. Our project contains example-problems
directory.
$ git clone https://github.com/GoogleCloudPlatform/cloud-opensource-java.git
$ cd cloud-opensource-java/example-problems/no-such-method-error-signature-mismatch
The following commands assume that this no-such-method-error-signature-mismatch
as current working directory.
Compile and run the project. You observe NoSuchMethodError
:
# in no-such-method-error-signature-mismatch directory
$ mvn clean compile exec:java
...
java.lang.NoSuchMethodError: com.google.common.base.Verify.verify(ZLjava/lang/String;Ljava/lang/Object;)V
at io.grpc.internal.DnsNameResolver.maybeChooseServiceConfig (DnsNameResolver.java:514)
at io.grpc.internal.App.main (App.java:31)
...
[INFO] BUILD FAILURE
Now you have a Maven project with a diamond dependency conflict.
(This section can be skipped if you just want to learn Linkage Checker Enforcer Rule.)
Linkage Checker Enforcer Rule Tutorial Problem Diagnosis
The project already has the Linkage Checker Enforcer Rule in its plugin
element to the pom.xml. Run the enforcer rule as below.
# in no-such-method-error-signature-mismatch directory
$ mvn verify
...
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-linkage-checker) @ no-such-method-error-example ---
...
Class javax.jms.QueueSession is not found;
referenced by 1 class file
org.apache.log.output.jms.JMSQueueTarget (logkit-1.0.1.jar)
Class javax.jms.TextMessage is not found;
referenced by 1 class file
org.apache.log.output.jms.TextMessageBuilder (logkit-1.0.1.jar)
(guava-20.0.jar) com.google.common.base.Verify's method verify(boolean arg1, String arg2, Object arg3) is not found;
referenced by 3 class files
io.grpc.internal.ServiceConfigInterceptor (grpc-core-1.17.1.jar)
io.grpc.internal.JndiResourceResolverFactory (grpc-core-1.17.1.jar)
io.grpc.internal.DnsNameResolver (grpc-core-1.17.1.jar)
[WARNING] Rule 0: com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule failed with message:
Failed while checking class path. See above error report.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
Now you can detect NoSuchMethodError
s in the project as part of the build.
In the output of the previous step, you might notice that it showed errors on seemingly irrelevant classes such as javax.jms.QueueSession
and javax.jms.TextMessage
. The project might not use the classes. To filter errors on unused classes, you can set reportOnlyReachable
flag to true
.
<LinkageCheckerRule
implementation="com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule">
<reportOnlyReachable>true</reportOnlyReachable>
</LinkageCheckerRule>
Rerun the build again.
$ mvn verify
...
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-linkage-checker) @ no-such-method-error-example ---
[ERROR] Linkage Checker rule found 1 reachable error. Linkage error report:
(guava-20.0.jar) com.google.common.base.Verify's method verify(boolean arg1, String arg2, Object arg3) is not found;
referenced by 1 class file
io.grpc.internal.DnsNameResolver (grpc-core-1.17.1.jar)
[WARNING] Rule 0: com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule failed with message:
Failed while checking class path. See above error report.
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.211 s
The enforcer rule now shows only relevant errors for the project.
The NoSuchMethodError
occurred because the two artifacts and their transitive dependencies are not compatible with each other. To fix the problem, you change the version of the google-api-client:
Run the linkage checker enforcer rule again. This time you don’t see the errors:
$ mvn verify
...
[INFO] --- maven-enforcer-plugin:3.0.0-M2:enforce (enforce-linkage-checker) @ no-such-method-error-example ---
[INFO] No reachable error found
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
Run the main class again. This time it succeeds to run without NoSuchMethodError
:
$ mvn clean compile exec:java
...
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ no-such-method-error-example ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------