Problems running executable jar with dependencies - java

Hey so I have been working on a project that I want to be able to run as an executable jar from the command line. I have been able to create the jar with dependencies using Mavens assembly:single command. My pom looks like this.
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<manifest>
<mainClass>org.openmetadata.main.OmadUpdate</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
The build is successful and creates the jar omad-update-0.0.1-SNAPSHOT-jar-with-dependencies.jar. I go to my projects target folder in the command line and type
java -jar omad-update-0.0.1-SNAPSHOT-jar-with-dependencies.jar
I have also tried
java -cp omad-update-0.0.1-SNAPSHOT-jar-with-dependencies.jar org.openmetadata.main.OmadUpdate
Unfortunately in each case I am given a java.lang.NoClassDefFoundError: org/openmetadata/main/OmadUpdate. I am confused because I know my main class is in the package org.openmetadata.main and yet it is not found. I find this especially confusing because in my pom I specify that class as my main class. I have tried changing the name of the main class to src.main.java.org.openmetadata.main.OmadUpdate and simply OmadUpdate as well but neither seems to have an effect. Thanks for any help in advance.

I do not see a Class-Path entry in the manifest above, but your very long filename mentions dependencies. If there are jars within this jar file that your program is dependent on, you must enumerate them in the Class-Path section. See Adding Classes to the JAR File's Classpath for more details.

Another option might be to use the onejar-maven-plugin. Unfortunately the usage page is a bit scarce, but the plugin does what is supposed to when configured correctly.

I finally have been able to get this to work by adding the following code to my pom.
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>org.openmetadata.omadupdate.OmadUpdate</mainClass>
</manifest>
</archive>
<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>
</plugins>
</build>
Without the executions tag in the pom along with its children only the maven dependencies will be added to the jar and the classes from the project itself will not be added.

Related

Maven - generate war and fat jar in same module

I need generate war and fat jar (jar with all dependencies) in same pom.
I found many similar threads on this site, but still have a problem.
In my pom I set packaging to war and add the maven-war-plugin and maven-assembly-plugin:
...
<packaging>war</packaging>
....
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
....
Note used maven-assembly-plugin version - 2.2-beta-5. In my tests its the only version that produce the correct jar file in this configuration. Unfortunately, it also prints many "[INFO] already added, skipping" lines and the build process takes too much time.
If I use the latest version of maven-assembly-plugin (2.6), there are no "already added" info prints and the build at least 3 times faster, but unlike in 2.2 version all my class files placed into /WEB-INF/classes/ folder (should be in root), so I cannon run any main class from this jar. All classes from dependency jars placed in root as expected.
Are there any plugin configuration parameters in the latest version that can help produce the correct jar?
You don't have to get all the classes from dependencies in your root location. Let the assembly plugin do its wonders. As far as running the main class is concerned, you can use the below code in addition to what you already have.
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
[...]
<archive>
<manifest>
<mainClass>org.sample.App</mainClass> // specify your main class here.
</manifest>
</archive>
</configuration>
[...]
</plugin>
[...]
</project>

how to avoid resource override when using maven to generate runnable jar?

I have one maven project and depend one jar which contain one resource file(c3p0.xml), I copy the resource into my src/main/resource folder and change the content according to my requirements so that I can use it.
but after I run the mvn assembly:assembly command, the generated jar contained resource's content is old in dependence jar not my content in src/main/resource How to handle it?
My pom.xml's key content is as followed:
<plugin>
<!-- mvn assembly:assembly -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.fastcheck.RequestUrl</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
The jar-with-dependencies assembly mechanism uses the maven dependencies you've declared, and not from what's in your resources directory. If you want to use a newer version of a jar, declare a newer version as the dependency in your .pom file.
You should bind maven-assembly-plugin to the build life cycle like this:
<project>
[...]
<build>
[...]
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</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>
[...]
</project>
which will be execute the maven-assembly-plugin within the package life cylce phase.

Java not able to find dependencies while executing executable jar generated with maven-jar-pluin configured with exact classpath arguments

The following is the directory structure of my java application:
application.jar
dependency-jars
a.jar
b.jar
c.jar
The application executes fine when I use the following command: java -cp "application.jar;dependency-jars/*" com.my.Application. In addition to application dependencies, 'dependency-jars' folder will also have jars dropped by its consumers. I want to make it an executable jar so as to make it easy for its consumers to invoke it. For creating executable jar I am making use of maven jar plugin. I want to simulate the above command line. I used the following maven jar plugin configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>com.my.Application</mainClass>
<addClasspath>true</addClasspath>
</manifest>
<manifestEntries>
<Class-Path>dependency-jars/*</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
The generated jar when executed is not able to find its dependencies at run time. Is there anything wrong with the above.
Thanks.
You need to use the maven-assembly-plugin for this like:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>com.my.Application</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
and you run it with
mvn clean compile assembly:single
Compile goal should be added before assembly:single. Generally, this goal is tied to the build phase to execute automatically. This ensures the JAR is built when executing mvn install.
And this answer would not be complete without a mention of the maven-shade-plugin which can help you in case your dependency jars have conflicting package and class names.

Maven pom.xml change manifest mainclass

I'm working on a project where I have gotten a sample code that is build with Maven. In the pom.xml there is
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<manifest>
<mainClass>com.xxx.research.control.ControlClass</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Now I have written my own code and I am trying to reuse this pom since I'm new to maven. I have tried to change <mainClass>com.xxx.research.control.Main</mainClass> to <mainClass>project.Main</mainClass> because thats where my code is. In Eclipse I have it in the sam source folder but in a package "project".
When I do maven clean install with the original pom I can run the jar that it produces just fine but when I modify it to build my code I get Exception in thread "main" java.lang.NoClassDefFoundError: project/Main.
What am I missing here?
Thanks in advance.
By default maven looks under src/main/java folder for your source code, so you have to put your main class on src/main/java/project/Main.java
Have a read at the maven manual, it also has some folder structure for resources and unit tests that will be included into classpath:
src/main/resources
src/test/java
src/test/resources

Exporting multiple projects as jars

How do I export multiple projects as individual jar files each, so as to have a 1:1 ratio of project to jar? I have thousands of projects, and exporting each of them one by one would take way too long, and exporting them all as one jar is also not ideal, because I run them individually via the cron scheduler.
Edit - What I need, to be specific, is exactly what I get from running "Export -> Runnable JAR" in Eclipse, having "Package required libraries into generated JAR", except to do it in a faster way. Maven is apparently good for this, but I'm having trouble getting it to work like I want.
You can use Maven. Then you just have to run a command like mvn package in each project folders to generate the jar files. You can write a script to automate this process.
To get the maven to create a runable jar with all your dependencies try doing this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.whatever.YourMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.whatever.YourMainClass</mainClass>
</manifest>
</archive>
</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>
</plugins>
</build>

Categories

Resources