How to package an assembly in Maven by moving resources out of the war? - maven

Our project is set up to package a WAR and this works great for local development:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>package-war</id>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
...
Included in this war, is a mapper file and logback file used by the application, which lives under: src/main/resources/logback.xml and /src/main/resources/mappers/our-mapper.xml.
In building the war, these files get sent where we expect and want them to be, under our.war/WEB-INF/classes/logback.xml and our.war/WEB-INF/classes/mappers/our-mapper.xml
When we package our assembly to hand off for deployment, we need to have these files separated out of the war, which we do using our assembly descriptor:
<assembly>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<files>
<file>
<source>target/${build.finalName}.war</source>
<outputDirectory>${tomcat-instance}/webapps</outputDirectory>
</file>
<file>
<source>src/main/resources/logback.xml</source>
<outputDirectory>${tomcat-instance}/resources/</outputDirectory>
</file>
</files>
<fileSets>
<fileSet>
<directory>src/main/resources/mapper</directory>
<outputDirectory>${tomcat-instance}/resources/mapper/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
And configured in Maven with:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/resources/our-assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
This constructs the assembly, but my concern is the logback.xml and mappers/our-mapper.xml files are still contained inside the war which is contained inside the assembly.tar.gz.
Is it possible to keep the configuration where the war outside the assembly contains the .xml files as it already does, but also have the war that goes inside the assembled .tar.gz assembly exclude these same files so they don't appear twice on the classpath?
Thanks in advance for any help.

You've probably found a solution or workaround to this problem now - however, I was intrigued to know whether this was possible so I created a small test project with the same file structure as you described.
I managed to get this project to build out the two war files - with the one outside the assembly containing the .xml files, and the one inside the assembly excluding the .xml files. I achieved this by creating an additional assembly that builds a second temporary war file which explicitly excludes the .xml files. Then the existing assembly includes this new war file, rather than the default war.
The new assembly war-assembly.xml looks like this:
<assembly>
<id>temp</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target/${build.finalName}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>**/logback.xml</exclude>
<exclude>**/mapper/*</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
The existing assembly is then modified to include the new war file:
<assembly>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<files>
<file>
<source>target/${build.finalName}-temp.war</source>
<outputDirectory>${tomcat-instance}/webapps</outputDirectory>
<destName>target/${build.finalName}.war</destName>
</file>
<file>
<source>src/main/resources/logback.xml</source>
<outputDirectory>${tomcat-instance}/resources/</outputDirectory>
</file>
</files>
<fileSets>
<fileSet>
<directory>src/main/resources/mapper</directory>
<outputDirectory>${tomcat-instance}/resources/mapper/</outputDirectory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
And then the pom.xml is modified to reference the new assembly before the existing assembly.
<descriptors>
<descriptor>src/main/resources/war-assembly.xml</descriptor>
<descriptor>src/main/resources/our-assembly.xml</descriptor>
</descriptors>
That seemed to work ok. It did leave the -temp war file lying around in the target folder which could potentially be removed to save any confusion.

Related

maven assembly plugin war packaging unexpected output result

I tried using the maven war plugin but is very opinionated on the folder structure and I need specific files into specific folders, so I've looked into using maven assembly plugin with the war format set.
Here's a snippet of the pom.xml.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/war-assembly.xml</descriptor>
</descriptors>
<finalName>${project.artifactId}-assembly</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
and the war-assembly.xml
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0 http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>war</id>
<formats>
<format>war</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>webapp/WEB-INF/lib</outputDirectory>
<excludes>
<exclude>*:war</exclude>
</excludes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/${project.artifactId}/WEB-INF</directory>
<outputDirectory>webapp</outputDirectory>
<includes>
<include>/**/*</include>
</includes>
<excludes>
<exclude>webapp/lib</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/${project.artifactId}</directory>
<outputDirectory>webapp</outputDirectory>
<includes>
<include>/**/*</include>
</includes>
<excludes>
<exclude>WEB-INF</exclude>
<exclude>META-INF</exclude>
<exclude>info.xml</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.basedir}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>README*</include>
<include>LICENSE*</include>
<include>NOTICE*</include>
</includes>
</fileSet>
</fileSets>
<files>
<file>
<source>${project.build.directory}/${project.artifactId}/info.xml</source>
<filtered>true</filtered>
<outputDirectory></outputDirectory>
</file>
</files>
</assembly>
this produces the desired outcome in terms of where i need the files to be copied to, except something still packages lib folder, classes folder and the web.xml into the webapp folder, which I do not want.
Outputted directory structure:
Expected Directory Structure (lib, classes and web.xml) are removed because they are in the webapp/WEB-INF sub folder:
am I using the maven plugin incorrectly? or a setting that I am overseeing? Or a way to set the output directories for the classes, lib, and the web.xml?

Maven assembly plugin - "install" folder

I have configured maven assembly plugin which generates "tar.gz" file.
However, when I untar, it somehow includes "install" folder at the beginning:
/install/lib
/install/scripts
My requirement is that, upon untar, it should have folders like below, no install directory:
/lib
/scripts
My pom.xml plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<finalName>install</finalName>
<descriptors>
<descriptor>assembly/app-assembly.xml</descriptor>
</descriptors>
<tarLongFileMode>posix</tarLongFileMode>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
app-assembly.xml:
<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>myapp</id>
<formats>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<excludes>
<exclude>src/**</exclude>
<exclude>readme.md</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Appreciate any help or guidance on this. Thanks for reading.
https://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
includeBaseDirectory: Includes a base directory in the final archive. For example, if you are creating an assembly named "your-app", setting includeBaseDirectory to true will create an archive that includes this base directory. If this option is set to false the archive created will unzip its content to the current directory.
Default value is: true.

How to provide a custom name to extracted folder from a zip, generated using maven-assembly-plugin

I'm using the maven assembly plugin to package a few directories into a zip file.
The following is the zip.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">
<baseDirectory>${project.build.directory}</baseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/bin</directory>
<outputDirectory>bin</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}/config</directory>
<outputDirectory>config</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.build.directory}/lib</directory>
<outputDirectory>lib</outputDirectory>
</fileSet>
</fileSets>
</assembly>
Following is the plugin configuration in pom.xml
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-zip</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>zip.xml</descriptor>
</descriptors>
<finalName>bootstrap</finalName>
</configuration>
</execution>
</executions>
</plugin>
When I run the assemply, a zip file is created with the name of my maven module, which is as expected. But when I extract this zip file, a folder named 'target' is created which is not very readable. How do i customize the name of this 'target' folder?

How to zip only specific directories using maven assembly plugin

I am using maven-assembly-plugin to create a zip file of the project when building the project. It is successful. Now what I want is to zip only specific directories in the project.
This is the code for plugin in my pom which I used previously.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make shared resources</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>resource.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
And the resource.xml file is as follows.
<assembly>
<id>resources</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<!-- Since it bundles all the units -->
<directory></directory>
<outputDirectory>/project</outputDirectory>
<excludes>
<exclude>pom.xml</exclude>
<exclude>*.iml</exclude>
<exclude>*.jar</exclude>
<exclude>**/src/**</exclude>
<exclude>**/target/**</exclude>
<exclude>resource.xml</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
I want to zip only some directories of the project in the maven build.
As an example I have following folder structure in the project.
project
|_directories
|_dir1
|_ ....
|_dir2
|_ ....
|_dir3
|_ ....
|_pom.xml
What I want is make zip file which only include the directories folder. When extracting my zip file that should only contain the four directories in it.
How can I achieve this?
Does the maven-assembly-plugin is enough to do this or should I create a mojo?
You misused directory and outputDirectory.
directory is the path in your project where the files to be zipped are taken from (so it should be directories in your case), outputDirectory the folder inside the generate zip file, where the fileset is place (since you do not want the toplevel directory, it should be /):
<assembly>
<id>resources</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<!-- Take everything inside the directories folder -->
<directory>directories</directory>
<!-- And place it inside the root of the zip file -->
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>

Maven - Using the Assembly plugin to package dependencies from multiple projects into one file

I’m working on a project that is made up of multiple other projects. It has the following structure:
MainProject
--projectA
--projectB
--projectC
--projectD
--parent
--projectE
...
--projectX
As you can see the parent is amongst the others. I’m not sure if this is unusual or not but it is the way it is and I have to just work with it.
I’m looking to use the Assembly plugin to get the dependencies from each of the sub projects and zip them up all within one folder. So for example, I want a zip file containing a folder which contains all of the unpacked dependencies of the children projects.
This is what I have so far:
assembly.xml (this is in the parent project)
[...]
<id>package</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<moduleSets>
<moduleSet>
<includes>
<include>com.example:../one</include>
<include>com.example2:../two</include>
<include>com.exampleX:../three</include>
</includes>
<binaries>
<outputDirectory>/library/jars</outputDirectory>
<unpack>false</unpack>
</binaries>
</moduleSet>
</moduleSets>
<dependencySets>
<dependencySet>
<unpack>false</unpack>
<scope>runtime</scope>
<outputDirectory>library/jars</outputDirectory>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<excludes>
<exclude>**.xml</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
and this is in the parent pom.xml
[...]
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>assembly</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
[...]
When I run a mvn clean install from cmd the build is successful. It does not however create a zip file containing my library/jars directory which should then contain all of the dependencies from each of the projects. It simply creates zips in each project. These zips do not contain the directory I want or any dependencies, they are simply zips of the each project directory. Can anyone see what I am doing wrong?

Resources