Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
comparison:maven plugin jar,assembly,shade

There are 3 plugins for generating to create a JAR-File in maven:

  • maven-jar-plugin
  • maven-assembly-plugin
  • maven-shade-plugin

maven-jar-plugin:This plugin provides the capability to build and sign jars.But it just compiles the java files under src/main/java and /src/main/resources/.It doesn't include the dependencies JAR files.

<!--exclude all xml files from the jar-->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.3.1</version>
    <configuration>
        <excludes>
            <exclude>**/*.xml</exclude>
        </excludes>
    </configuration>
</plugin>

maven-assembly-plugin: this plugin extracts all dependency jars into raw classes, and group it together.It works in project with less dependencies only, for large project with many dependencies, it will cause Java class name conflict issue.

....
<build>
    <plugins>
      <!-- any other plugins -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>single</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
        </configuration>
      </plugin>
    </plugins>
  </build>
....

maven-shade-plugin:it packages all dependencies into one uber-jar. It can also be used to build an executable jar by specifying the main class.this plugin is particularly useful as it merges content of specific files instead of overwriting them. This is needed when there are resource files that are have the same name across the jars and the plugin tries to package all the resource files.

<plugins>
  <!-- any other plugins -->
  <!-- Maven Shade Plugin -->
	<plugin>
	  <groupId>org.apache.maven.plugins</groupId>
	  <artifactId>maven-shade-plugin</artifactId>
	  <version>2.3</version>
	  <executions>
	     <!-- Run shade goal on package phase -->
	    <execution>
    		<phase>package</phase>
    		<goals>
    			<goal>shade</goal>
    		</goals>
    		<configuration>
    		  <transformers>
    			<!-- add Main-Class to manifest file -->
            <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
    				<mainClass>YourMainClass</mainClass>
    			</transformer>
    		  </transformers>
    		</configuration>
	    </execution>
	  </executions>
	</plugin>
</plugins>

another solution-use some other plugins:

  • maven-resources-plugin
  • maven-dependency-plugin
  • maven-jar-plugin

maven-resources-plugin: The Resources Plugin handles the copying of project resources to the output directory. The main resources are the resources associated to the main source code.

maven-dependency-plugin: The dependency plugin provides the capability to manipulate artifacts. It can copy and/or unpack artifacts from local or remote repositories to a specified location.

maven-jar-plugin: This plugin provides the capability to build and sign jars.

<build>
	<pluginManagement>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</pluginManagement>
	<plugins>
		<plugin>
			<artifactId>maven-resources-plugin</artifactId>
			<version>2.6</version>
			<executions>
				<execution>
					<id>copy-resources</id>
					<phase>validate</phase>
					<goals>
						<goal>copy-resources</goal>
					</goals>
					<configuration>
						<outputDirectory>${basedir}/target/ProjetName/</outputDirectory>
						<resources>
							<resource>
								<directory>resources</directory>
								<filtering>true</filtering>
							</resource>
						</resources>
					</configuration>
				</execution>
			</executions>
		</plugin>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-dependency-plugin</artifactId>
			<executions>
				<execution>
					<id>copy-dependencies</id>
					<phase>prepare-package</phase>
					<goals>
						<goal>copy-dependencies</goal>
					</goals>
					<configuration>
						<outputDirectory>${project.build.directory}/ProjetName/lib</outputDirectory>
						<overWriteReleases>false</overWriteReleases>
						<overWriteSnapshots>false</overWriteSnapshots>
						<overWriteIfNewer>true</overWriteIfNewer>
					</configuration>
				</execution>
			</executions>
		</plugin>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-jar-plugin</artifactId>
			<configuration>
				<archive>
					<manifest>
						<addClasspath>true</addClasspath>
						<classpathPrefix>lib/</classpathPrefix>
						<mainClass>ProjetMainClass</mainClass>
					</manifest>
					<manifestEntries>
						<Class-Path>.</Class-Path>
					</manifestEntries>
				</archive>

				<finalName>Crunchify/Crunchify</finalName>
			</configuration>
		</plugin>
	</plugins>
</build>

You can extracts and review the content of MANIFEST.MF, the dependencies are added in the Class-Path.

an exemple from flyway:

 <plugins>
    <plugin>
        <artifactId>maven-resources-plugin</artifactId>
        <executions>
            <execution>
                <id>copy-license</id>
                <goals>
                    <goal>copy-resources</goal>
                </goals>
                <phase>generate-resources</phase>
                <configuration>
                    <resources>
                        <resource>
                            <directory>..</directory>
                            <includes>
                                <include>LICENSE.txt</include>
                                <include>README.txt</include>
                            </includes>
                        </resource>
                    </resources>
                    <outputDirectory>${project.build.outputDirectory}/META-INF</outputDirectory>
                </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
            </archive>
        </configuration>
    </plugin>
    ....
</plugins>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment