Maven assembly plugin - "install" folder - maven

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.

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?

How to create password-protected zip in maven

currently I am using maven-assembly-plugin to create a zip file via "mvn clean package". The whole process works fine, the zip contains everything I need but a new requirement asks to create this zip file password-protected. I googled but not found any useful; is there anyone who needed to perform this task ?
Current plugin is defined in this way:
<build>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-distribution</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly/zip.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</build>
and zip.xml is defined in this way:
<?xml version="1.0" encoding="UTF-8"?>
<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>zip</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<outputDirectory>directory1/</outputDirectory>
<directory>directory1</directory>
</fileSet>
<fileSet>
<outputDirectory>/</outputDirectory>
<includes>
<include>config.properties</include>
</includes>
</fileSet>
</fileSets>
<files>
<file>
<source>target/data-jar-with-dependencies.jar</source>
<destName>data-jar-with-dependencies.jar</destName>
</file>
</files>
</assembly>
You must use an external program to unzip and zip the archive again. For example 7z:
7z e Unprotected.zip
7z a Protected.zip -pPASSWORD UNPROTECTEDFILENAME
If you want to integrate it in the build lifecycle then you need the maven exec-plugin to execute those two commands after the package phase.

How can a jar with specific deps be created, after using maven-dependency-plugin to select the wanted deps?

My goal is to create a jar with specific dependencies from my dependency list in the pom. I'm using maven-dependency-plugin like so:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<includeScope>runtime</includeScope>
<excludes>META-INF/*.SF,META-INF/*.DSA,META-INF/*.RSA</excludes>
<outputDirectory>${project.build.directory}/uber-deps/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.some.blaClass</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
and an assembly.xml file holding:
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
<id>plugin</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
<includes>
<include>
${project.build.directory}/uber-deps/
</include>
</includes>
<excludes>
<exclude>*:sources</exclude>
</excludes>
</dependencySet>
</dependencySets>
</assembly>
After mvn clean install all relevant dependencies appear in target/uber-deps as I would expect. My problem is with the next plugin under <plugins> - maven-assembly-plugin. Seems to me as if it doesn't take uber-deps in.
I know this only by trying to unpack the jar using jar xf to see if the deps in uber-deps were packed in the jar created after mvn clean install.
What should be changed?
1)
The jar you are building as part of the assembly-plugin will be called (by default) ./target/<artifactId>-plugin.jar
Note that the plugin part is what you've put under id in your assembly xml file.
2)
Since you already unpack the dependencies to a folder, you should use fileSets rather then dependencySets:
<fileSets>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<includes>
<include>
${project.build.directory}/uber-deps/
</include>
</includes>
</fileSet>
</fileSets>
</fileSets>
3)
BTW if you want the outputs of your own project in that jar you should add another fileSet:
<fileSet>
<outputDirectory>/</outputDirectory>
<includes>
<include>
${project.build.outputDirectory}
</include>
</includes>
</fileSet>
4) Also just noted that your assembly plugin definition is not stating the location of your assembly xml file and that you try to define mainClass using shade-plugin configuration. This is how it should look in assembly plugin (assuming that your assembly file is located under src/assembly/plugin.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>src/assembly/plugin.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>com.some.blaClass</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>

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 package an assembly in Maven by moving resources out of the war?

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.

Resources