maven assembly, avoiding full path in zip file? - maven

I have a multi-module project which contains 2 modules (each with its own pom.xml) and a parent pom.xml pointing to those modules.
When I run "mvn clean package" on the parent pom, each project ends up with a zip file under it's own target folder. I would like to package a zip file containing each module zip file under the zip file's root folder but I am having some issues doing so.
I have created an assembly file in the parent pom.xml folder:
<!-- Release distribution -->
<assembly>
<id>release</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/projectA/target/</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.tar.gz</include>
</includes>
</fileSet>
<fileSet>
<directory>${basedir}/projectB/target/</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.tar.gz</include>
</includes>
</fileSet>
</fileSets>
</assembly>
While the above works, if we start adding more and more modules to this project, it gets very annoying to have to keep updating this assembly.
Ideally I'd like for it to automatically just go into every target folder for a module and get a zip file in there.
This can be accomplished by doing
...
<fileSet>
<directory>${basedir}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/target/*.tar.gz</include>
</includes>
</fileSet>
however the issue here is the zip file will contain full paths, so rather than having zip files inside the root folder, the zip file will have projectA/target/xxxx.zip and projectB/target/xxxx.zip which is exactly what I do not want.
Is there any way to make a simple assembly in maven so I don't have to update it everytime I add a new module and not have full paths inside the zip?
EDIT 1
It looks like this is simply not possible. Either you get a nicely structured zip file with a hard to maintain assembly or you get an easy to maintain but annoingly structured zip file.
I'll leave this unanswered until I can find a proper solution
EDIT 2
Back at looking for a solution for this again. Regarding khmarbaise solution posted below there are a few issues with it:
- It relies on assemblies of dependencies, in my case I just want an assembly of assemblies (Which are more like fileSets and not dependencyset)
- The fact that it relies on me manually specifying which projects I want to have included in the assembly. I already have this information in the parent pom which specifies which modules should be built, so if I remove a module from the parent pom so that it is no longer built, the assembly should already know that and skip picking that project (Reason for which fileset seems to work so well except for the shitty, non-controllable path inside the assembly zip). I shouldnt have to manually mess with what modules I want included other than simply removing adding modules from the pom I am running the assembly from.
Has nobody really ever run into a similar problem?

First i would suggest to create dist-packaging module which contains the resulting package. Furthermore it sounds like your assembly-descriptor for creating the final archive which contains the zip files of others is wrong.
<id>proj1-assembly</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<unpack>false</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
But you must be aware that you have to maintain the dependencies in the dist-module as usual module dependencies like the following:
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>package-one</artifactId>
<version>${project.version}</version>
<classifier>package-1-assembly</classifier>
<type>zip</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>package-two</artifactId>
<version>${project.version}</version>
<classifier>package-2-assembly</classifier>
<type>zip</type>
</dependency>
....
Here you can find a full working example.

I just ran into the same problem: My resulting zip file contained the full system path! My original configuration looked like that:
<fileSets>
<fileSet>
<directory>${project.basedir}/src/main/resources</directory>
<outputDirectory>${project.build.directory}</outputDirectory>
<includes>
<include>someFolder/somefile.txt</include>
</includes>
</fileSet>
</fileSets>
As the result my zip file contained full system path!
After lots of investigating I found a working solution:
<fileSets>
<fileSet>
<outputDirectory>./</outputDirectory>
<directory>src/main/resources</directory>
<includes>
<include>someFolder/somefile.txt</include>
</includes>
</fileSet>
</fileSets>
So when specifying the outputDirectory with ${project.build.directory} then for some strange reason the full path will be part of the jar/zip file.

Related

Maven, exclude all classes but one under a package

This may sound silly, but I really want to know if I can do that (by adding some 'magic' configuration in pom.xml).
Let's say, I have a project which has a bunch of packages, one of them, say 'com.foo.bar', has quite a few .java files, including one named 'Dummy.java'.
Now, when generating the jar file, I want to exclude all classes under com.foo.bar, except the 'Dummy'.
I tried regular expression in a section, but no luck.
Is there an easy way to go? Many thanks.
With a "sledge hammer" (assuming Dummy.class not .java):
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<includes>
<include>com/foo/bar/Dummy.class</include>
</includes>
<!-- alternatively(!) excludes/exclude* -->
</configuration>
</plugin>
... or with a "Swiss army knife": maven-assembly-plugin ... ^^!"%/"))
...
To use the Assembly Plugin in Maven, you simply need to:
choose or write the assembly descriptor to use,
configure the Assembly Plugin in your project's pom.xml,
and
run "mvn assembly:single" on your project.
...
with an assembly descriptor like:
<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>dummy-only</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<outputDirectory>/</outputDirectory>
<directory>${project.build.outputDirectory}</directory>
<includes>
<include>com/foo/bar/Dummy.class</exclude>
</includes>
</fileSet>
</fileSets>
</assembly>
see also: I wish to exclude some class files from my jar. I am using maven-assembly-plugin. It still adds the files. I dont get any error

Maven: add non-JAR dependency

I'am using the maven-assembly-plugin to create a tar.gz archive. Now I need to include files in that archive. These are just a bunch of plain old text files and are a dependency at runtime, not at compile or (unit) test time.
I thought about adding a maven dependency on that but these files are not stored in a maven repository but in a simple remove folder. To make it even worse, this folder is password protected. I could, in a pre-build-step, download these password-protected files into a local folder. But then there is still the problem of using those files in the assembly. Also, this is extra work I want to avoid.
Is there any way to do that?
If you can download those files, workaround password. Maybe this will help.
Create mod assembly project where you put something like that:
<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>${artifact.version}</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>true</useTransitiveDependencies>
<unpack>false</unpack>
<excludes>
<exclude>${project.groupId}:*:*</exclude>
</excludes>
<outputFileNameMapping>project${timestamp}_code-${artifact.name}.${artifact.extension}</outputFileNameMapping>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<includes>
<include>readme.txt</include> <!-- here's that plain file -->
</includes>
</fileSet>
</fileSets>
You can include those files in fileSets.
http://maven.apache.org/plugins/maven-assembly-plugin/examples/single/filtering-some-distribution-files.html for more info

maven-assembly-plugin include *.properties at root level of zip

I'm trying to get maven to include my *.properties files when it zips up my artifacts. They are located inside src/main/resources. I tried adding the fileSet element to my assembly file, but the resources are not being included in the zip. I saw this question which seems to indicate that adding fileSet should work.
plugins.xml:
<?xml version="1.0"?>
<assembly>
<id>release</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.properties</include>
</includes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<useTransitiveFiltering>true</useTransitiveFiltering>
</dependencySet>
</dependencySets>
</assembly>
The properties that you want to include inside your ZIP are located in the src/main/resources source directory of your project. So the <fileSet> element should point to this directory.
${project.build.directory} is Maven current build directory, which is by default target. You could also point to the temporary directory where Maven copies all resources during the build but it is preferable to stick with the permanent data where possible.
As such, you just need to change your <fileSet> element with:
<directory>src/main/resources</directory>

Create maven uberjar without including an internal pom file

I have a maven build setup but it has been requested that I make one change to the uberjar and that is to not include the pom file, because it messes up my clients subsequent build that uses my uberjar as a dependancy. I know this is not the way to do this but my client cannot access my central repo because of security issues. So the uberjar was settled on as a deployment method. Now the question is this: Is there a way to not include the pom file in the creation of a jar via maven?
Thanks,
Blair
I assume you are using the maven-assembly-plugin to build your uberjar and using an assembly descriptor. What you want to do is instruct the assembly plugin (via the assembly descriptor) to exclude any files named "pom.xml". For example:
<assembly>
<id>bin</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target/classes</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<unpackOptions>
<excludes>
<exclude>**/pom.xml</exclude>
</excludes>
</unpackOptions>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
</dependencySet>
</dependencySets>
</assembly>
The key here is the "unpackOptions" section and the exclusion contained therein.
Hope that helps, if so please remember to mark my answer as correct so I get the reputation points.

Maven Assembly: Introduce java doc from a separate project

I have an assembly descriptor to generate a separate package for our documentation, including the javadoc. It contains the following to include generated javadoc from the same project it's
running in (assembly is a subproject from core):
<fileSet>
<directory>../core/target/site/apidocs</directory>
<outputDirectory>javadoc</outputDirectory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
But how can I include java doc from a completely separate project which I do not know the path on the file system to, just have the .m2 repo let's say. I have tried the following but it does not seem to do anything:
<dependencySets>
<dependencySet>
<includes>
<include>com.company:company-utils:*:javadoc</include>
</includes>
<outputDirectory>apidocs-util</outputDirectory>
<unpack>true</unpack>
</dependencySet>
</dependencySets>
Any ideas appreciated.
Thanks
Jonas
Assuming the javadoc of the project that you are interested has been installed/deployed to local/remote repository, you can get it into your assembly by adding it as a dependency in your pom with javadoc as <classifier>.
<dependency>
<groupId>com.company</groupId>
<artifactId>company-utils</artifactId>
<version>1.0-SNAPSHOT</version>
<classifier>javadoc</classifier>
</dependency>
The following snippet in the assembly descriptor (without the classifier) worked for me.
<dependencySets>
<dependencySet>
<includes>
<include>com.company:company-utils</include>
</includes>
<outputDirectory>apidocs-util</outputDirectory>
<unpack>true</unpack>
</dependencySet>
</dependencySets>
Why would you like to create the javadoc within a different project than the current one. It is created during the default release cycle. So need to make a separate assembly for that. Or if you think you need something supplemental apart from the javadoc check the documentation for the maven-javadoc-plugin
BTW: Never make packaging from a different package than your own, cause that will produce trouble.

Resources