I am trying to generate an executable jar for a small home project called "logmanager" using maven, just like this:
How can I create an executable JAR with dependencies using Maven?
I added the snippet shown there to the pom.xml, and ran mvn assembly:assembly. It generates two jar files in logmanager/target: logmanager-0.1.0.jar, and logmanager-0.1.0-jar-with-dependencies.jar. I get an error when I double-click on the first jar:
Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.
A slightly different error when I double-click the jar-with-dependencies.jar:
Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar
I copied and pasted the path and classname, and checked the spelling in the POM. My main class launches fine from an eclipse launch configuration. Can someone help me figure out why my jar file won't run? Also, why are there two jars to begin with? Let me know if you need more information.
Here is the full pom.xml
, for reference:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gorkwobble</groupId>
<artifactId>logmanager</artifactId>
<name>LogManager</name>
<version>0.1.0</version>
<description>Systematically renames specified log files on a scheduled basis. Designed to help manage MUSHClient logging and prevent long, continuous log files.</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<!-- nothing here -->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!-- commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<!-- Quartz scheduler -->
<dependency>
<groupId>opensymphony</groupId>
<artifactId>quartz</artifactId>
<version>1.6.3</version>
</dependency>
<!-- Quartz 1.6.0 depends on commons collections -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<!-- Quartz 1.6.0 depends on commons logging -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1</version>
</dependency>
<!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
<scope>runtime</scope>
</dependency>
<!-- junitx test assertions -->
<dependency>
<groupId>junit-addons</groupId>
<artifactId>junit-addons</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
<!-- junit dependency; FIXME: make this a separate POM -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.1</version>
</dependency>
</dependencies>
<dependencyManagement>
</dependencyManagement>
</project>
Actually, I think that the answer given in the question you mentioned is just wrong (UPDATE - 20101106: someone fixed it, this answer refers to the version preceding the edit) and this explains, at least partially, why you run into troubles.
It generates two jar files in logmanager/target: logmanager-0.1.0.jar, and logmanager-0.1.0-jar-with-dependencies.jar.
The first one is the JAR of the logmanager module generated during the package
phase by jar:jar
(because the module has a packaging of type jar
). The second one is the assembly generated by assembly:assembly
and should contain the classes from the current module and its dependencies (if you used the descriptor jar-with-dependencies
).
I get an error when I double-click on the first jar: Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.
If you applied the suggested configuration of the link posted as reference, you configured the jar plugin to produce an executable artifact, something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
So logmanager-0.1.0.jar
is indeed executable but 1. this is not what you want (because it doesn't have all dependencies) and 2. it doesn't contain com.gorkwobble.logmanager.LogManager
(this is what the error is saying, check the content of the jar).
A slightly different error when I double-click the jar-with-dependencies.jar: Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar
Again, if you configured the assembly plugin as suggested, you have something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
With this setup, logmanager-0.1.0-jar-with-dependencies.jar
contains the classes from the current module and its dependencies but, according to the error, its META-INF/MANIFEST.MF
doesn't contain a Main-Class
entry (its likely not the same MANIFEST.MF as in logmanager-0.1.0.jar). The jar is actually not executable, which again is not what you want.
So, my suggestion would be to remove the configuration
element from the maven-jar-plugin and to configure the maven-assembly-plugin like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<!-- nothing here -->
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>org.sample.App</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Of course, replace org.sample.App
with the class you want to have executed. Little bonus, I've bound assembly:single
to the package
phase so you don't have to run assembly:assembly
anymore. Just run mvn install
and the assembly will be produced during the standard build.
So, please update your pom.xml with the configuration given above and run mvn clean install
. Then, cd into the target
directory and try again:
java -jar logmanager-0.1.0-jar-with-dependencies.jar
If you get an error, please update your question with it and post the content of the META-INF/MANIFEST.MF
file and the relevant part of your pom.xml
(the plugins configuration parts). Also please post the result of:
java -cp logmanager-0.1.0-jar-with-dependencies.jar com.gorkwobble.logmanager.LogManager
to demonstrate it's working fine on the command line (regardless of what eclipse is saying).
EDIT: For Java 6, you need to configure the maven-compiler-plugin. Add this to your pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
The answer of Pascal Thivent helped me out, too. But if you manage your plugins within the <pluginManagement>
element, you have to define the assembly again outside of the plugin management, or else the dependencies are not packed in the jar if you run mvn install
.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<mainClass>main.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>
</plugins>
</pluginManagement>
<plugins> <!-- did NOT work without this -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<!-- dependencies commented out to shorten example -->
</dependencies>
</project>
If you don't want execute assembly goal on package, you can use next command:
mvn package assembly:single
Here package is keyword.
Right click the project and give maven build,maven clean,maven generate resource and maven install.The jar file will automatically generate.
Success story sharing