How to run a jar with lib? - java

I have this jar file 'domain-directory-configurator-cli-3.1.3000.0.0.0.jar' that doesn't contain dependancies
I have also this file 'domain-directory-configurator-cli-3.1.3000.0.0.0-lib.zip'
I want to run the jar file and my application using the libs.
What is the current syntax?
I tried
java -cp 3.1.3000.0.0.0/domain-directory-configurator-cli-3.1.3000.0.0.0.jar com.imperva.itp.directory.configurator.cli.MainClass
but I keep getting the exception :
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory
so how do I refer the jar to work with the lib file?

You can do this by using the maven plugin maven-assembly-plugin
https://maven.apache.org/plugins/maven-assembly-plugin/usage.html
http://tutorials.jenkov.com/maven/maven-build-fat-jar.html

Assuming domain-directory-configurator-cli-3.1.3000.0.0.0-lib.zip does contain a number of jar files, you would have to extract themand list them one by one on the classpath.
More user friendly would be to have an executable jar where the main class is already mentioned in the manifest. Note you can configure the classpath in the manifest as well,so for a uer it could be sufficient to run java -jar domain-directory-configurator-cli-3.1.3000.0.0.0.jar and both the main class and the classpath are taken from the manifest.
In case you are using Maven, the below combination can help. It downloads all dependencies into the lib directory and configures both the main class and the classpath into the project's jar file.
<project>
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addDefaultEntries>true</addDefaultEntries>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.imperva.itp.directory.configurator.cli.MainClass</mainClass>
</manifest>
<manifestEntries>
<Build-Date>$(enf.BUILD_DATE)</Build-Date>
<Build-Date-Formatted>$(enf.BUILD_DATE_FORMATTED)</Build-Date-Formatted>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Finally, when distributing your application do not forget to deliver not only your jar but also the lib directory with content.

Related

Create Executable Jar with Maven (maven-assembly-plugin) Not Working vs. Eclipse Export Function

I am trying to create a runnable jar using maven (maven-assembly-plugin) which includes all required libraries in a generated jar file, maven successfully creates .jar file however when executing it seems some libraries are not being correctly loaded (specifically it is trying to load com.ibm.mq.jms classes it throws a DetailedJMSException: JMSCC0091), however when exported in eclipse as a runnable jar it successfully creates a runnable jar and when executed no exceptions are thrown.
Just wondering how I can use maven to do the same as the eclipse export runnable jar function without the exception?
Note: I have also tried a similar approach using maven-shade-plugin with the same exception thrown.
Here is the relevant build information in my pom.xml:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<groupId>org.apache.maven.plugins</groupId>
<executions>
<execution>
<id>make-executable-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.tapcons.execute.Execute</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
seeing other questions related to this you may should remove ur plugin from the pluginmanagement.
see here:
maven assembly plugin is not working with pluginManagement

Maven - Dependency folders inside a lib directory in Jar [duplicate]

I am using Maven in my standalone application, and I want to package all the dependencies in my JAR file inside a library folder, as mentioned in one of the answers here:
How can I create an executable JAR with dependencies using Maven?
I want my final JAR file to have a library folder that contains the dependencies as JAR files, not like what the maven-shade-plugin that puts the dependencies in the form of folders like the Maven hierarchy in the .m2 folder.
Well, actually the current configuration does what I want, but I am having a problem with loading the JAR files when running the application. I can't load the classes.
Here's my configuration:
<plugins>
<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}/classes/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>com.myapp.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>install</id>
<phase>install</phase>
<goals>
<goal>sources</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
The project runs fine from Eclipse, and the JAR files are put in the library folder inside my final JAR file as I want, but when running the final JAR file from the target folder I always get ClassNotFoundException:
Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
Caused by: java.lang.ClassNotFoundException: org.springframework.context.ApplicationContext
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: com.myapp.MainClass. Program will exit.
How can I fix this exception?
The following is my solution. Test it if it works for you:
<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}/classes/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>test.org.Cliente</mainClass> -->
</manifest>
<manifestEntries>
<Class-Path>lib/</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
The first plugin puts all dependencies in the target/classes/lib folder, and the second one includes the library folder in the final JAR file, and configures the Manifest.mf file.
But then you will need to add custom classloading code to load the JAR files.
Or, to avoid custom classloading, you can use "${project.build.directory}/lib, but in this case, you don't have dependencies inside the final JAR file, which defeats the purpose.
It's been two years since the question was asked. The problem of nested JAR files persists nevertheless. I hope it helps somebody.
Updated:
<build>
<plugins>
<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>
</plugins>
</build>
The simplest and the most efficient way is to use an uber plugin like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<finalName>uber-${project.artifactId}-${project.version}</finalName>
</configuration>
</plugin>
You will have de-normalized all in one JAR file.
The executable packer maven plugin can be used for exactly that purpose: creating standalone java applications containing all dependencies as JAR files in a specific folder.
Just add the following to your pom.xml inside the <build><plugins> section (be sure to replace the value of mainClass accordingly):
<plugin>
<groupId>de.ntcomputer</groupId>
<artifactId>executable-packer-maven-plugin</artifactId>
<version>1.0.1</version>
<configuration>
<mainClass>com.example.MyMainClass</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>pack-executable-jar</goal>
</goals>
</execution>
</executions>
</plugin>
The built JAR file is located at target/<YourProjectAndVersion>-pkg.jar after you run mvn package. All of its compile-time and runtime dependencies will be included in the lib/ folder inside the JAR file.
Disclaimer: I am the author of the plugin.
following this link:
How To: Eclipse Maven install build jar with dependencies
i found out that this is not workable solution because the class loader doesn't load jars from within jars, so i think that i will unpack the dependencies inside the jar.
Here´s how I do it:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.project.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
And then I just run:
mvn assembly:assembly
I found this answer to the question:
http://padcom13.blogspot.co.uk/2011/10/creating-standalone-applications-with.html
Not only do you get the dependent lib files in a lib folder, you also get a bin director with both a unix and a dos executable.
The executable ultimately calls java with a -cp argument that lists all of your dependent libs too.
The whole lot sits in an appasembly folder inside the target folder. Epic.
=============
Yes I know this is an old thread, but it's still coming high on search results so I thought it might help someone like me.
This is clearly a classpath problem. Take into consideration that the classpath must change a bit when you run your program outside the IDE. This is because the IDE loads the other JARs relative to the root folder of your project, while in the case of the final JAR this is usually not true.
What I like to do in these situations is build the JAR manually. It takes me at most 5 minutes and it always solves the problem. I do not suggest you do this. Find a way to use Maven, that's its purpose.

Eclipse and Maven - resources in jar

I know this question was asked many times before, but I still can't manage it to work.
What I want to achieve is to create jar which will load resource (packed in jar) in runtime, without broking resource loading while executing application from Eclipse.
My project structure is standard:
src/main/java
src/main/resources
src/test/java
src/test/resources
Code for load image resource:
ClassLoader classLoader = getClass().getClassLoader();
splashImage = ImageIO.read(new File(classLoader.getResource("img/splash.png").getFile()));
It is working fine when starting the App from the Eclipse. However, when I export the runnable jar from the Eclipse, it doesn't works.
Exported jar have /resources/img folder in it's root directory. But when the app starts, an exception is thrown:
Caused by: javax.imageio.IIOException: Can't read input file!
How it is possible to make it work from runnable jar file and when running the App from the Eclipse?
I was also trying to build jar with maven plugins, but with no luck.
<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>
<groupId>org.apache.maven.plugins</groupId>
<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>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>foo.bar.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
You should go the following way for loading your resource:
classLoader.getResourceAsStream("/img/splash.png")
The point is that src/main/resources will automatically being copied to target/class which is the root of your classpath. This will work in Eclipse as well from the packaged jar.
An runnable jar will be created by maven via maven-assembly-plugin like this:
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
[...]
</project>
After you have added this you can create the full runnable jar via:
mvn clean package
This will produce a jar file in target folder which looks like: ´whatever-1.0-SNAPSHOT-jar-with-dependencies.jar´.
What i don't understand is the usage of maven-dependency-plugin in your build?

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 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>

Categories