I've got a project I've made with Maven. I compile a JAR, with "mvn package", and now I want to run it, preferably without setting some insane classpath, as it depends on Spring and half the internet or something. Is there any way I can run it easily? Something like "mvn run" would be great, or an option to throw in all dependencies into the jar so I can do "java -jar" would also be splendid.
How do you deal with this, and what do you recommend doing? Because exporting a CLASSPATH based on ~/.m2 would probably just be hurtful ;-)
Setting CLASSPATH and calling java -jar myjar.jar wouldn't work anyway. Because the java -jar command ignores the CLASSPATH environment variable as well as the -cp flag.
In this case you had to add the classpath entries to the jar's MANIFEST at the Class-Path key, like:
Class-Path: jar1-name jar2-name directory-name/jar3-name
Use the Maven Assembly Plugin - it will automatically build your JAR with all included dependencies, and you can set the main class parameter to make the JAR executable.
The documentation can be confusing, so here is an example of what your POM will look like:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>package.of.my.MainClass</mainClass>
<packageName>package.of.my</packageName>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
And then you can run as:
mvn assembly:assembly
You will want to look into the Maven Assembly Plugin. And then once you have created the XML file required by the plugin and have modified your POM file to work with the plugin, you can run it with:
mvn assembly:assembly
This will create the JAR with all of its dependencies.
Related
I'm coding a maven project with eclipse 2018.09 under java 11 and I've a problem with the maven jar creation. When I clean package the project, it delivers me a jar but no dependencies are added into and i sometimes have warning in eclipse like:
classpath entry junit(for example) will not be exported it may result a ClassNotFoundException.
Which is in fact what's happening when i launch my jar project.
Thanks.
it delivers me a jar but no dependencies are added into [it]
it is totally normal. By default, when Maven builds a jar, it does not add any dependencies in it, but only the .class and resources of your current project.
When you run your programm you want it to find your dependencies otherwise you will face ClassNotFoundException. So you must configure your classpath to reference the dependencies.
1- if you want to run you programm from your local computer with Maven, use the exec Maven plugin with the <java> goal defined in your pom like explained here: https://www.mojohaus.org/exec-maven-plugin/usage.html#Java_goal
alternatively you can run it from a launcher in your IDE. The IDE will build the classpath for you and the classpath will corectly contain your dependencies.
2- if you want to run from the command line on any computer, you have to copy all of you dependencies in one directory (using Maven's dependency plugin mvn dependency:copy) and run you jar like this:
java -cp myProgram.jar:dependencyDirectory/* com.blabla.MainClass
(beware the use of ';' or ':' and '/' or '\' depending on Linux/Windows)
3- as an alternative you can run your jar with java -jar myprogram.jar but only if it contains a correct MANIFEST.MF where the location of all the dependencies are hardcoded.
My advice is to target solution 1 or 2 first.
PS: you can also create "fat jars" or "uber jars" containing your dependencies but I would advise you do not target this solution at first.
You can simply add this to your pom.xml (under the < plugins > tag):
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>App</mainClass>
</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>
Remember to change the mainclass to your entrypoint (which class the static void main(string[args]) is).
Now when you run the command mvn clean install there will be a jar in the targets folder with name yourproject-version-SNAPSHOT-jar-with-dependencies.jar
I am trying to create a .jar for my app. This app contains many things such as another .jar.
Using this plugin in my pom configuration :
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.rilent.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
And I have this link to a local jar
...
<dependency>
<groupId>it.sauronsoftware.jave</groupId>
<artifactId>jave</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/main/resources/jave-1.0.2.jar</systemPath>
</dependency>
I am using this command to build my app which returns BUILD SUCCESS :
mvn clean compile assembly:single
but when I try to execute my program, It crashes at some point returning this error :
Exception in thread "main" java.lang.NoClassDefFoundError: it/sauronsoftware/jave/InputFormatException
( a class from the .jar)
I tried decompressing my main jar to see its content :
what is wrong with the way I am creating my jar?
edit #Thorbjørn Ravn Andersen
I tried this way too, I added this to my pom :
<!-- https://mvnrepository.com/artifact/com.jolira/onejar-maven-plugin -->
<dependency>
<groupId>com.jolira</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.4</version>
</dependency>
then I m compiling with mvn compile and when I try to run the .jar I get this error
no main manifest attribute, in .\myapp-0.0.1-SNAPSHOT.jar
what am I doing wrong again ...?
Note : My jar also contains a .exe
The standard classloaders cannot load classes from jars inside jars. EXE files cannot be run from inside jars.
This does not mean that it is impossible, but a bit cumbersome and perhaps above your current skill level. You might find One Jar (http://one-jar.sourceforge.net/) interesting as it automates exactly this.
For a Maven project I have had good experience with creating a deployment structure and scripts with appassembler. http://www.mojohaus.org/appassembler/appassembler-maven-plugin/
I followed the example in Building a fat jar using maven and now I can run the following to build/test and install my jars.
mvn clean compile install
However, install now takes a lot longer because we are now building a fat jar. Is it possible to have two versions of install where one just builds jars without dependencies and the other does that and in addition builds the fat jar, like:
mvn clean compile install
mvn clean compile install-fatjar
I know install-fatjar is not a valid phase but just want to give an idea of what I'm trying to accomplish, i.e. a conditional install where the fat jar is built only when an option is provided.
Create a profile for the fat jar and configure the maven assembly plugin to create the fat jar in this profile.
For example use this profile:
<profiles>
<profile>
<id>fatjar</id>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Then you can build it by activating the profile
mvn -P fatjar clean install
where fatjar is the profile id.
Multiple profiles can also be activated
mvn -P fatjar,release install
Normally we don't use the fat-jar (or, uber-jar) as the main artifact.
You can make use of Assembly or Shade plugin to create a variation of the artifact (with a different classifier) which is a uber-jar.
It is strongly recommended that you still keep your "normal" artifact as is. If you want the uber-jar only occasionally, put the use of assembly/shade plugin for "uber-jar" creation in a profile, and activate the profile whenever you want. However, this should still generate you an "extra" uber-jar instead of making your main artifact a uber-jar.
I'm trying to build a maven java program on on Windows7 and my java -version is 1.7. I'm getting this error:
"Error: Could not find or load main class com.mycompany.App" when trying to execute Maven-generated Jar
even though com/mycompany/App.class exists within the Jar and it has a main method. Here is what my META-INF/MANIFEST.MF looks like:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: me
Build-Jdk: 1.7.0_03
Main-Class: com.mycompany.App
Class-Path: C:/Users/me/.m2/repository/com/mycompany/commons/2.1-SNAPSHOT/commons-2.1-SNAPSHOT.jar
I'm trying to execute the jar using:
java -jar mycompany-2.1-SNAPSHOT.jar 12:141678 1
There is a blank line at the end of my Manifest file. I'm using Maven 3.0.5 and using mvn package to generate the jar file. Here is a portion of my pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathLayoutType>repository</classpathLayoutType>
<classpathPrefix>${settings.localRepository}</classpathPrefix>
<mainClass>com.mycompany.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Can someone help me understand what is causing this error?
If you remove everything from manifest except the mainClass, it should work.
If you are trying to create an executable jar file that includes all of the classpath
dependencies, you probably want to use either the assembly plugin or the shade plugin
instead of the jar plugin.
assuming you have already checked that those files exist:
./mycompany-2.1-SNAPSHOT.jar
C:/Users/me/.m2/repository/com/mycompany/commons/2.1-SNAPSHOT/commons-2.1-SNAPSHOT.jar
Does the artifact contain com/mycompany/App.class ?
jar -tf mycompany-2.1-SNAPSHOT.jar
Running java with the option -verbose:class can show how the classpath is resolved to load (or not) each class.
Note
You might have a warning at build time because no version is specified for the plugin:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
...
I am developing a Java maven project with Eclipse and want to export a jar that includes all referenced libraries. These referenced libraries fall into one of these two categories:
They are explicit (or implicit) dependencies in the pom.xml
I have some libraries not available as maven artifacts and have put them in /lib (and added them to the build path in Eclipse)
There's the maven-assembly-plugin, which works fine for 1). However, I'm unable to find a maven plugin that also includes non-maven-dependencies, e.g. "all jars in /lib".
Then there's the Eclipse FatJar plugin, which sort of works, but hasn't been updated since 2009, so it seems unmaintained. Also I prefer an export method that I can directly specify in the pom.xml.
Can anyone point me to a maven plugin or the like to export all referenced libraries, including those from case 2) ? That only needs to involve putting them in the jar and referencing them in the manifest's classpath.
Thanks!
I think the best way to handle this is to include your custom libs into a local maven repository. Now you can inlcude your libraries as maven dependencies and you can export all your dependencies specified in your pom with the maven-assembly-plugin.
Here is a tutorial, how to put your libs into a local repository in maven to use it in your pom. http://www.mkyong.com/maven/how-to-include-library-manully-into-maven-local-repository/
And in your pom.xml:
<!-- setup jar manifest to executable with dependencies -->
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>your.main.class</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
This looks like a task for Tycho. It is a set of maven plugins that allows to create eclipse plugins with maven. Tycho considers manifest entries as build dependencies.
However I'm not aware of how to package all those dependencies in a single jar. This may also be conflicting with the osgi spec. But if you wish to ignore osgi you could just try the jar-with-dependencies assembly.