D. Müller
D. Müller

Reputation: 3426

Intellij Maven: Create jar with all library dependencies

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: enter image description here

enter image description here

As parameter in the run configurations I set "package", see screenshot below: enter image description here

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

  1. Open pom.xml
  2. Menu "Code" > "Generate" > "Dependency" (or shortcut ALT + INSERT)

Upvotes: 11

Views: 23570

Answers (4)

John kerich
John kerich

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

amitgh
amitgh

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. IntelliJ screenshot

Upvotes: 0

emanciperingsivraren
emanciperingsivraren

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

H&#233;ctor
H&#233;ctor

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

Related Questions