Why maven assembly create manifest if file format is rar? - maven

I have a Maven project with the following assembly descriptor:
<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>assemby-id</id>
<formats>
<format>rar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<files>
<file>
<source>${project.build.directory}/resources/file.txt</source>
<outputDirectory>/</outputDirectory>
</file>
</files>
If the format is rar, I get a folder META-INF with a manifest file in the rar.
Can someone explain why?

The maven-assembly-plugin does not support the rar archive format. Quoting the format documentation, the list of supported formats is:
"zip" - Creates a ZIP file format
"tar" - Creates a TAR format
"tar.gz" or "tgz" - Creates a gzip'd TAR format
"tar.bz2" or "tbz2" - Creates a bzip'd TAR format
"jar" - Creates a JAR format
"dir" - Creates an exploded directory format
"war" - Creates a WAR format
When the archiver encounters an unknown format, it defaults to jar and for this format, a META-INF directory is created by default.
As such, the assembly you have created is not a valid RAR file. It is in fact a JAR file.

The maven-assembly-plugin uses the maven-archiver for packaging. The maven-archiver adds a MANIFEST.MF to your package.
Update:
As mentioned here, you may configure the maven-archiver-plugin to leave out the DefaultImplementationEntries:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>false</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>

Related

Zip file empty using maven assembly plugin in pom

my pom.xml but i have written something like
.......
..........
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<finalName>${project.artifactId}</finalName>
<descriptor>assembly.xml</descriptor>
</configuration>
<executions>
<execution>
<id>create-archive</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
..........
.......
My assembly.xml is
<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>${project.version}</id>
<includeBaseDirectory>false</includeBaseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}/${create.stage.directory}</directory>
<includes>
<include>*.*</include>
</includes>
<outputDirectory>${project.basedir}/${create.release.directory}</outputDirectory>
</fileSet>
</fileSets>
</assembly>
This creates an EMPTY foldername.zip in target!!NOT IN THE OUTPUT FOLDER LOCATION THAT I HAVE GIVEN.Is it always target? cant i override??
But in the given directory path I have 3 folders (in which some files) and readme.txt.I just tried giving *.txt inside include tag still I got empty zip folder. I initially guessed that my directory path and output directory path can be wrong.I directly hardcode still there is no luck.
Please help (This question is not duplicate but similar, and I have tried almost all stackoverflow questions related to this.they haven't solved anything)
For details see http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_fileSet
Your descriptor is now configured like this:
create a zip called ${project.artifactId}
from the directory ${project.basedir}/${create.stage.directory} put all files with an extension (not directories, since it says *.*, not something like **/*.* in the ${project.basedir}/${create.release.directory} folder inside the zip.
Especially the last part is weird. Where in the zip should these files end? It should be a relative path to make it predictable.
Don't like the zip file to be created in target? Set the outputDirectory in the plugin configuration, not in the assembly descriptor.

Packaging into a tar file in maven without creating a jar file

I'm trying to package a text based file into .tar using maven. To achieve this I used an assembly plugin and it worked, but along with the file tar a jar is also being generated. How can I avoid that?
<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>configuration</directory>
<fileMode>0444</fileMode>
</fileSet>
</fileSets>
</assembly>
You can change the packaging of your project.
I guess current packaging is jar, and thus the creation of a jar.
You may use pom and configure the assembly plugin to attach its result (the tar) to your build.
You could also configure the jar plugin, to skip the creation of empty jar (if it is your case).
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<skipIfEmpty>true</skipIfEmpty>
</configuration>
</plugin>

Maven: Three Jars in one project. Trying to use an assembly, but not getting pom.xml and pom.properties embedded in the jars

I have a project that produces three different jar files:
Server.jar: This contains all classes and resources. A standard jar
Client.jar: This contains only a few external classes and no resources.
ServerSDK.jar: This contains all the classes, resources, test classes, and other configuration files.
I've decided to do all three jars in a single project, so a change in any of the sources spawns a Jenkins build and deploys all three at once. I build the Server.jar as my standard pom.xml jar. Then, I use assemblies to build the Client.jar and the ServerSDK.jar.
I have the assemblies that build the other two jars, and everything is 99% of the way I like it, but there is bit of munging I'd like to do.
We add a few entries in our MANIFEST.MF file to incorporate the Jenkins build information and project information.
In a standard Maven jar, the pom.xml and pom.properties are embedded in the META-INF directory.
The first one I have managed to do via the <assembly> configuration in my maven-assembly-plugin. The second one I can't seem to get to work even though I have <addMavenDescriptor> set to true in my <assembly> configuration.
Here's my maven-assembly-plugin section in my pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<addMavenDescriptor>true</addMavenDescriptor>
<manifestSections>
<manifestSection>
<name>Build-Information</name>
<manifestEntries>
<Project-Name>${env.JOB_NAME}</Project-Name>
<Build-Number>${env.BUILD_NUMBER}</Build-Number>
<SVN-Revision>${env.SVN_REVISION}</SVN-Revision>
</manifestEntries>
</manifestSection>
<manifestSection>
<name>Module-Information</name>
<manifestEntries>
<Group-ID>${project.groupId}</Group-ID>
<Artifact-ID>${project.artifactId}</Artifact-ID>
<Version>${project.version}</Version>
</manifestEntries>
</manifestSection>
</manifestSections>
</archive>
</configuration>
<executions>
<execution>
<id>Client</id>
<configuration>
<finalName>Client</finalName>
<appendAssemblyId>true</appendAssemblyId>
<descriptors>
<descriptor>src/assembly/client.xml</descriptor>
</descriptors>
</configuration>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
The <manifestSections> work just fine, but the <addMavenDescriptor> doesn't seem to be working although I've explicitly set it to true.
According to the documentation on the maven-archiver-plugin:
Whether the created archive will contain these two Maven files:
The pom file, located in the archive in META-INF/maven/${groupId}/${artifactId}/pom.xml
A pom.properties file, located in the archive in META-INF/maven/${groupId}/${artifactId}/pom.properties
The default value is true.
According the maven-assembly-plugin page:
<archive>
This is a set of instructions to the archive builder, especially for building .jar files. It enables you to specify a Manifest file for the jar, in addition to other options. See Maven Archiver Reference
Is there something simple I'm missing here?
The Maven Assembly Plugin actually ignores the addMavenDescriptor parameter, and will never include the Maven descriptor in the resulting assembly. This can be seen in the source code: only the META-INF/MANIFEST.MF file is possibly added to the JAR archive.
I couldn't find an existing JIRA issue about this, so I went ahead and created MASSEMBLY-835 to track this.
A work-around for now would be to add the files yourself in the assembly descriptor:
<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>client</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<files>
<file>
<source>pom.xml</source>
<outputDirectory>META-INF/maven/${project.groupId}/${project.artifactId}</outputDirectory>
</file>
<file>
<source>${project.build.directory}/maven-archiver/pom.properties</source>
<outputDirectory>META-INF/maven/${project.groupId}/${project.artifactId}</outputDirectory>
</file>
</files>
<!-- rest of your configuration -->
</assembly>
This adds a <files> configuration that adds the pom.xml and the generated pom.properties into the target directory.
Note that the pom.properties is generated by the Maven Archiver component during the default package goal into the target/maven-archiver directory; therefore, in order for it to be present when making your assembly, the Assembly Plugin has to be bound to the phase package (or later in the lifecycle), and the current Maven project needs to be of packaging JAR / WAR / EAR / EJB / RAR... but not POM which doesn't package an archive. The primary artifact of the Maven project also needs to be built (if you skip the generation of the primary JAR of a JAR project, the pom.properties won't be generated).
This works in a large majority of cases. But if you want a bullet-proof solution, you can just create the file yourself. Create a pom.properties somewhere in your project (example, base directory) with the following content:
#Generated by Apache Maven ${maven.version}
version=${project.version}
groupId=${project.groupId}
artifactId=${project.artifactId}
and in the previous assembly descriptor, have instead:
<file>
<source>pom.properties</source>
<outputDirectory>META-INF/maven/${project.groupId}/${project.artifactId}</outputDirectory>
<filtered>true</filtered>
</file>
This would correctly replace the placeholders inside the pom.properties that was created, and mimic what Maven Archiver would do.

Maven assembly plug-in - how to produce artifact with custom file extension?

I am producing an artifact named foo.bar.zip from the following...
My pom.xml plug-in entry looks like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptor>src/assembly/bin.xml</descriptor>
<finalName>foo.bar</finalName>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
My descriptor file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<formats>
<format>zip</format>
</formats>
<fileSets>
etc. etc.
My question, is how do I produce a file with a custom extension? E.g. with the name foo.bar instead of foo.bar.zip.
I solved this by combining:
maven-assembly-plugin
copy-rename-maven-plugin
build-helper-maven-plugin
The assembly plugin has a configuration option to not attach the file, so I do that:
<configuration>
...
<attach>false</attach>
</configuration>
Then I use the copy-rename-maven-plugin to rename the file, produced by assembly-plugin, from zip to my custom file type (in my case it is CLI).
After that I use build-helper-maven-plugin to attach the artifact with the custom file type.
Assembly supports just these formats:
"zip" - Creates a ZIP file format
"tar" - Creates a TAR format
"tar.gz" or "tgz" - Creates a gzip'd TAR format
"tar.bz2" or "tbz2" - Creates a bzip'd TAR format
"jar" - Creates a JAR format
"dir" - Creates an exploded directory format
"war" - Creates a WAR format
You should consider to use antrun plugin in a later goal/phase to rename file extension

How to Exclude Certain Jar Dependencies while creating jar without using maven?

I am working on a core Java project. I am writing an Apache Storm topology and need to exclude storm jars while binding the topology into jar. Is there any way to do this without using maven? I know with maven we can use <scope>provided</scope> but I need an alternative to this.
PS: I am using Eclipse.
I use Gradle for compiling the JAR files for topologies. It allows you to exclude certain files when generating JAR files.
The example below shows the set-up that I use in my build.gradle file
apply plugin: 'java'
apply plugin: 'eclipse'
configurations {
provided
compile.extendsFrom provided
}
jar {
dependsOn configurations.runtime
from {
(configurations.runtime - configurations.provided).collect {
it.isDirectory() ? it : zipTree(it)
}
}
manifest {
attributes 'Main-Class': 'com.example.myclass'
}
}
dependencies {
provided files('./lib/asm-4.0.jar')
provided files('./lib/carbonite-1.4.0.jar')
# ... The rest of the Storm jars found in the lib directory of your storm installation
}
By default the directory structure Gradle expects is
MyProjectName
- build.gradle
- src
- main
- java
- [Your Java Files]
- resources
- resources
- [Mutlilang files / other resources]
From the command line when you run gradle build in the directory containing your build.gradle file a JAR file should be generated under .\build\libs
There is also a Gradle plugin for eclipse
If you are using Maven instead of Gradle, and you come here for excluding lib of Storm in building, I have the solution and a working example.
The documentation of Storm tells us to exclude the Storm dependency and provides a link to a page of Maven, which explains how to do it but it lacks a full example. It turns out that we have to create another XML file as the descriptor of assembly configuration, instead of putting the configuration directly in the pom.xml, even when Eclipse does not complain about putting the two files together.
Here is how:
We have our pom.xml with assembly plugins, pointing to another descriptor xml file:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptors>
<descriptor>/src/main/resources/exclude-storm.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>path.to.main.class</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
Note the part of: (should be complete path)
<descriptors>
<descriptor>/src/main/resources/exclude-storm.xml</descriptor>
</descriptors>
And in this path:
<?xml version="1.0" encoding="UTF-8"?>
<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>exclude-storm</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>true</unpack>
<scope>compile</scope> <!-- note here!!!! -->
<excludes>
<exclude>org.apache.storm:storm-core:jar:1.1.1</exclude>
</excludes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>${project.build.outputDirectory}</directory>
</fileSet>
</fileSets>
</assembly>
Here we add the settings of Maven doc page.
The most important thing: format of exclusion: should be: (ref)
groupId:artifactId:type[:classifier]:version
And the scope! runtime is default, I changed it to compile and it works.
At last, when you compile, use:
clean assembly:assembly
And turn on debug output to see full output in console. If you:
have a successful build
search the output and haven't found anything like: [WARNING]The following patterns were never triggered in this artifact inclusion filter: o 'org.apache.storm:storm-core:jar:1.1.1'.
the jar contains no default.yaml
Then you know you have succeeded.
Thanks for the inspiration of another question and answers: How to exclude dependencies from maven assembly plugin : jar-with-dependencies?

Resources