Two weeks ago I wrote about how Java 9 may break your code. A substantial obstacle for the transition to Java 9 can be a project's dependencies on JDK-internal APIs. These will be unaccessible in the new Java version and code containing them will not compile. It is hence important to weed them out in the remaining time. (Btw, Java 9 is scheduled for September 2016.)
To help our projects (and maybe yours) with that, I created the JDeps Maven Plugin. It breaks the build if the code contains any problematic dependencies.
▚JDeps
To help identify problematic dependencies the JDK 8 contains the Java Dependency Analysis tool jdeps. Run against a jar, a folder or a single class it will analyze and output dependencies. Analysis and output can be configured with several command line options.
Run as jdeps -jdkinternals
it will only list the dependencies on JDK-internal API.
Exactly these dependencies are the ones that would break if compiled against Java 9.
It is hence the basis of the Maven plugin.
▚JDeps Maven Plugin
The plugin runs jdeps -jdkinternals
against the compiled classes, parses the output and breaks the build if it contained any dependencies.
▚Configuration
To use it in a project include this in its pom:
<build>
<plugins>
...
<plugin>
<groupId>org.codefx.maven.plugin</groupId>
<artifactId>jdeps-maven-plugin</artifactId>
<version>0.1</version>
<executions>
<execution>
<goals>
<goal>jdkinternals</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
The plugin is extremely simple and the current version neither allows nor requires any further configuration.
▚Execution
The plugin will be executed during the verify phase.
It will hence run in a full build with mvn verify
(or any later phase).
With mvn jdeps:jdkinternals
it can be run directly.
If your project contains any internal dependencies the build will fail with a message like this:
[ERROR] Failed to execute goal
org.codefx.maven.plugin:jdeps-maven-plugin:0.1:jdkinternals
(default-cli) on project MavenLab:
[ERROR] Some classes contain dependencies on JDK-internal API:
[ERROR] . org.codefx.lab.ExampleClass
[ERROR] . -> sun.misc.BASE64Decoder [JDK internal API, rt.jar]
[ERROR] . -> sun.misc.Unsafe [JDK internal API, rt.jar]
[ERROR] . org.codefx.lab.AnotherExampleClass
[ERROR] . -> sun.misc.Unsafe [JDK internal API, rt.jar]
[ERROR] . org.codefx.lab.foo.ExampleClassInAnotherPackage
[ERROR] . -> sun.misc.BASE64Decoder [JDK internal API, rt.jar]
▚Roadmap
The plugin fulfills the minimum requirements to be useful: it breaks the build if JDeps discovers any dependencies on JDK-internal APIs. But this may be inconvenient for larger projects which might already contain some. It would be nice to be able to configure the plugin so that it ignores certain known dependencies.
This is the next step.
A simple configuration consisting of elements of the form org.codefx.lab.ExampleClass -> sun.misc.*
will allow to ignore certain dependencies.
The plugin can hence be included in any build and be configured such that it only breaks when new dependencies are introduced.
You can track the progress in this issue.
▚Existing Plugins
There are (at least) two Maven plugins which allow to use JDeps.
Maven JDeps by Philippe Marschall: Runs JDeps against the compiled classes and either prints the output or creates a report from it. Has no consequences for the build.
Apache Maven JDeps: In development. Seems to be aimed at breaking the build when discovering internal dependencies but this does currently not work.
I wanted fast results and full control over where this is going for my projects. I hence decided to reimplement parts of the functionality.
If this JDeps Maven plugin proves to be useful I will reach out and try to get some code included in either of those plugins (most likely the official one from Apache).