Reputation: 15283
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.7</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>test.Test</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
mvn install
completes successfully, (i.e. maven sees tools.jar
dependency during the build), but on execution I have
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/tools/javac/api/JavacScope
at test.Test.main(Test.java:24)
Caused by: java.lang.ClassNotFoundException: com.sun.tools.javac.api.JavacScope
...
Upvotes: 3
Views: 2647
Reputation: 49472
Most <scope>system</scope>
dependencies are not made available to plugins.
Also, including the tools.jar in your uberjar isn't terribly portable across newer versions of JVMs. Its fine if you have a super controlled and limited deployment environment, but generally its better to discover the tools.jar and use it.
Here's an example from the maven-javadoc-plugin itself (it looks up the tools.jar and then validates that the active classloader has classes from the tools.jar)
In your case, instead of looking for com.sun.tools.doclets.Taglet
, you'd look for com.sun.tools.javac.api.JavacScope
to verify a valid environment.
From there it would be trivial to build up a new ClassLoader with your uberjar + tools.jar and then execute what you need from a valid Thread.currentThread().setContextClassLoader()
scope
Upvotes: 1
Reputation: 240908
maven-shade plugin assumes System dependencies be present and it doesn't actually include them inside fat-jar
fast dirty workaround is to install tools.jar into your maven repository and refer it as a compile scoped dependency
better workaround is to use maven-assembly-plugin and include tools.jar as a <file>
Upvotes: 1