I'm starting to work with Maven but am not yet successfully thinking in Maven's terms. I have a specific requirement and the docs aren't giving me enough clues, so I could use a bit of help:
I'd like to create an assembly that
builds a jar-with-dependencies
like the "standard" target of this name, but excluding a couple of the resources. I want log4j.properties
and a couple of other configuration files to not be in the jar.
builds a .ZIP
file containing in its root directory the .jar
from step 1 as well as the above mentioned config files.
I want to fire this assembly up from the command line (only), hence no need to tie to a phase (or goal? mojo?). Preferrably using either assembly:assembly
or assembly:single
.
pom.xml
? So it goes in src/assembly/something.xml
and gets referenced with a descriptorRef
?I'm starting to work with Maven but am not yet successfully thinking in Maven's terms.
Welcome on board, Carl! :D
I want to fire this assembly up from the command line (only), hence no need to tie to a phase (or goal? mojo?). Preferrably using either assembly:assembly or assembly:single.
Just to clarify: the build lifecycle itself is made of phases
(compile, test, package, etc) and plugin goals (technically Mojos) are bound on phases. You then either invoke a phase... or just a specific plugin goal.
Do I need a custom assembly descriptor for this?
Well, since you want behavior that the pre-defined descriptors don't cover, yes. You'll even need two of them (of for the uberjar, one for the zip).
And is it true I can't nest it in the pom.xml? So it goes in src/assembly/something.xml and gets referenced with a descriptorRef?
Yes, that's true (descriptors use a custom format) and they usually go into src/main/assembly
. And no, descriptorRef
is for the built-in descriptors, you'll have to use descriptor
here.
Can I code this as two relatively simple assemblies, of which one builds on the other (i.e. the .Zip assembly uses the .Jar assembly) or do I have to do everything in one assembly?
As hinted, you'll need two assembly descriptors. Let me help a bit...
Let's assume you have the following project structure:
$ tree . . ├── pom.xml └── src ├── main │ ├── assembly │ │ ├── jar.xml │ │ └── zip.xml │ ├── java │ │ └── com │ │ └── stackoverflow │ │ └── App.java │ └── resources │ └── log4j.properties └── test └── java └── com └── stackoverflow └── AppTest.java
Where the pom.xml
contains the following configuration for the assembly plugin:
<project>
...
<dependencies>
...
</dependencies>
...
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/jar.xml</descriptor>
<descriptor>src/main/assembly/zip.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
</project>
The descriptor for the "filtered" uberjar (jar.xml) looks like this:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>uberjar</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
<excludes>
<exclude>log4j.properties</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
What this descriptor does is (in short):
And the descriptor for the zip (zip.xml) looks like this:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>bin</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/resources</directory>
<outputDirectory/>
<includes>
<include>log4j.properties</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory/>
<includes>
<include>*-uberjar.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Which is (somehow) self explaining :)
<directory>
) at the root of the assembly<directory>
) at the root of the assemblyFinally, just run mvn assembly:assembly
(that's the goal intended to be used on the CLI).
I didn't (knowingly) include META-INF/maven/** in the assembly for the uberjar. Is there a simple way to prevent inclusion of these?
These are coming from the libraries that are unpacked. You can exclude them using unpackOptions
. Here is a modified version of the jar.xml
:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>uberjar</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<scope>runtime</scope>
<unpackOptions>
<excludes>
<exclude>META-INF/maven/**</exclude>
</excludes>
</unpackOptions>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
<excludes>
<exclude>log4j.properties</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With