I am trying to use the Assembly plugin to include the dependecies as well as
Here is my assembly plugin
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>create-executable-jar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>
jar-with-dependencies
</descriptorRef>
</descriptorRefs>
<descriptors>
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>com.sarm.myproject.XMLParser.LPUnMarshaller</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
here is my assembly.xml descriptor, i made the id same as the descritpor ref as it was creating a different jar for this descriptor. So i have two descriptors one is a jar-with-dependencies descriptor ref and one is the below descriptor, in this case what is happening is that it creating two jars and the second jar overwrites the previous jar. How is it possible to include these two in the same jar.
<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>
<fileSets>
<fileSet>
<directory>${basedir}</directory>
<includes>
<include>*.xml</include>
</includes>
<excludes>
<exclude>30000dests.xml</exclude>
</excludes>
</fileSet>
<fileSet>
<directory>${basedir}/test</directory>
<includes>
<include>*.xml</include>
</includes>
</fileSet>
</fileSets>
</assembly>
Edit: I have tried some other approaches and i have seen that if i use the assembly.xml as a descriptor, a new jar is created along side any other default jar that is created as well. So i end up with two jars. The default jar is an executable like the jar plugin is configured. even though the assembly plugin is configured to have a manifest.mf with my main class name the jar created thru the assmbly.xml is not executable and has a folder of my projects name with the executable jar inside it.
I use mvn clean install to build my project and the jar file.
You should create two modules that produce two jars. Typically maven is going to produce one jar file per module with the module name as the jar name.
Maven recommends that each module have a single output artifact.
If you have concerns about duplicating code. You can inherit relevant stuff by have a parent pom.
Related
Right now if I run my project as a "Maven install", my Java Maven build creates a war file and a zip file, both under the same directory location.
How can I have this build add a regular folder to this directory location, and put the zip file inside that folder?
More Info
I tried using the maven-assembly-plugin. In repository.xml, I specify which files to put in my zip. The files are in ${project.basedir}/files. I tried putting the files inside an "extrafolder" so they're at ${project.basedir}/files/extrafolder, hoping this extra folder would be in my local repository, but Maven ignored the folder and still put both the war and zip in the same repository.
Here's the plugin in my POM:
<project>
[...]
<build>
[...]
<plugins>
[...]
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<descriptors>
<descriptor>src/assembly/repository.xml</descriptor>
</descriptors>
</configuration>
</plugin>
[...]
</project>
And here's the repository.xml file:
<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>repository</id>
<formats>
<format>tar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}/files</directory>
<outputDirectory>/</outputDirectory>
<filtered>true</filtered>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
</fileSets>
</assembly>
You should configure the outputDirectory as extrafolder if you need it. Example as below:
<fileSets>
<fileSet>
<directory>${project.basedir}/files</directory>
<outputDirectory>extrafolder</outputDirectory>
<filtered>true</filtered>
<includes>
<include>**/*.*</include>
</includes>
</fileSet>
</fileSets>
To configure the plugin to put the zip file into a specific folder as below:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<outputDirectory>extrafolder</outputDirectory>
<descriptors>
<descriptor>src/assembly/repository.xml</descriptor>
</descriptors>
</configuration>
</plugin>
Find more details here: https://maven.apache.org/plugins/maven-assembly-plugin/single-mojo.html#outputDirectory
I'd like to create a fat-jar which is autoexecutable (Shade Plugin), but also includes sources, resources, tests, and everything in a Eclipse-importable way.
The jar would be single-file executable app, which also contains the whole project in an importable fashion as a maven project someway (after unzipping the jar, I assume).
Another option would be a resulting project zip that includes the binary distribution at base level.
Is there such a thing?
A possible solution requires 3 steps:
Create an uber-jar of the project with the maven-shade-plugin. This JAR will contain all the dependencies and will be executable.
Create a side artifact consisting of the sources of the project with the maven-assembly-plugin. This ZIP will contain the pom.xml and all of the sources under src.
Create another side artitact that will effectively be our final artifact, that will contain both the unpacked shaded JAR (to make it effectively executable) and the sources ZIP.
This would be a possible configuration:
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>make-uberjar</id>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>fully.classified.name.to.main.Class</mainClass>
</transformer>
</transformers>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>sources</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly-sources.xml</descriptor>
</descriptors>
</configuration>
</execution>
<execution>
<id>final</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
This configures the execution of the maven-shade-plugin and 2 execution of the maven-assembly-plugin. The first execution will creates the sources ZIP. This would be the assembly-sources.xml assembly descriptor file:
<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>sources</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.basedir}</directory>
<includes>
<include>pom.xml</include>
<include>src/**</include>
</includes>
</fileSet>
</fileSets>
</assembly>
It includes pom.xml and everything under src into a ZIP having the sources classifier.
The second assembly.xml assembly descriptor file would be:
<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>jar-with-sources</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<includes>
<include>${project.groupId}:${project.artifactId}:jar:${project.version}</include>
</includes>
<unpack>true</unpack>
</dependencySet>
<dependencySet>
<useProjectAttachments>true</useProjectAttachments>
<includes>
<include>${project.groupId}:${project.artifactId}:zip:sources:${project.version}</include>
</includes>
</dependencySet>
</dependencySets>
</assembly>
This creates 2 <dependencySet>. The first one unpacks the shaded JAR (which replaced the main artifact at that point in the build). The second one simply includes the sources ZIP attached artifact; note that we need to use <useProjectAttachments> to include the attached sources ZIP.
When you run mvn clean install, you will have as result a file {finalName}-jar-with-sources.jar that will be your wanted executable JAR. It will also contain a ZIP file of all the sources in the root folder.
I found that using the maven assembly-plugin gives you the best control over these kind of things, for both an uber jar or an installable zip. The shade plugin works well for uber jars, but not so well for installer zips or installers.
In the past i also augmented that functionality by adding in the mix the izpack plugin, which creates a real installer, off of the distributable zip that you create with the assembly plugin.
For example, with the assembly-plugin you can choose to include or exclude certain file resources. This happens for example when you want to use a configuration file while working with the IDE, but you really want to exclude it in the final distribution zip, or you want to include a slightly different one.
Same happens when you want to generate an rpm: the assembly plugin can help quite a bit in first preparing what's needed for the rpm plugin to operate.
The assembly plugin comes with all sort of settings, which you declare in its xml configuration file and it is well documented.
In most cases, trying to pack all the application dependencies in a single .jar is a bad idea, mainly because .jars are not designed to be used this way. In fact, they might contain META-INF/ and other jar-specific files that might clash each other.
When I have to build binary distributions that can be run from the command line, I use the Assembly plug-in, as I've described in this post. If you need to distribute a GUI application or a one-click, self-contained web server, the approach would be very similar.
I'm building a web app with Dropwizard, and trying to use the Shiro bundle module (Maven repo) to integrate Shiro authentication.
My problem is that in the remote Maven repo the filename is dw-shiro-bundle-0.0.1-20130412.232035-4.jar, instead of dw-shiro-bundle-0.0.1-SNAPSHOT.jar. I understand this happens when you build the same SNAPSHOT version four times to avoid clobbering the first three, and the index takes care of finding the latest one.
However I'm also following this advice to avoid using maven-shade-plugin and effectively do the shading myself, since the final JAR is otherwise too big. maven-assembly-plugin is configured to copy the Shiro bundle JAR to lib/dw-shiro-bundle-0.0.1-SNAPSHOT.jar, but in the final JAR's MANIFEST.MF, the dependency is listed as io.ifar.dw-shiro-bundle-0.0.1-20130412.232035-4.jar, and hence I get a ClassDefNotFoundError at runtime.
A workaround is to manually rename the lib jar to io.ifar.dw-shiro-bundle-0.0.1-20130412.232035-4.jar so it gets picked up on the classpath, but it's not really a solution. Is there a way to either:
fix the MANIFEST.MF entry
normalize the name of third-party JARs as they are downloaded by Maven to strip any build numbers, or
automate the process of renaming the JAR file to include the build number?
My plugins are as follows:
In maven-jar-plugin:
<configuration>
<forceCreation>true</forceCreation>
<archive>
<manifest>
<mainClass>${mainClass}</mainClass>
<addClasspath>true</addClasspath>
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>lib/${artifact.groupId}.${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</customClasspathLayout>
</manifest>
</archive>
</configuration>
In maven-dependency-plugin:
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<prependGroupId>true</prependGroupId>
</configuration>
</execution>
</executions>
assembly.xml:
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<id>package</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>true</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target/dependency</directory>
<outputDirectory>/lib</outputDirectory>
<includes>
<include>**/*</include>
</includes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<includes>
<include>configuration.yml</include>
</includes>
</fileSet>
</fileSets>
</assembly>
As soon as I posted this I found the answer. I guess that's just how it goes.
Buried in the documentation for the Maven Archiver is a section on Handling Snapshot Versions, which says to replace ${artifact.version} with ${artifact.baseVersion}. And it works! The 20130412.232035-4 on the end is replaced with SNAPSHOT.
I want to build an application distribution with Maven. I have a module in my project which holds the main source code. I decided to build the application distribution from this module. I'm telling maven in the module's POM to copy all the configuration files and dependant libs to the target/ directory. My problem is that Maven keeps all the build related temporary dirs (like. classes, generated-sources, maven-archiver) in the target directory. I wan't to auto delete these at least during the install phase. How can i achive this? If i put the maven-clean-plugin to the end of the build it looks like Maven always deletes the whole target directory, no matter who i'm trying to exclude files what i'm trying to keep.
try this in your pom
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<executions>
<execution>
<id>user_distribution</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/dist.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
and here is the xml
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/xsd/assembly-1.1.1.xsd">
<id>dist</id>
<formats>
<format>zip</format>
</formats>
<files>
<file>
<source>target/${pom.artifactId}-${pom.version}.jar</source>
<outputDirectory>lib/</outputDirectory>
</file>
</files>
<fileSets>
<fileSet>
<directory>directory to be included</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>file name to be included</include>
</includes>
</fileSet>
<fileSet>
<directory>another directory to be included</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>
I'm telling maven in the module's POM to copy all the configuration
files and dependant libs to the target/ directory
How are you doing this?
Based on the question, it looks like you need to worry less about selectively deleting contents of target folder (which can be done by customizing maven clean plugin), but creating a distribution using maven assembly plugin (as pointed out by #Scorpion).
The latter allows you to bundle together all your project artifacts including the dependencies into zip or other formats, which can then be easily used by developers. You may want to decouple this from regular build by using a separate profile, so that the distribution is built only on need basis.
We have created a jar(Spring project) which we are including using Maven in another Spring project (war)
we can use this no problem if we include the required dependancies.
If I wanted to ensure the jar contained all it's depenadancies and used them what is the best way to go about this ?
To avoid having to include the dependancies I have tried in using the maven assembly plugin
which definately includes the files - but these appear to be ignored as they are still required as dependancies in the consuming project - any suggestions why?
POM detail for assembly plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<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>
</plugin>
You can use the maven winstone plugin to create a standalone executable jar with all dependencies included of the war, the jar etc....
Adding
<plugins>
<plugin>
<groupId>net.sf.alchim</groupId>
<artifactId>winstone-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<goals>
<goal>embed</goal>
</goals>
<phase>install</phase>
</execution>
</executions>
<configuration>
<filename>${project.parent.build.finalName}.jar</filename>
</configuration>
</plugin>
...
</plugins>
will bundle all modules of your app, wars and jars, and any needed dependencies in a executable jar which includes a servlet engine.
This works really nice to give a single deployable bundle to your Ops team for deploying.
I would advise against creating a jar which contain all dependencies to be used by the war however. You are likely to end up with multiple copies of slightly different versions of the same classes in the class path. Certain libraries are a bit euhhmmm, ..., temperamentfull about this (hibernate and log4j spring to mind).
Maven does a decent job of figuring out which dependencies to take, and if things break mvn dependency:tree make things a lot clearer. You lose this when you create an uber-jar.
If there are good reasons to do this, I would recommend an environment where you can tightly control the classpaths like a full-blown J2EE server or using an OSGi container. However, be careful what you wish for : these are not kittens to be handled without (iron) gloves.
I use the following assembly configuration to create a jar with all runtime dependencies included:
<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>runnable</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>