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
Related
I am trying to create a jar, that contains some test classes and a main class that runs those test classes using custom junit runner. I have used maven assembly plugin. The jar is getting created but when I try to run the jar using
java -jar <nameofthejar>
it gives error saying:
Error: Could not find or load main class com.ora.arb.tap.Main
Here is my project structure:
src:
- main:
- java:
- resources:
- test:
- java:
- tap:
- Main
- TestClass1
- TestClass2
- resources:
assembly plugin from pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.ora.arb.tap.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>attached</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/tap</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Whats the issue and how can I fix it?
I was facing Same issue,
please check if you have added packaging jar at top your pom.xml inside tag.
like this:
<project>
<groupId>com.rohan</groupId>
<artifactId>jmetertester</artifactId>
**<packaging>jar</packaging>**
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.
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>
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.
I have a maven project I created with spring roo. When I run mvn assembly:single I get a fat jar with all the dependencies, but not the actual code I wrote. Here is my maven-assembly-plugin configuration from my pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>net.justaprogrammer.poi.cleanser.Cleanser</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
What am I doing wrong?
The solution is to add the single goal to the package phase of the project life cycle. This means you have to add the following xml under the configuration section:
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
I will say what you have done are totally enough. Instead of assembly:single, do:
mvn clean compile assembly:single
And you should be good to go.
Well, jar-with-dependencies does exactly what you describe is happening. Why don't you just use mvn package?