-
Notifications
You must be signed in to change notification settings - Fork 73
Linkage Checker with Gradle
The Linkage Checker Gradle plugin verifies that a project's classpath does not have any linkage errors. For a Gradle project, we provide two ways to check its dependency graph: Gradle's way and Maven's way.
- Gradle's way: When Gradle builds dependency graphs and it encounters multiple versions of the same library, it selects the highest versions of library in the transitive dependencies.
- Maven's way: When Maven builds dependency graphs and it encounters multiple versions of the same library, it selects the closest (the minimum hop from the root) version to the root project.
If you have Gradle project that produces a library which Maven users depend on it, it's worth checking your library's dependency in Maven's manner.
To check Gradle project's dependency graph in Gradle's way, use the Linkage Checker Gradle plugin. The plugin installs "linkageCheck" task to the project and specify the configuration you want to check.
plugins {
id "com.google.cloud.tools.linkagechecker" version "1.5.10"
}
linkageChecker {
configurations = ['compile']
reportOnlyReachable = true
}
// Run build task first to generate JAR file of this project
linkageCheck.dependsOn('build')
Run the task to detect linkage errors:
$ ./gradlew linkageCheck
...
> Task :linkageCheck FAILED
Linkage Checker rule found 81 errors:
Class com.jcraft.jzlib.JZlib is not found;
referenced by 4 class files
io.grpc.netty.shaded.io.netty.handler.codec.spdy.SpdyHeaderBlockJZlibEncoder (io.grpc:grpc-netty-shaded:1.28.1)
io.grpc.netty.shaded.io.netty.handler.codec.compression.JZlibEncoder (io.grpc:grpc-netty-shaded:1.28.1)
...
A configuration in Gradle is a list of dependencies. In your build.gradle, you declare dependencies of your project with dependencies
clause. It actually adds the dependency to the configuration you specify in the arguments to the clause. For example, assume you have a build.gradle with the following dependencies:
dependencies {
compile 'com.google.cloud:google-cloud-logging:1.101.1'
compile 'io.grpc:grpc-core:1.29.0'
}
This adds the two dependencies to compile
configuration. In Gradle Java plugin, when Gradle "compiles" your project it resolves the dependencies of the compile
configuration and supplies the Java compiler. Another example is testCompile
configuration. When Gradle compiles tests, it supplies the dependencies of testCompile
configuration.
A Gradle module often outputs a Maven artifact. For a library developed in Gradle, it's important to ensure the dependency graph of the Maven artifact in Maven's manner because Maven users may use the library and Maven
To detect linkage errors in Maven artifacts generated by a Gradle project, you can first install the artifact in Maven local repository using Gradle's Maven Publish Plugin and then run LinkageCheckerMain
with your artifact coordinates.
// Separate configuration (class path) for Linkage Checker
configurations { linkageChecker }
dependencies {
linkageChecker "com.google.cloud.tools:dependencies:1.5.10"
}
project.task('runLinkageChecker', type: JavaExec) {
// Replace 'MavenJava' with your publication name
dependsOn project.getTasksByName('publishMavenJavaPublicationToMavenLocal', true)
classpath = project.configurations.linkageChecker
main = 'com.google.cloud.tools.opensource.classpath.LinkageCheckerMain'
args '-a', 'com.example:foo:0.1.0-SNAPSHOT' // the coordinate of the Maven artifact
}