如何在构建阶段验证Maven依赖与Java 11的兼容性?
Absolutely! You can automate compatibility checks for your Java 11 migration using Maven or Gradle plugins, catching issues like missing javax.xml.bind-style classes (and other removed JRE packages) during the build process—way before you hit a runtime NoClassDefFoundError.
Let’s break down the most effective tools for both build systems:
Maven Solutions
1. Maven Enforcer Plugin
This plugin lets you enforce a wide range of build rules, including checks for dependency compatibility with Java 11. You can use it to:
- Ensure your project and dependencies are compiled against a compatible Java version
- Block dependencies that reference packages removed in Java 11 (like
javax.xml.bind,javax.annotation, etc.)
Here’s a sample configuration to ban dependencies that use removed JRE packages:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-enforcer-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <id>enforce-banned-dependencies</id> <goals> <goal>enforce</goal> </goals> <configuration> <rules> <bannedDependencies> <excludes> <exclude>java.xml.bind:*</exclude> <exclude>javax.xml.bind:*</exclude> <!-- Add other removed packages here --> </excludes> <message>Found dependency referencing a JRE 11 removed package! Please update or replace this dependency.</message> </bannedDependencies> </rules> </configuration> </execution> </executions> </plugin>
You can also use the enforceJavaVersion rule to ensure your build uses Java 11, preventing accidental cross-compilation issues.
2. Animal Sniffer Plugin
This plugin is specifically designed to check that your code and dependencies only use APIs available in a specified Java version. It works by comparing bytecode against a "signature" file for your target Java version (Java 11, in this case). If a dependency uses an API that’s removed in Java 11, the build will fail with a clear error.
Sample pom configuration:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>animal-sniffer-maven-plugin</artifactId> <version>1.23</version> <executions> <execution> <id>check-java-11-compatibility</id> <goals> <goal>check</goal> </goals> </execution> </executions> <configuration> <signature> <groupId>org.codehaus.mojo.signature</groupId> <artifactId>java11</artifactId> <version>1.0</version> </signature> </configuration> </plugin>
Gradle Solutions
1. Animal Sniffer Gradle Plugin
Just like the Maven version, this plugin checks for API compatibility against your target Java version. Add it to your build.gradle file:
plugins { id 'java' id 'org.codehaus.mojo.animal-sniffer' version '1.23' } animalSniffer { signature = "org.codehaus.mojo.signature:java11:1.0" }
Run ./gradlew check—the plugin will flag any dependencies using APIs removed in Java 11.
2. Gradle Enforcer Plugin (Community-Maintained)
This plugin mirrors Maven Enforcer’s functionality for Gradle. You can use it to ban dependencies that reference removed JRE packages or enforce Java version constraints.
Add it to your build.gradle:
plugins { id 'java' id 'io.freefair.enforcer' version '8.6' } enforce { rules { bannedDependencies { bans = [ "java.xml.bind:*", "javax.xml.bind:*" ] message = "Dependency uses a package removed in Java 11! Please update or replace it." } } }
Bonus: jdeps Tool
While not a build plugin, the built-in jdeps tool (shipped with Java 11+) is great for ad-hoc analysis of individual dependencies. Run this command on your old JAR to find references to removed JRE packages:
jdeps --jdk-internals path/to/oldartifact-oldversion.jar
You can even integrate this into your build script as a custom task if you want automated checks.
Key Note for javax.xml.bind-Style Issues
If a plugin flags a dependency using javax.xml.bind, you don’t necessarily need to replace the dependency entirely. You can often add the standalone versions of these APIs to your pom/gradle file:
<!-- Maven example for JAXB --> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> <scope>runtime</scope> </dependency>
By integrating these tools into your build pipeline, you’ll catch compatibility issues early, avoiding frustrating runtime errors and making your Java 11 migration far more manageable.
内容的提问来源于stack exchange,提问作者kolobok_ua

