Maven

Maven assembly plugin example

In this example we are going to see how we can use the assembly maven plugin in order to control how maven generates our output packages.

Maven is a build automation tool used mainly for java projects from apache.

You can access to the maven assembly plugin information here.

We are going to use the assembly plugin in order to generate different packages for different usages.

For this example we use the following technologies:

  • MAC OSX
  • Eclipse Luna
  • Maven3
  • JDK 1.8.0_65 64bits
  • Maven assembly plugin 2.6

1. Introduction

For this example we are going to show how we can generate several packages in order to use it in different environments: for different servers, distribute source code, organize files for different audiences, etc…

In this kind of situations the maven assembly plugin will help us to achieve it.

2. Example project

For this example, we are going to use a java project with maven nature that will be packaged as a jar file. Eclipse Luna comes with maven support out of the box, so you don´t have to install anything. Our project will look like this:

Initial project, ready for work
Initial project, ready for work

At this point, we have an empty maven project. Note that the project has several text files like NOTICE.txt, LICENSE.txt, NOTICE.txt and README.txt. We are going to change the way those files are stored in the output packages with the assembly plugin help.

The pom.xml has some dependencies in order to show how we can decide if those dependencies will be in the output package, or not, or only a part of them.

The pom.xml will look like this:

pom.xml:

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.examples</groupId>
	<artifactId>maven-assembly-plugin-example</artifactId>
	<version>1.0.0-SNAPSHOT</version>
	<name>Maven assembly ::  example</name>
	<url>http://maven.apache.org</url>

	<properties>
		<spring.version>4.2.2.RELEASE</spring.version>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<dependencies>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.17</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.4</version>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-assembly-plugin</artifactId>
				<version>2.6</version>
				<configuration>
					<descriptorRefs>
						<descriptorRef>jar-with-dependencies</descriptorRef>
						<descriptorRef>bin</descriptorRef>
						<descriptorRef>src</descriptorRef>
						<descriptorRef>project</descriptorRef>
					</descriptorRefs>
					<descriptors>
						<descriptor>assembly/ourAssembly.xml</descriptor>
					</descriptors>
				</configuration>
				<executions>
					<execution>
						<id>trigger-assembly</id>
						<phase>package</phase>
						<goals>
							<goal>single</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

Note that the project includes spring framework and log4j logger framework, also defines the assembly plugin in lines 35 to 59 with several descriptor references and a custom descriptor too. The next sections will show how all those descriptors work.

3. Assembly plugin predefined descriptors

The assembly maven plugin comes out of the box with some predefined descriptors, let´s see it:

  • jar-with-dependencies -> Allow us to generate a jar package with all the dependencies defined in pom.xml file inside of it. This is useful when we plan to deliver an auto-executable jar.
  • bin -> Use this predefined descriptor in order to create a binary distribution of your package.
  • src-> Use this predefined descriptor in order to distribute your source code. The output package will have the src folder content inside it.
  • project -> (since 2.2) Use this predefined descriptor in order to distribute your entire project minus the target folder content

You can see more details about those predefined descriptors here.

The example project use all the predefined descriptors in order to show how they work. We can see the result output in later sections.

4. Assembly plugin custom descriptors

The assembly plugin allow us to create a custom assembly in which we can define how our package will be.

The example project references a custom descriptor in assembly/ourAssembly.xml at line 47. So you have to create a folder called assembly in project root folder, and create inside it a file called ourAssembly.xml. The content of the new file will be the following:

ourAssembly.xml:

<assembly
	xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
	<id>ourAssembly</id>
	<formats>
		<format>jar</format>
	</formats>
	<dependencySets>
		<dependencySet>
			<excludes>
				<exclude>commons-logging:commons-logging</exclude>
				<exclude>log4j:log4j</exclude>
			</excludes>
		</dependencySet>
	</dependencySets>
	<fileSets>
		<fileSet>
			<directory>${basedir}</directory>
			<includes>
				<include>*.txt</include>
			</includes>
			<excludes>
				<exclude>AWESOME.txt</exclude>
				<exclude>LICENSE.txt</exclude>
			</excludes>
		</fileSet>
	</fileSets>
	<files>
		<file>
			<source>AWESOME.txt</source>
			<outputDirectory>/MyFiles</outputDirectory>
			<filtered>true</filtered>
		</file>
		<file>
			<source>LICENSE.txt</source>
			<outputDirectory>/License</outputDirectory>
			<filtered>true</filtered>
		</file>
	</files>
</assembly>

Our assembly uses a dependecySets tag in order to exclude the following dependencies: commons-logging:commons-logging and log4j:log4j. The commons-logging was not defined as a dependency in our pom.xml, but it is indirectly referenced by spring.

Our assembly uses a fileSets tag in order to include some files (all txt files) and exclude two of them: AWESOME.txt and LICENSE.txt. We can use this tag in order to include files that conform to predefined patterns.

Our assembly uses a files tag in order to include some files in custom folders. In this case the assembly includes AWESOME.txt file inside of MyFiles folder and LICENSE.txt file inside of License folder. We can use this tag in order to include some concrete files in concrete locations.

For more details about how we can define custom assemblies you can go to here.

5. Running the assembly plugin

The assembly plugin only has one non-deprecated target called single. The pom.xml file has defined the assembly plugin to run in package phase, so we can run it with mvn package.

Output:

[INFO] Scanning for projects...
[INFO] 
[INFO] Using the builder org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder with a thread count of 1
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven assembly ::  example 1.0.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ maven-assembly-plugin-example ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ maven-assembly-plugin-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ maven-assembly-plugin-example ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 0 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ maven-assembly-plugin-example ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ maven-assembly-plugin-example ---
[INFO] 
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ maven-assembly-plugin-example ---
[INFO] 
[INFO] --- maven-assembly-plugin:2.6:single (trigger-assembly) @ maven-assembly-plugin-example ---
[INFO] Reading assembly descriptor: assembly/ourAssembly.xml
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /MyFiles
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /License
[INFO] Building jar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-ourAssembly.jar
[INFO] Building jar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-jar-with-dependencies.jar
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[INFO] Building tar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-bin.tar.gz
[WARNING] Entry: maven-assembly-plugin-example-1.0.0-SNAPSHOT/maven-assembly-plugin-example-1.0.0-SNAPSHOT-jar-with-dependencies.jar longer than 100 characters.
[WARNING] Resulting tar file can only be processed successfully by GNU compatible tar commands
[WARNING] Entry: maven-assembly-plugin-example-1.0.0-SNAPSHOT/maven-assembly-plugin-example-1.0.0-SNAPSHOT-ourAssembly.jar longer than 100 characters.
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[INFO] Building tar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-bin.tar.bz2
[WARNING] Entry: maven-assembly-plugin-example-1.0.0-SNAPSHOT/maven-assembly-plugin-example-1.0.0-SNAPSHOT-jar-with-dependencies.jar longer than 100 characters.
[WARNING] Resulting tar file can only be processed successfully by GNU compatible tar commands
[WARNING] Entry: maven-assembly-plugin-example-1.0.0-SNAPSHOT/maven-assembly-plugin-example-1.0.0-SNAPSHOT-ourAssembly.jar longer than 100 characters.
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[INFO] Building zip: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-bin.zip
[INFO] Building tar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-src.tar.gz
[INFO] Building tar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-src.tar.bz2
[INFO] Building zip: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-src.zip
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[INFO] Building tar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-project.tar.gz
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[INFO] Building tar: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-project.tar.bz2
[WARNING] The assembly descriptor contains a filesystem-root relative reference, which is not cross platform compatible /
[INFO] Building zip: /Users/fhernandez/Documents/workspaceJavaCodeGeeks/maven assembly plugin/target/maven-assembly-plugin-example-1.0.0-SNAPSHOT-project.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.104 s
[INFO] Finished at: 2015-11-23T11:16:00+01:00
[INFO] Final Memory: 17M/309M
[INFO] ------------------------------------------------------------------------

6. See the result

After run the maven command, we can see the different packages generated by the plugin like this:

different packages generated by the assembly plugin
Different packages generated by the assembly plugin

For each different descriptor we have a different package, we can relate each package with the descritor that generates it because the descriptor name is added to the end of the file name.

For example, we can see the src result package here:

Jar generated by the src descriptor content
Jar generated by the src descriptor content

We can see our classes inside it.

We can also see the ourAssembly package result here

Jar generated by ourAssembly content
Jar generated by ourAssembly content

We can see how the files are distributed how we want, and how there are no jars for log4j and common-loggins inside it as we specified in ourAssembly.xml file.

7. Download the eclipse project

Download
You can download the full source code of this example here: maven-assembly-plugin-example.zip

Francisco Hernandez

JEE technologies geek and development engineer. I have over 13 years of experience as software engineer in JEE architectures: Design, development, improvement etc. Currently I work as software architect and consultant. I am mainly involved in projects related to the bank and energy sectors based on Java technologies and Oracle products. I am also very interested in open-source projects
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Filip Živanović
Filip Živanović
5 years ago

Hi, how to generate only .zip file, and not tar.gz and tar.bz2 files? Thanks

max
max
3 years ago

Hi is there any way to specify jar, text files and external configuration using path inside assembly.xml

Back to top button