Search code examples
javamavenmaven-assembly-plugin

Include jar-with-dependencies in separate assembly?


I'm using the maven assembly plugin to package a distributable ZIP archive. However, I would like to include the result of a separate assembly, jar-with-dependencies, inside my final archive. How can I do this? I realize that I could probably just include the JAR manually, but how can I ensure that my custom assembly will run after the JAR assembly?


Solution

  • You can use a multimodule project for that:

    parent
      |- ...
      |- jar-with-dependencies-module
      |- final-zip-module
    

    In the jar-with-dependencies module, you assemble the "uber-jar" with all dependencies. The build configuration in the POM should look something like this:

    <build>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.3</version>
          <configuration>
            <descriptorRefs>
              <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
          </configuration>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>single</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
    

    In the final-zip-module you can add the jar-with-dependencies as a dependency and use it in the assembly descriptor for the ZIP file. The POM would look something like this:

    <project>
      ...
    
      <dependencies>
        <dependency>
          <groupId>com.example</groupId>
          <artifactId>jar-with-dependencies-module</artifactId>
          <version>1.0.0-SNAPSHOT</version>
          <classifier>jar-with-dependencies</classifier>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.3</version>
            <configuration>
              <appendAssemblyId>false</appendAssemblyId>
              <descriptors>
                <descriptor>src/main/assembly/assembly.xml</descriptor>
              </descriptors>
            </configuration>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
        </plugins>
      </build>
    

    And the assembly descriptor would look something like this:

    <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    
      <id>final-assembly</id>
      <formats>
        <format>zip</format>
      </formats>
    
      <dependencySets>
        <!-- Include the jar-with-dependencies -->
        <dependencySet>
          <includes>
            <include>com.example:jar-with-dependencies-module:*:jar-with-dependencies</include>
          </includes>
          <useProjectArtifact>false</useProjectArtifact>
          <!-- Don't use transitive dependencies since they are already included in the jar -->
          <useTransitiveDependencies>false</useTransitiveDependencies>
        </dependencySet>t>
      </dependencySets>
    </assembly>
    

    Because of the dependency to jar-with-dependency-module, maven will build the final-zip-module always after your uber-jar was built.