Prevent breakup of fat jars in dependencySet during maven-assembly-plugin build - java

I have a Maven project that is intended to be a demo of one of our products, which is itself a fat jar with several dependencies. We distribute the source code of these demos as a .zip file containing a self-contained Maven project that our customers can build and play around with.
I'm using the maven-assembly-plugin to do a custom assembly of our distributed demos project. I'm using a dependencySet to place our product's JAR in a lib/ directory in the final assembly. The problem is, the maven-assembly-plugin splits up our fat jar into the normal jar (without dependencies), and all of the dependencies of the jar. I would rather the plugin not split up the fat jar, and simply place the fat jar in the lib/ directory. Is there a way to do this?
assembly.xml:
<dependencySets>
<dependencySet>
<useProjectArtifact>false</useProjectArtifact>
<outputDirectory>lib/</outputDirectory>
<includes>
<include>our-product:jar</include>
</includes>
<outputFileNameMapping>our-product.jar</outputFileNameMapping>
</dependencySet>
</dependencySets>
pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>DemoManager</mainClass>
</manifest>
</archive>
<!-- Generates jar -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- Generates distributed demo project -->
<descriptors>
<descriptor>src/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-jar</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
</execution>
</executions>
</plugin>

Related

How to have a final jar with the dependency inside that jar in the jar format?

I need a configuration for Maven where all the libraries inside the project are in the final jar in the jar format... So i need to have jars inside the final jar. For that i can only use maven. I already tried without success with plugins like one-jar.
Thanks
To make a fat jar that includes all you jar files, add the following code to your pom.xml. When you clean and build the project this will automatically make a fat jar file. You need to give your main class inside <mainClass> tag. That's it.
<project>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>your.main.class</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>final-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Not sure for nested jar because I haven't tried yet.
But I have created .jar file with all project dependencies(specified in pom file)
Try following mvn command in terminal...
mvn org.apache.maven.plugins:maven-assembly-plugin:2.6:assembly -DdescriptorId=jar-with-dependencies package

run maven java project using batch file

I've a java application in which I'm using maven to load dependencies. My main method is in App.java and there are various other classes. This is a spring based application.
I've to run this application using batch file.
This is what I've tried so far:
made a manifest file to give main class name
generated a jar of application
in a lib folder placed all the jars which my app uses
in manifest gave all the jars path
But I want to know if there is any other way I can achieve the same thing. Here in manifest I've to give all the jars names
Also in application jar, a manifest file is automatically created. So I've to manually edit it to give main class name and all dependent jars.
Any help appreciated.
Thanks.
Use the Maven Jar Plugin to do what you want. You can configure it to place all your manifest entries to meet your needs.
<plugin>
<!-- jar plugin -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifestEntries>
<Main-Class>package.path.for.App</Main-Class>
<implementation-version>1.0</implementation-version>
</manifestEntries>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix> <!-- use this to specify a classpath prefix, in your case, lib -->
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
To facilitate copying all your dependencies to a particular folder, use the Maven Dependency Plugin:
<plugin>
<!-- copy all dependencies of your app to target folder-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory> <!-- use this field to specify where all your dependencies go -->
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>

How do I create an executable jar file including dependencies where the main class is in Test, using Maven

I am new to Maven and have a project with the following directory structure
project
-src
-main
-java
-org
-core
-starter.java
-test
-java
-org
-core
-testStarter.java
Both starter.java and testStarter.java are Main classes. However I wish to create an executable jar file (including dependencies) where testStarter.java is executed.
I added the following to my pom file:
<groupId>org</groupId>
<artifactId>proj</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>project</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>org.core.testStarter</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugins>
</build>
However everytime I run mvn clean package, it creates a package with only the compiled classes in the main directory and not the test directory. Hence everytime I run the jar file, it does not run, since the testStarter.class does not exist in the created jar file.
Is there a way I can create either
1) One big jar file containing test and main classes while it executes only the test class
2) Only the test classes but all dependencies are included.
According to you pom.xml you have already had a big jar with all dependencies and correct classname in manifest.
All you need now is to include your test classes into artifact.
One big jar file containing test and main classes while it executes only the test class. You can specify you /src/test directory as another source directory (see Maven compile with multiple src directories).
Only the test classes but all dependencies are included. You can mark your test directory as the only source directory by using sourceDirectory tag in build section. But I guess, your tests depend on code in main, so this configuration could fail on compile time.
p.s. I strongly recommend you to create separate build-profile for such case, because it seems strange for me to have main method for jar in test class.
Well, this seems kinda strange, but what you can do is to put testStarter under main (I suppose this won't work because it has references to other classes under the testfolder, am I right?). Btw, use CapitalCamelCase class names, that's more Java-ish.
Alternatively, you can use test-jar to create a jar for the tests (this might work if you add the original jar to the Class-Path manifest property), or you can start hacking the whole assembly of your project, but I wouldn't recommend that.
What I'd suggest is rethinking your project layout and clarifying your requirements. Probably you won't need this process.
I'd recommend using the Maven OneJar Plugin,
look here: https://code.google.com/p/onejar-maven-plugin/
"Lets you build an executable jar with Maven2, containing all dependencies"
As for you scoping issue-- You need to move that Main class to the src folder so that it can be in the compile scope.
Cheers!
We do this in our project by using a assembly.xml with the maven-assembly-plugin.
In the POM we have:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/resources/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>package-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
Then there is a assembly.xml in src/main/resources which tells how to build that assembly:
<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>bin</id>
<formats>
<format>jar</format>
</formats>
<!-- Adds dependencies to jar package under lib directory -->
<dependencySets>
<dependencySet>
<useProjectArtifact>true</useProjectArtifact>
<outputDirectory></outputDirectory>
<unpack>true</unpack>
</dependencySet>
</dependencySets>
</assembly>

How do I create a Netbeans style Jar with all dependencies in a lib folder?

As the question says, how to package a Netbeans Maven project exactly the way a Netbeans native project is packaged:
All the dependencies in a separate lib folder
The main project jar with a manifest that includes the lib folder on it's classpath
In your pom.xml file ...
1) Add this code to your project->properties node. This will define your main class in a central place for use in many plugins.
<properties>
<mainClass>project.Main.class</mainClass>
</properties>
2) Add this code to your project->build->plugins node. It will collect all your jar dependencies into a lib folder AND compile your main class jar with the proper classpath reference:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>${mainClass}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

How to package an Akka project

I have an Akka stand alone project
that implements the Bootable interface of the mico-kernel
The tutorials on paclaging an akka system with the micro-kernel
describes an SBT project that uses the sbt pluggin
Can nay one tell me how to package the maven project with the micro-kernel
A search on Google for "akka microkernel maven" lists this as one of the top contending answers to your question: http://jcranky.com/2012/07/13/akka-microkernel-with-maven/
after going through JCrnak's blog and reading through the maven assembly plugin and the manifest file documentation,I was able to come up with a slightly different solution from that of JCranky and will like to share.
The first assumption is that all the Akka plugins including that of the microkernel have been configured in the POM.xml. Secondly, that the application to be distributed has been developed.
The maven package phase creates an executable jar file. However this will need the main class of the application to be directly executed using the java -jar command. To make the location of the main class known to the package application , we insert the following plugin with the configuration of the manifest file in the POM.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.bbox.gesture.BoundingBox</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
To copy the akka dependencies into the lib file in the target file we add the following plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
With this plugins we copy all the necessary files to the target file.
Now we copy the content of the target file to a zip folder using the assembly plugin with the descriptor.xml file. below is the descriptor.xml file.
<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>akka</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/deploy</outputDirectory>
<includes>
<include>**</include>
</includes>
<excludes>
<exclude>*.jar</exclude>
<exclude>*.zip</exclude>
</excludes>
</fileSet>
</fileSets>
<files>
<file>
<source>target/com-bbox-gesture-1.0-SNAPSHOT.jar</source>
<outputDirectory>/deploy</outputDirectory>
<destName>bbox.jar</destName>
</file>
<file>
<source>src/main/resources/application.conf</source>
<outputDirectory>/deploy/config</outputDirectory>
</file>
</files>
</assembly>
To run the assembly plugin we add the following to the POM.xml
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptors>
<descriptor>/descriptor.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
To top it all we add a simple batch file that start's the application by running the java -jar command from withing the deploy directory. Below is the simple script from the batch file
echo off
cls
start java -jar bbox.jar
the start command runs the java -jar command on the executable jar file. the bbox.jar file is the executable jar
To run the application simply unpack the zip folder in your server , navigate to the start.bat file and click.

Categories