Search code examples
javamavenjarmaven-plugin

Maven assembly plugin: dependency jars are not included, fat jar without jars


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>first.second</groupId>
    <artifactId>mytestapp</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <name>mytestapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
               
               <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.6</version>
    <configuration>
        <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
        </descriptorRefs>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>first.second.MyTest</mainClass>
            </manifest>
        </archive>
    </configuration>
    <executions>
        <execution>
            <id>assemble-all</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>
               
        </plugins>
        
    </build>
</project>

mytestapp-0.0.1-SNAPSHOT-jar-with-dependencies.jar:

enter image description here

So the final jar with dependencies doesn't include junit dependency.

Therefore when I try to run MyTest:

java -cp mytestapp-0.0.1-SNAPSHOT-jar-with-dependencies.jar first.second.MyTest

I get

MyTest main
Exception in thread "main" java.lang.NoClassDefFoundError: org/junit/Assert
        at first.second.MyTest.main(MyTest.java:16)

output and exception

MyTest.java:

package first.second;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class MyTest 
{
    public static void main( String[] args )
    {
        System.out.println("MyTest main");
        assertEquals(1, 1);
    }
}

How do I make maven assembly plugin include junit jar inside the jar with dependencies, so that

java -cp mytestapp-0.0.1-SNAPSHOT-jar-with-dependencies.jar first.second.MyTest

runs without errors?

I'm aware there are other questions on this topic, but having tried many of the suggested answers, the dependency jars are still not included.


Solution

  • Normally is a typical "test" dependency, but it doesn't have to be...

    To make it "available" for "main" classes:

    • at compilation - we have to remove (because it is the default) or set <scope>compile</scope>
    • at runtime - we set <scope>runtime</scope>

    These will also receive more consideration by jar-with-dependencies (assembly-plugin built-in descriptor).

    More details: introduction-to-dependency-mechanism

    The generated jar with dependencies now looks like this inside:

    enter image description here