-
Notifications
You must be signed in to change notification settings - Fork 73
Linkage Checker Enforcer Rule
The Linkage Checker Enforcer Rule verifies that a project's runtime classpath does not have any linkage errors. The rule assumes that the classpath is constructed from a project's pom.xml according to the usual Maven algorithm.
Add the following plugin configuration to your pom.xml
:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<dependencies>
<dependency>
<groupId>com.google.cloud.tools</groupId>
<artifactId>linkage-checker-enforcer-rules</artifactId>
<version>1.5.7</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>enforce-linkage-checker</id>
<!-- Important! Should run after compile -->
<phase>verify</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<LinkageCheckerRule
implementation="com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule"/>
</rules>
</configuration>
</execution>
</executions>
</plugin>
...
For a BOM project, set dependencySection
element to DEPENDENCY_MANAGEMENT
.
<LinkageCheckerRule
implementation="com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule">
<dependencySection>DEPENDENCY_MANAGEMENT</dependencySection>
</LinkageCheckerRule>
To suppress linkage errors that are not reachable in the class reference graph from the classes in the direct
dependencies of the project, set reportOnlyReachable
element to true
. (default: false
).
<LinkageCheckerRule
implementation="com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule">
<reportOnlyReachable>true</reportOnlyReachable>
</LinkageCheckerRule>
To suppress linkage errors using Linkage Checker Exclusion File, set exclusionFile
element to the exclusion file.
<LinkageCheckerRule
implementation="com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule">
<exclusionFile>linkage-checker-exclusion-rules.xml</exclusionFile>
</LinkageCheckerRule>
If you want violations not to fail the build, set the level
element to WARN
:
<LinkageCheckerRule
implementation="com.google.cloud.tools.dependencies.enforcer.LinkageCheckerRule">
<level>WARN</level>
</LinkageCheckerRule>
The Linkage Checker Enforcer Rule is bound to the verify
lifecycle:
$ mvn verify
Successful checks output no error.
[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (enforce-linkage-checker) @ protobuf-java-util ---
[INFO] No error found
Failed checks output the missing classes, fields, or methods and the referencing classes.
[INFO] --- maven-enforcer-plugin:3.0.0-M3:enforce (enforce-linkage-checker) @ google-cloud-core-grpc ---
[ERROR] Linkage Checker rule found 21 reachable errors. Linkage error report:
Class org.eclipse.jetty.npn.NextProtoNego is not found;
referenced by 1 class file
io.grpc.netty.shaded.io.netty.handler.ssl.JettyNpnSslEngine (grpc-netty-shaded-1.23.0.jar)
...
The dependencySection
element determines whether the rule checks the dependencies in
the dependencies
section or the dependencyManagement
section.
The following values are accepted:
-
DEPENDENCIES
(default value): the rule checks the class path calculated from the project'sdependencies
section. -
DEPENDENCY_MANAGEMENT
: the rule checks the class path calculated from the project'sdependencyManagement
section.
In both cases, the rule builds dependency graph that Maven would create. For example, in the dependency graph, the optional dependencies of transitive dependencies are not included in the graph.
This enforcer rule requires Maven 3.6.0 or later and Java 8.
This enforcer rule relies on the immutability of JAR files in the class path. Running this enforcer rule concurrently (the -T
option in mvn
) with install
task causes PluginExecutionException with the following error:
Caused by: org.apache.maven.plugin.PluginExecutionException: Execution enforce-linkage-checker of goal
org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce failed: The source class in the reference
is no longer available in the class path
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:148)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:208)
If you want concurrent execution of Maven, split the install
lifecycle from verify
:
$ mvn -T 1.5C verify
$ mvn -T 1.5C install -Denforcer.skip=true
If you use the Linkage Checker Enforcer Rule with other enforcer rule (such as extra-enforcer-rules
), it sometimes causes the following "An API incompatibility" error: Execution enforce-linkage-checker of goal org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce failed: An API incompatibility was encountered while executing org.apache.maven.plugins:maven-enforcer-plugin:3.0.0-M3:enforce: java.lang.IllegalAccessError: tried to access method org.eclipse.aether.util.ChecksumUtils.toHexString([B)Ljava/lang/String; from class org.eclipse.aether.connector.basic.ChecksumCalculator$Checksum
. This error means the class in the old aether-util is not compatible with the one transitively used by Linkage Checker. To resolve this dependency conflict, add the following dependency to extra-enforcer-rules
that explicitly excludes old aether-util artifact:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0-M3</version>
<dependencies>
<dependency>
<groupId>com.google.cloud.tools</groupId>
<artifactId>linkage-checker-enforcer-rules</artifactId>
<version>1.5.7</version>
</dependency>
<!-- Add this maven-resolver-util dependency to avoid dependency conflicts
with extra-enforcer-rules -->
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-util</artifactId>
<version>1.6.1</version>
<scope>compile</scope>
</dependency>
</dependencies>