Reputation: 3426
Working with IntelliJ Idea, I want to implement the following:
I want to export an application to a jar, which contains all needed libraries. E.g. I need the AWS Java SDK libraries for S3 access, but if I upload the jar to the server and run the jar I get an NoClassDefFoundError, see below:
Exception in thread "main" java.lang.NoClassDefFoundError: com/amazonaws/auth/AWSCredentials
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2625)
at java.lang.Class.getMethod0(Class.java:2866)
at java.lang.Class.getMethod(Class.java:1676)
at sun.launcher.LauncherHelper.getMainMethod(LauncherHelper.java:494)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:486)
Caused by: java.lang.ClassNotFoundException: com.amazonaws.auth.AWSCredentials
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 6 more
Comparison: I created the same project in Eclipse and get no error! The jar file sizes are very different (Eclipse: ~35 MB vs. IntelliJ Idea: ~5,5 MB)!
I included the libraries via Maven and downloaded them also into the "lib" folder of my project:
As parameter in the run configurations I set "package", see screenshot below:
SOLUTION:
Thanks for all your hints, I got it to work now! The trick was that I did't add the dependencies to the pom.xml file (because I thought that this would be done automatically after setting them in the Project Structure, but it didn't)!!! See also my other question: Intellij IDEA Maven Plugin - Manage Dependencies and https://www.jetbrains.com/idea/help/maven.html! Add the dependencies by
Upvotes: 11
Views: 23570
Reputation: 46
For the maven-assembly-plugin compile problem, if you add <executions>
block the SNAPSHOT-jar-with-dependencies.jar will be created automatically, so you don't need to modify the maven compile command. see https://medium.com/@randilfernando/when-to-use-maven-jar-maven-assembly-or-maven-shade-ffc3f76ba7a6#:~:text=maven%2Dassembly%2Dplugin%20%3A%20This,Java%20class%20name%20conflict%20issue.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.xxx.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Upvotes: 0
Reputation: 61
After adding the maven assembly plugin as suggested by Hector, he mentioned to run mvn clean compile assembly:single
. I couldn't figure out where to run this command in Intellij.
This is what I ended up doing and successfully creating my xxx-SNAPSHOT-jar-with-dependencies.jar
file.
View -> Tool Windows -> Maven -> <Your Package> -> Lifecycle -> right click compile -> Modify Run Configuration -> update Command line with 'compile assembly:single -f pom.xml' -> OK.
This created a new run configuration in the Maven tool window. There, double click on the recently created [compile].
You'll see the jars getting created under the target directory. Attaching a screenshot of my IntelliJ for reference.
Upvotes: 0
Reputation: 1305
I recommend that you use the plugin shade
. It is better than Assembly
because it is possible to relocate classes if a conflict occur.
A typical setup can look like this: (copied from the official documentation)
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<excludes>
<exclude>classworlds:classworlds</exclude>
<exclude>junit:junit</exclude>
<exclude>jmock:*</exclude>
<exclude>*:xml-apis</exclude>
<exclude>org.apache.maven:lib:tests</exclude>
<exclude>log4j:log4j:jar:</exclude>
</excludes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
If size is important you can try to use the <minimizeJar>true</minimizeJar>
to reduce size.
Upvotes: 3
Reputation: 26074
You need to use Maven Assembly Plugin to include dependencies:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>your.package.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
and then: mvn clean compile assembly:single
Upvotes: 22