Building executable jar with maven?
Solution 1
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>
Solution 2
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>
Solution 3
If you don't want execute assembly goal on package, you can use next command:
mvn package assembly:single
Here package is keyword.
RMorrisey
Updated on September 14, 2020Comments
-
RMorrisey over 3 years
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>
-
RMorrisey over 14 yearsThanks for your comments! I changed my pom.xml as you specified. When I run mvn clean install, I get a bunch of compilation errors from my code, saying that annotations and so on are not supported in -source 1.3. I am using jdk1.6 and it compiles in eclipse; I'm not sure how the 1.3 got introduced. Maybe one of the library versions in the pom snippet is an older one?
-
RMorrisey over 14 yearsThanks! I got past the 1.3 issue. I also had to add the junit4 dependency to my POM. I'm working on troubleshooting other stuff; if I get stuck I'll post again! If I get the jar running I'll mark this as answer. My current POM is updated in the question above.
-
Admin over 13 yearsIs there any way to exclude the resources from the generated jar file?
-
Devanshu Mevada over 13 years@HaiMinhNguyen Which jar? The default one or the one generated by the assembly plugin? In both cases, it's possible but not exactly the same way.
-
Admin over 13 yearsThe one generated by the assembly plugin. I've found a way thanks to your answer here stackoverflow.com/questions/2737601/…. Thanks.
-
Admin over 13 years@Pascal Thivent: Sorry I think I'm wrong. I've asked a question about my problem (stackoverflow.com/questions/4113697/…). Could you please help me? Thank you very much.
-
Funky coder over 12 yearsNice answer, but I have a small problem with my assembly. When I switch
appendAssemblyId
to false, I have my classes doubled in my outpu jar file! Any idea how to fix this? I assume that assembly plugin would normally create a new jar file with "-jar-with-dependencies" suffix, but since I switched it off it appends dependencies together with project files in the existing jar (created with jar:jar) -
saravana_pc almost 12 years@Pascal, as per the above approach, the dependent jars are in exploded format inside my jar. Is it possible to retain the dependencies as jars (within my jar) ?
-
Adam Parkin over 11 yearsIf I could give more than one upvote on this I so would. Thank you so much as the other answer simply did not work for me.
-
Daniil Shevelev over 10 yearsIs it possible to have resulting jar to have a "normal" name?
-
Daniil Shevelev over 10 yearsTo answer my own comment: using "shade" plugin with "transformers" property works for changing the name of the produced jar.
-
Admin about 9 yearsI also found this Sonatype blog post useful
-
shashaDenovo almost 9 yearsThanks Mike, It helped me. Initially my package was getting generated without using <pluginManagement>. But Eclipse was giving some error in pom.xml "maven - Plugin execution not covered by lifecycle". Which distract me. So to solve this i added <pluginManagement>, now the eclipse error gone but my package stopped being build. Your above snippet of pom has worked for me. :)
-
ininprsr almost 9 yearsThis was useful.. while using <pluginManagement>, the top answer won't work.