how to exclude project class files when using maven assembly plugin? - java

I am using maven assembly plugin to package all my dependencies in a zip inside lib folder.
I am also adding the project artifact using
<useProjectArtifact>true</useProjectArtifact>
The only problem is that in the final zip I am also seeing the project class files. I want to exclude them since lib already contains the artifact, but after trying various options, no success so far.
here is my assembly.xml
<assembly>
<id>binary</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
<unpack>false</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>

The classes of your project appear in your assembly because your are including them in your assembly with this :
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
So if you don't want your project's classes in your assembly then you have to remove this part from your assembly descriptor.
As a reminder, the variable ${project.build.outputDirectory} is by default the folder target/classes.

Related

Add scala test-case to jar file in maven project

I want to include scala test case to the jar file. I have maven project.
I have used following :
<assembly>
<id></id>
<formats>
<format></format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<includes>
<include>...</include>
</includes>
</dependencySet>
<dependencySet>
<outputDirectory></outputDirectory>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test/scala</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*.class</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
Can anybody tell me what is the way to add scala testcase into jar file using
mvn clean package
Thanks.
You need to create a fat jar with test-classes and external dependencies. The Maven Assembly Plugin is the obvious choice:
Plugin example:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>com.example.MainTest</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
You also need to create a descriptor file, in the src\main\assembly folder an assembly.xml file with the following content:
An example:
<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>fat-tests</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>**/*.class</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
Build Jar:
mvn clean compile test-compile assembly:single
Run Jar:
java -jar fat-jar-include-tests.jar

How to exclude log4j.properties file when building fat jar with Maven assembly plugin

I am bundling a FAT jar from 'my.jar' and its dependencies. 'My.Jar' contains log4j.properties file and 'my.jar' dependencies include Log4j.jar which also has log4j.properties file bundeled in log4j.jar file by default. now when assembly plugin combines all jars it put the default log4j.properties file but exempt the log4j.properties file from my jar file.
How can i instruct assembly plugin to exclude log4j.properties file from default Log4j.jar file and use put it from my jar into final Fat jar? or it must override the default file from provided file.
Here is my assembly descriptor
<?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>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
<useProjectAttachments>true</useProjectAttachments>
</dependencySet>
<dependencySet>
<scope>system</scope>
<unpack>true</unpack>
<includes>
<include>sample:com.sample</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>

Maven assembly include snapshot depedencies

I am noticing that maven-assembly-plugin doesnt want to include snapshot dependencies in the assembly jar. Is this by design or am i doing something wrong.
<dependency>
<groupId>com.xxx.zzz</groupId>
<artifactId>projectname</artifactId>
<version>1.7.0-SNAPSHOT</version>
</dependency>
There are multiple snapshot dependencies like this, so I hate to include them explicitly in the assembly descriptor.
Question 1:
Is there a way to include the snapshot dependencies in the bundle too?
Question 2:
Can you help to figure out how to include all dependencies (compile, test, provided and runtime) in the assembled jar . By default, maven considers only the runtime jars
Following is the maven-assembly section in the pom
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>${project.basedir}/assembly.xml</descriptor>
</descriptors>
<tarLongFileMode>gnu</tarLongFileMode>
<finalName>${project.artifactId}-${project.version}</finalName>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Here is assembly descriptor 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>dist</id>
<includeBaseDirectory>true</includeBaseDirectory>
<formats>
<format>jar</format>
</formats>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>true</useTransitiveDependencies>
<unpack>false</unpack>
<fileMode>0755</fileMode>
<directoryMode>0755</directoryMode>
<includes></includes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<includes>
<include>database/**</include>
<include>deploy/**</include>
</includes>
<excludes>
<exclude>**/*.tmp</exclude
</excludes>
<directory>${project.basedir}</directory>
</fileSet>
</fileSets>
</assembly>
Could you please shed some light?
as for question 1, to include snapshot dependencies from the current build, use a moduleSet
http://maven.apache.org/plugins/maven-assembly-plugin/examples/multimodule/module-binary-inclusion-simple.html
that is, if they come from the current reactor. otherwise you will have to build them and depend on a release version.
figured out the answer for 2nd question. Thanks to Bo Ni, who posted this blog: http://bosbluebluesky.blogspot.com/2012/11/maven-package-jar-file-include-all.html
All i had to do was include different scope in multiple dependencyset sections individually
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>true</useTransitiveDependencies>
<unpack>false</unpack>
<scope>runtime</scope>
<fileMode>0755</fileMode>
<directoryMode>0755</directoryMode>
<includes></includes>
</dependencySet>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>true</useTransitiveDependencies>
<unpack>false</unpack>
<scope>compile</scope>
<fileMode>0755</fileMode>
<directoryMode>0755</directoryMode>
<includes></includes>
</dependencySet>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>true</useTransitiveDependencies>
<unpack>false</unpack>
<scope>provided</scope>
<fileMode>0755</fileMode>
<directoryMode>0755</directoryMode>
<includes></includes>
</dependencySet>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useProjectArtifact>false</useProjectArtifact>
<useTransitiveDependencies>true</useTransitiveDependencies>
<unpack>false</unpack>
<scope>test</scope>
<fileMode>0755</fileMode>
<directoryMode>0755</directoryMode>
<includes></includes>
</dependencySet>
</dependencySets>

Deploying jars for production in Maven

I have multiple Java projects (packaged to jars) in my product which have a single pom combining them as modules. Each of the projects has different dependencies and their combined dependencies are defined in the parent pom. I want to prepare the output for production and do the following:
deploy (copy) all my jars to a single location
copy the 3rd party jars from all projects to a different single folder
copy the configuration files (found under the src/main/resources) from all the projects to a third folder.
Anyone knows of a way to do it without having to manually copy each of the above for all the projects? I also want my future projects to support this deployment procedure without having to work too hard and specific.
You need to use Maven assembly plugin for this - here is example of zipping distributive (on production you need then just to unzip):
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${project.basedir}/src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
and 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>${env}</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<includes>
<include>com.mycompany:ear-project</include>
<include>com.mycompany:jnlp-project</include>
</includes>
<outputDirectory>libs</outputDirectory>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>src/main/resources</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
<fileSet>
<directory>target/docbook/pdf</directory>
<includes>
<include>index.pdf</include>
</includes>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
Please NOTE that for your 2 projects (EAR, JNLP) you can place dependencies via outputDirectory configuration.
I have the same requirements in my project.
There is a difference between using the Jenkins with ClearCase and SVN.
If you were using SVN you should have checked out your projects into your main project, and worked on them like there were on the same dir.
After checking out my child projects I can work on them, in the example you can see a portion from the assembly.xml, in which core and scheduler are the child projects.
</fileSet>
<fileSet>
<directory>./core/src/main/resources/</directory>
<outputDirectory>./examples</outputDirectory>
<includes>
<include>*</include>
</includes>
</fileSet>
<fileSet>
<directory>./scheduler/src/main/resources/</directory>
<outputDirectory>./examples</outputDirectory>
<includes>
<include>*</include>
</includes>
</fileSet>
This will basically copy the resources folder content into the main project example project.
You can do the same here, if all you projects are on the same vob, and available, you should specify a relative location to which you are going to copy all your resources.
For example:
</fileSet>
<fileSet>
<directory>../../../your_sub_project1/src/main/resources/</directory>
<outputDirectory>./examples</outputDirectory>
<includes>
<include>*</include>
</includes>
</fileSet>
<fileSet>
<directory>../../../your_sub_project2/src/main/resources/</directory>
<outputDirectory>./examples</outputDirectory>
<includes>
<include>*</include>
</includes>
</fileSet>
This way, when running the primary pom, you will be able to access the content of the sub projects and copy the resources to a certain folder.
Hope it helps..
I will summarize What I did in the assembly XML (to answer all of my issues) in addition to Andrey Borisov answer.
deploy (copy) all my jars to a single location [Used the "moduleset" element]
copy the 3rd party jars from all projects to a different [Used the "dependencySets" element]
copy the configuration files (found under the src/main/resources) from all the projects to a third folder. [Used the "fileset" element]
http://maven.apache.org/xsd/assembly-1.1.2.xsd">
bin
dir
false
<moduleSets>
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<binaries>
<outputDirectory>modules</outputDirectory>
<unpack>false</unpack>
</binaries>
</moduleSet>
</moduleSets>
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>my DIR 1</directory>
<excludes>
<exclude>*log4j*</exclude>
</excludes>
<outputDirectory>resources</outputDirectory>
</fileSet>
<fileSet>
<directory>my DIR 2</directory>
<outputDirectory>resources</outputDirectory>
</fileSet>
</fileSets>

How to create a release package with maven?

I build a desktop application using Maven2.
I'd like to make a release from time to time (just copy all the project's and third party jars into a single dir and generate a run.bat file).
How to do it ?
You need to create run.bat yourself and place it in src/main/assembly/scripts, for example. Then you need to create an assembly.xml file in src/main/assembly.
Here is an example of an assembly.xml file that you might want to use. It creates a tar.gz with all your dependency jars and your run.bat.
<assembly>
<id>1.0</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/lib</outputDirectory>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>target</directory>
<outputDirectory>/lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/assembly/scripts</directory>
<outputDirectory>/scripts</outputDirectory>
<includes>
<include>*.bat</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Finally, in your pom.xml file add the assembly plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
</plugin>
Now, when you run "mvn install" you should see your tar.gz created.
To release run:
mvn release:prepare
mvn release:perform
OK I got it with a little help of dogbane's answer
I used my own assemlby file src/main/assemlby.assembly.xml
<assembly>
<id>teleinf</id>
<formats>
<format>dir</format>
</formats>
<moduleSets>
<moduleSet>
<includes>
<include>pl..........:core</include>
<include>pl..........:gui</include>
</includes>
<binaries>
<outputDirectory>../../release</outputDirectory>
<unpack>false</unpack>
</binaries>
</moduleSet>
</moduleSets>
<fileSets>
<fileSet>
<directory>src/main/assembly/</directory>
<outputDirectory>../../release</outputDirectory>
<includes>
<include>*.bat</include>
</includes>
</fileSet>
</fileSets>
</assembly>
and added following to pom
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</plugin>
I had to write a run.bat myself - so it's not fully satisfying but will do.
i would go with the maven release plugin, see:
maven release plugin
using maven release plugin
Just an addition to the answer given by dogbane
Your .bat file will running packaged jar file with a filename reflecting the current version of the application, e.g.
java -Xms256m -Xmx350m -jar bin\yourApp-1.10.1-SNAPSHOT.jar
On every release this file will need to get updated with a new version name of the application. This can be automatized, too.
In your pom.xml file add this section:
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>${project.build.sourceDirectory}/../assembly/scripts</directory>
<includes>
<include>yourApp.bat</include>
</includes>
</resource>
...
</resources>
...
</build>
This asumes that you have put the yourApp.bat file in the folder:
src/main/assembly/scripts
Content of the yourApp.bat file should look like this:
java -Xms256m -Xmx350m -jar bin\${project.build.finalName}.jar
Just run the Maven commands and enjoy.

Categories