Packing one tar created using maven assembly into another tar using maven assembly - maven

I have created a tar(say project.tar) using maven assembly descriptor.
I need to create one more tar(say final.tar) file which would contain the previously created tar (project.tar) along with one script file.
To do this 'm trying using two descriptors specified in pom.xml. One descriptor is for project.tar and second for final.tar .
While doing so I'm facing the following error.
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.4:single (default-cli) on project ede: Failed to create assembly: Error creating assembly archive bin: A tar file cannot include itself. -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.4:single (default-cli) on project ede: Failed to create assembly: Error creating assembly archive bin: A tar file cannot include itself. "
My pom.xml file is
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly/src.xml</descriptor>
<descriptor>assembly/final.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</plugin>
...
I've also tried using pom.xml file as
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly/src.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
</execution>
<execution>
<id>bin</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>assembly/final.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<finalName>ede2</finalName>
</configuration>
</execution>
</executions>
</plugin>
In this way, it's not able to locate the descriptors files.
Could anyone please guide me if 'm doing anything wrong?

I know that this post is very old but I think it might need some explanations.
In my opinion, the best way for what you want to do is to use two executions of the maven-assembly-plugin. The first will generate your project tar and the second you final tar. (please read all the answer before saying that there is more simple)
Here is what I would do (and it works of course).
As I like to have the assemblies in different folders (because I think it is easier like that), I declare properties in my pom with the directories paths :
<properties>
<myproperties.assembly.project-tar.dir>${project.build.directory}/assembly-project/</myproperties.assembly.project-tar.dir>
<myproperties.assembly.final-tar.dir>${project.build.directory}/assembly-final/</myproperties.assembly.final-tar.dir>
</properties>
Then in the maven-assembly-plugin I configure the executions (never forget that the order of the executions is very important because they will be executed in the declaration order if they are binded on the same phase) :
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<executions>
<execution>
<id>project-tar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<outputDirectory>${myproperties.assembly.project-tar.dir}</outputDirectory>
<descriptors>
<descriptor>src/assembly/project-tar.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>final-tar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<outputDirectory>${myproperties.assembly.final-tar.dir}</outputDirectory>
<descriptors>
<descriptor>src/assembly/final-tar.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
(you can see that the tars will be in different folders and that the project tar will not have the assembly id appended to its name so it will look like myproject-1.0.tar)
Now concerning the assemblies definitions.
For the project-tar.xml, I just include the jars in it, you can do whatever you want :
<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>project</id>
<formats>
<format>tar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
And for the final-tar.xml, I include the project tar and the scripts I have in my folder src/main/scripts :
<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>final</id>
<formats>
<format>tar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${myproperties.assembly.project-tar.dir}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>*.tar</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/scripts</directory>
<outputDirectory></outputDirectory>
<fileMode>755</fileMode>
</fileSet>
</fileSets>
</assembly>
And there we are, you have your two tars.
There is a solution more simple which is as you did at the beginning :
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<executions>
<execution>
<id>project-tar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assembly/project-tar.xml</descriptor>
<descriptor>src/assembly/final-tar.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
<configuration>
<appendAssemblyId>true</appendAssemblyId>
</configuration>
</plugin>
The descriptors order is very important of course.
The only difference with your initial solution is that I keep the property appendAssemblyId set to true because if not, the two assemblies will have the same name and when the maven-assembly-plugin will try to build the final assembly it will detect that there is a file which is already having this name and will fail saying that it cannot include itself...
With my solution in two executions, you can set the appendAssemblyId to false.

Part of the answer is to use the descriptorRef as outlined in the assembly plugin examples.
Hopefully that will give you something to get started with.

Related

maven assembly and depedency plugin - copying files works when using archives, fails when using dir

I have 2 projects: ProjA and ProjB. ProjB depends on ProjA. What i'm trying to do is simply copy several files from ProjA (which is packaged with assembly plugin) to ProjB (which is just standard jar) in the package phase.
There are two cases - one works, the other doesn't work. But first here are the relevant files:
ProjA pom:
<build>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assembly/distribution.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
ProjA assembly descriptor:
<id>native-libs</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>dir</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.dll</include>
<include>*.so</include>
</includes>
</fileSet>
</fileSets>
ProjB pom:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy native lib</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>someGroupID</groupId>
<artifactId>ProjA</artifactId>
<version>0.1-SNAPSHOT</version>
<type>dir</type>
<classifier>native-libs</classifier>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
In the first case, if i use <packaging>zip</packaging> in ProjA's assembly descriptor, and then set ProjB's <goal>unpack</goal> and <packaging>zip</packaging>, it all works as expected.
In the second case, if i use <packaging>dir</packaging> and <goal>copy</goal>, as it is given in the examples, ProjB fails with error: Failed to execute goal ...:copy on project ProjB: Unable to find artifact.: Could not find artifact...
Is this some bug i'm facing or i'm doing something plain wrong? Again, it works if i change packaging to zip and goal to unpack; it fails for packaging dir and goal copy.

Maven assembly: generate a resource zip file and include it into the main assembly zip file

How can I proceed to include a generated zip file into a main zip file with the Maven Assembly plugin?
For example, I have the following folder structure:
./folderA/
./file1
and I want to generate a zip file where the content is like this:
folderA.zip
file1
Here my simplified config':
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project >
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptor>${basedir}/assembly-zipFolderA.xml</descriptor>
<finalName>folderA.zip</finalName>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptor>${basedir}/assembly.xml</descriptor>
<finalName>${module-zipFinalName}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>
assembly-zipFolderA.xml
<assembly>
<id>folderA-zip</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>folderA</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>
assembly.xml
<assembly>
<id>main</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<files>
<file>
<source>file1</source>
</file>
<file>
<source>folderA.zip</source>
</file>
</files>
</assembly>
===> with this config, Maven complains that it can't find folderA.zip...
Don't declare the plugin twice; instead, you need to declare two executions of the maven-assembly-plugin.
The first execution will create the first assembly and then, the second execution will use this assembly to create the final one. Both of those executions will be bound to the package phase, and Maven will invoke the plugin's execution in the order of declaration in the POM.
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>make-folderA</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/assembly-zipFolderA.xml</descriptor>
</descriptors>
<finalName>folderA</finalName> <!-- name without extension -->
<attach>false</attach>
</configuration>
</execution>
<execution>
<id>make-assembly</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${basedir}/assembly.xml</descriptor>
</descriptors>
<finalName>${module-zipFinalName}</finalName>
</configuration>
</execution>
</executions>
</plugin>
A couple of notes:
The <finalName> should not contain the extension, so a finalName of folderA will produce the archive folderA.zip after the ZIP assembly is made.
The first assembly will be created inside the build directory, which is target by default. As such, the second one needs to reference it there with:
<file>
<source>${project.build.directory}/folderA.zip</source>
</file>
in its assembly descriptor.
Since the first assembly is not the final one, you probably don't want it attached, i.e. as an additional artifact produced by your project. You can disable this by setting attach to false. This will make sure only the last final one is considered when deploying or releasing.
descriptor is a deprecated parameter, you should use descriptors instead.
With such a configuration, running mvn clean package will produce the correct archive inside the build folder.

Creating multiple zip files with assembly plugin - no assembly descriptors found

In addition to creating a war file in my pom (which works fine) I'm trying to create a couple of ZIP files that include only some of my content. Previously I had just one zip file and created my own assembly descriptor using the zip format, and this worked fine. When I wanted to add a second zip file with different content, I had to change my plugin to multiple executions. Now when I run it I get an error message that says no assembly descriptors found and that the build failed.
What's funny is that it actually is doing everything it needs to do. It creates the war file. It creates the two zip files, even though it says it failed to do so. But this maven build is one of many run by an automated deployment process, and if it gets an error message, that's not going to fly.
This is the plugin section of my pom:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>zip-metricsscnapshot</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<outputDirectory>src/main/webapp/resources</outputDirectory>
<finalName>metricssnapshot</finalName>
<descriptors>
<descriptor>src/main/assembly/zip.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>zip-metricdetails</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<outputDirectory>src/main/webapp/resources</outputDirectory>
<finalName>metricdetails</finalName>
<descriptors>
<descriptor>src/main/assembly/details-zip.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
Solved
addendum:
I run maven with clean yuicompressor:compress assembly:assembly package.
My src/main/assembly directory contains two files, zip.xml and details-zip.xml. They are mostly identical except for the element and the filesets. Here's the zip.xml file:
<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>widget</id>
<baseDirectory>/</baseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>src/main/webapp/resources/metricssnapshotwidget</directory>
<excludes>
<exclude>**/metricssnapshotwidget.js</exclude>
<exclude>**/metricssnapshotwidget.css</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>

Create a tar with maven generated jar with dependenceis and few other files

I'm new to maven and its interesting subject to learn.
Succeed to create a jar with dependencies, using:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</configuration>
</plugin>
Now, i have to include few shell scripts and generated jar to a tar.
To achieve this, i ve tried the following way:
Added
<descriptors>
<descriptor>hadoop-job.xml</descriptor>
</descriptors>
to the above script.
In hadoop-job.xml i'm including required files into tar.
The problem is tar is generated first and says no *.jar found in target.
Is there a way to schedule jar creation first and tar next, since both the configurations reside in assembly plugin.
OR
Is there a command to execute and generate a jar first and then a command to generate a tar ?
By the way i'm executing mvn clean assembly:assembly -Dbinary=true.
Help me to resolve. Thanks.
Here is an example of assembly building the jar-with-dependencies and after that a tar that includes this jar-with-dependencies (built by the maven-assembly-plugin just before). In the tar I also includes the shell script files in .sh from the folder src/main/bin.
First, the plugin configuration :
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<executions>
<execution>
<id>jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorId>jar-with-dependencies</descriptorId>
</descriptorRefs>
</configuration>
</execution>
<execution>
<id>all</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/assembly/all.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/assembly/</outputDirectory>
</configuration>
</plugin>
The order of the executions is important because if I want to include the jar-with-dependencies into my tar I need to have it built before.
I put all the assemblies in the same folder, that's why I have a global configuration tag additionally to the configuration tag of the executions
And then the content of my assembly file all.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>all</id>
<formats>
<format>tar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory></outputDirectory>
<includes>
<include>**/*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>755</fileMode>
</fileSet>
</fileSets>
</assembly>
The includeBaseDirectory is here to avoid my tar containing the root folder with the name of the project with the version.
If you don't specify the outputDirectory tags, the folder structure into your archive will begin from the root of the project, for example it will include your jar with the path target/your-project-1.0-SNAPSHOT.jar.
EDIT : The plugin configuration that I did before could be simplified with just the following :
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<executions>
<execution>
<id>jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorId>jar-with-dependencies</descriptorId>
<descriptors>
<descriptor>src/assembly/all.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
<configuration>
<outputDirectory>${project.build.directory}/assembly/</outputDirectory>
</configuration>
</plugin>
The reason is because in the maven-assembly-plugin the descriptorId is read before the descriptors so that's good for our case but if not, we would need two executions as done higher with care about the order.
The same attention have to be done for the order of the descriptors, they are performed in the reading order (it can seems logic but I think it might be useful to indicate it).

Maven: release single file, set line endings

I would like to release single file to Nexus repo (deploy script, sh) and for that purpose I am using
build-helper-maven-plugin:attach-artifact
Unlike Maven Assembly Plugin, it hasn't explicit option to set line ending of the deployed file. How can I solve the task using this or other plugin.
Important: I need file deployed as .sh and not as archive. Otherwise it's possible to switch to Maven Assembly Plugin.
Let me share final solution. I hope it would help someone one day...
pom.xml
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>deploy-script-assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>deploy-script-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${build.directory}/${project.artifactId}-${project.version}-single/deploy-script.sh</file>
<type>sh</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
deploy-script-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>single</id>
<formats>
<format>dir</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<files>
<file>
<source>deploy-script.sh</source>
<outputDirectory>/</outputDirectory>
<lineEnding>unix</lineEnding>
</file>
</files>
</assembly>
The maven-assembly-plugin has a format dir which is simply a folder structure on the hard drive which you can use to copy the sh script to that folder and convert linenendings and use build-helper-maven-plugin to attach that artifact afterwards.

Resources