Search code examples
javamavendependenciespackagemaven-assembly-plugin

Maven-assembly: how package only imported/used dependencies for each execution


I have a Maven project where I need to package different Java programs as jars, each one with its own dependecies. To achieve this I am currently using maven-assembly-plugin with different executions, one for each java program I need to package (e.g. Program1.java, Program2.java, Program3.java):

<plugin>
    <artifactId>maven-assembly-plugin</artifactId>
    <executions>

        <execution>
            <id>assembly1</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>my.package1.Program1</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <finalName>Program1</finalName>
                <appendAssemblyId>false</appendAssemblyId>
            </configuration>
        </execution>

        <execution>
            <id>assembly2</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>my.package2.Program2</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <finalName>Program2</finalName>
                <appendAssemblyId>false</appendAssemblyId>
            </configuration>
        </execution>

        <execution>
            <id>assembly3</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>my.package3.Program3</mainClass>
                    </manifest>
                </archive>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <finalName>Program3</finalName>
                <appendAssemblyId>false</appendAssemblyId>
            </configuration>
        </execution>

    </executions>
</plugin>

Each one of these classes (Program1, Program2, Program3) requires different libraries as depedencies, thus I expected in output to get 3 jars with different size, but I got 3 files of the same size (Program1.jar, Program2.jar, Program3.jar). It's like Maven is packaging all the dependencies defined inside the tag dependencies, regardless if they are used or not.

How can I tell maven to package, for each execution inside the assembly-plugin, only the dependencies effectively imported and used by the specified Class?


Solution

  • The default behaviour of assembly plugin is to include all dependencies of your current maven module. You could change that by explictly excluding the unwanted dependencies.

    However, if you have three different programs that even do not have the same dependencies, it might be better to split up your project into three different (sub-)modules, maybe with a common parent pom. More details can be found here. After splitting up the project, each submodule can run its own assembly plugin that only packs the dependencies that are declared for each submodule.

    If you decide to split up your project, you can clean up the required dependencies for each sub-module with the help of the dependency plugin, goal dependency:analyze.