How to make jar file independent? - java

Please, could you explain me why my jar file doesn't execute outside the target folder? And how can I do it independent? To copy/paste it to another directory.
When I execute my jar outside target folder, NoClassDefFound error is produced. It can't load jars from dependencies.
This is my pom.xml:
<properties>
<docx4j.version>3.3.0</docx4j.version>
</properties>
<build>
<plugins>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.epam.executor.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR with runtime dependencies so that this program can be executed from command line using java -jar command -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.docx4j</groupId>
<artifactId>docx4j</artifactId>
<version>${docx4j.version}</version>
</dependency>
</dependencies>
I execute my jar via this command with 3 parameters:
java -jar DocumentTemplate-1.0.jar D:\Trash\xml1.xml D:\Trash\template.docx D:\Trash\results.docx

I think you need to create one jar which includes all its executable dependencies also. I have been you one-jar plugin for it. try below plugin .
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.kulhade.elasticsearch.Indexer</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>

Copy Dependencies to a specific directory
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.build.finalName}.lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Make the Jar Executable and Classpath Aware
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
<mainClass>${fully.qualified.main.class}</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
At this point the jar is actually executable with external classpath elements.
$ java -jar target/${project.build.finalName}.jar

Related

Avoid libraries binding in jar file upon building maven project

I have made a spring project and created a seperate directory for libraries/dependencies but whenever i build the project libraries are included in jar file along with being copied in libraries directory which resulted in increasing my jar file size to 47 MB. I want my jar to read libraries from directory mentioned in pom.xml file but jar file must not have libraries in it.
Following is the build tag of my pom.xml file
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<!--<goal>copy-dependencies</goal>-->
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.kalsym.requestresponsesimulator.RequestResponseSimulatorApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>

Maven manifest file issue

I have been struggling with this for some time. I have a Maven project that builds and packages just fine with one problem. I have a jar I am using that is NOT in my companies version of NEXUS. I added the jar to my .m2 repository through this command line command:
mvn install:install-file -Dfile=c:/u/lib/terajdbc4-15.00.00.20.jar -DgroupId=com.teradata -DartifactId=terajdbc4 -Dversion=15.00.00.20 -Dpackaging=jar
This jar will NOT append to the manifest file when the jar is built. So, when I need this jar, the code dies because it can't find the resource it's looking for (the teradata driver)
Is there any way to add this single jar to the manifest file IN ADDITION TO the other jars I'm already adding to the manifest?
Here is the build section from the parent pom file:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/Crunchify</outputDirectory>
<resources>
<resource>
<directory>resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/Crunchify/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>ap.invalert.handler.InvAlertHandler</mainClass>
</manifest>
<manifestEntries>
<Class-Path>.</Class-Path>
</manifestEntries>
</archive>
<finalName>Crunchify/Crunchify</finalName>
</configuration>
</plugin>
</plugins>
</build>

Maven dependency stripVersion creates wrong classpath

I am trying to compile a project with Maven (through Eclipse), while stripping versions from dependency JARs. I have the following in my pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<stripVersion>true</stripVersion>
</configuration>
</execution>
</executions>
</plugin>
And indeed, the JARs are copied into lib/ without the version numbers. Alas, I get ClassNotFound, because the MANIFEST.MF in the generated executable JAR contains a classpath referring to the files including the version numbers, which naturally are not there.
What am I doing wrong, and how do I fix it?
Edit: JAR is created with maven-jar-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>my.main.class</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
</archive>
</configuration>
</plugin>
I am using Run as -> Maven Install (Eclipse with m2e plugin)
Change the maven-jar-plugin to create a custom classpath layout without the version
Example:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<classpathLayoutType>custom</classpathLayoutType>
<customClasspathLayout>lib/$${artifact.artifactId}.$${artifact.extension}</customClasspathLayout>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>

How to package a pom project as runnable jar [duplicate]

This question already has answers here:
How can I create an executable/runnable JAR with dependencies using Maven?
(33 answers)
Closed 9 years ago.
I have a free project that is all based on Free and Open source programs:
some of them have pom and public accessible jars
some of them have pom but no public accessible jars
some of them have no pom
I want to distribute the project as a unique jar since all licences are compatible I legally can, if it's possible to generate such a jar with maven, I don't know how. Can you help?
If it's not possible what is the best way to distribute such project?
My pom is managed by netbeans, here is the missing configuration:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<!-- I added the following -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>net.hypermove.graphitidb.GraphitiDB</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
There are many options for you
Maven Assembly Plugin with jar-with-dependencies descriptor
Maven One Jar Plugin
Distribution Jar - Zip Archive with your jar, all dependencies in directory lib and configured manifest for easy execution. Sample configuration below.
Executable Jar with Maven Shade Plugin
Runnable Jar with dependencies mapped to local maven repository (possible, but not portable) Altering The Classpath: Using a Maven Repository-Style Classpath
1. Jar Assembled With Dependencies
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>eu.codearte.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
2. Maven One Jar
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>eu.codearte.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
<executions>
<execution>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
...
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
3. Distribution Jar configuration
Maven Dependency Plugin
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
<stripVersion>false</stripVersion>
<stripClassifier>false</stripClassifier>
</configuration>
</execution>
</executions>
</plugin>
Maven Assembly Plugin
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/bundle.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
Maven Jar Plugin
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>exe-jar</id>
<goals>
<goal>jar</goal>
</goals>
<phase>package</phase>
<configuration>
<classifier>exe</classifier>
<archive>
<manifest>
<mainClass>eu.codearte.MainClass</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<useUniqueVersions>false</useUniqueVersions>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
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>bundle</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target/lib</directory>
<outputDirectory>lib</outputDirectory>
</fileSet>
</fileSets>
<files>
<file>
<source>target/project-exe.jar</source>
<outputDirectory>/</outputDirectory>
</file>
</files>
</assembly>

Different MANIFEST.MF for default jar-file and tests.jar

I'm trying to create different MANIFEST.MF files for the jar-packaged artifacts and the test-jar-packaged. The maven-jar-plugin being used to add additional stuff into the MANIFEST.MF - that works perfectly so far. But if I'd like to chose different template file for the MANIFEST.MF for the testproject, Maven only uses the second referenced template for both artifacts...
How can I get Maven to use the PROD-MANIFEST.MF-template for the normal jar-packaging and the TEST-MANIFEST.MF-template for test-jar-packaging?
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>test-manifest-mf</id>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestFile>foo/TEST-MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>default-manifest-mf</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestFile>foo/PROD-MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
Wrap each plugin configuration you have provided in a profile.
<profiles>
<profile>
<id>PROD</id>
<build>
<plugins>
// your PROD plugin configuration
</plugins>
</build>
</profile>
<profile>
<id>TEST</id>
<build>
<plugins>
// your TEST plugin configuration
</plugins>
</build>
</profile>
</profiles>
Then you invoke Maven with a profile
mvn package -P PROD
Hope that helps.
Try this:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>test-manifest-mf</id>
<phase>package</phase>
<goals>
<goal>test-jar</goal>
</goals>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestFile>foo/TEST-MANIFEST.MF</manifestFile>
</archive>
</configuration>
</execution>
<execution>
<id>default-manifest-mf</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
<manifestFile>foo/PROD-MANIFEST.MF</manifestFile>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
This configuration is performing 2 different executions of the same plugin, each of which has its own archive configuration.
If there is a parent pom somewhere in your hierarchy that has the archive configured outside of an execution, like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
... other archive config ...
</archive>
</configuration>
</plugin>
then that configuration will be merged with what you have by default. If you don't want that to happen, add the combine.self attribute to the <archive> element like so:
<archive combine.self="override">
as described in the plugins section of the POM reference.

Categories

Resources