Maven won't create runnable jars - java

My pom.xml looks like this
...
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<archive>
<manifest>
<mainClass>application.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
...
but although I specified the main class, on clean package install maven only creates jars that aren't runnable.
How can I fix that? The manifest then looks like this:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: Matthias
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_121

Instead of maven compiler plugin, you should configure the maven jar plugin to create an executable jar :
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>application.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
To declare the source/target java version you could use :
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
instead of declaring the compiler plugin.
This is less verbose and it produces exactly the same result.
Besides, if you want to include dependency jars of your application inside your executable jar, you should favor the maven assembly plugin over the maven jar plugin :
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>application.Main</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>

Related

Error build maven multi-module - jar file

Currently I have a multi module project with maven, in the super pom I have added the modules of the projects. From the SparkAppBuilder module I intend to build the jar project that contains the SparkDriver and SparkProcess projects.
To do this from the SparkAPPBuilder module, add the maven-assembly-plugin plugin, I see that it builds the project by adding my 2 modules, but the problem is that it is generating the jar with all the dependencies that are in my local repository, so the jar weighs more than 150MB.
This is my SparkAppBuilderPOM:
<profile>
<id>dev</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.streaming.example.DirectStreaming</mainClass>
</manifest>
</archive>
<finalName>JavaStreamingDirect</finalName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.streaming.example.DirectStreaming</mainClass>
</manifest>
</archive>
<finalName>JavaStreamingDirect</finalName>
</configuration>
</plugin>
</plugins>
</build>
</profile>
...
<dependencies>
<dependency>
<groupId>com.spark.driver</groupId>
<artifactId>SparkDriver</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.spark.streaming</groupId>
<artifactId>SparkProcess</artifactId>
<version>0.0.2-SNAPSHOT</version>
</dependency>
</dependencies>
Do you know why you add my entire local repository in the assmbly phase?
Thanks so much.
Regards
A jar-with-dependencies also contains all transitive dependencies. Those are usually needed to run the project because they are the dependencies of your dependencies.
So it is not unusual that this jar is large. You should look in your mvn dependency:tree where most of the stuff comes from -- then you might be able to reduce the amount by changing the dependencies of your modules.
So: The jar-with-dependencies does not contain the whole local repository, just the whole dependency tree.

Run Java Maven project with Linux command line

I have a Java project that prints "Hello world !". It runs well under Eclipse/Windows and on a Linux server with the command:
java MyClass.java; javac MyClass
Now that I have converted the project to a Maven project it's still running fine in Eclipse, but I can't find how to run it with a Linux command. I tried many answers that I found on forums but none work for me.
Here is an example of what I tested:
mvn package install;
cd target;
java -cp myApp-0.0.1-SNAPSHOT.jar mypackage.Mylass;
This results to an error:
Error: Could not find or load main class mypackage.Mylass
So, how can I run the Maven code on Linux without generating a jar file or at least make it work with a command line?
i finally managed to make it work thanks to all the answers.
here is what i did
i moved my Main class to the outside of packages and deleted/regenerated a new POM file with
<manifest>
<mainClass>Myclass</mainClass>
</manifest>
but i got some dependency errors so i generated a jar file with the dependency by adding maven plugin jar-with-dependencies
so here is what the build part of my POM file looks like now
....
</dependencyManagement>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>MyClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>MyClass</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>
and here is how i execute it .
rm -rf target/ #delete old generated files
mvn install package # generate new jar files
java -jar target/App-0.0.1-SNAPSHOT-jar-with-dependencies.jar # execution
i hope this can save someone else's time
thanks for your help
You've specify a main class in the manifest of myApp-0.0.1-SNAPSHOT.jar
Add the next snippet of code to your pom file.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>mypackage.Mylass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
This's the complete pom.file
http://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
com.mycompany.app
my-app
jar
1.0-SNAPSHOT
my-app
http://maven.apache.org
junit
junit
3.8.1
test
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.mycompany.app.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Can you confirm the class name you can trying to run ?
As per your comment, originally ran the class using below command.
java MyClass.java; javac MyClass - here the class name is MyClass
After maven install, it should be invoked using
mvn package install;
cd target;
java -cp myApp-0.0.1-SNAPSHOT.jar mypackage.MyClass;

.jar with Maven and Eclipse

I have a java project done with Eclipse and Maven with this estructure folder:
enter image description here
Ok, when i make a Maven install to create the .jar take this structure folder:
enter image description here
So that the hierarchy is not the same and links to the images and css do not work.
I show you the code of pom.xml
enter code here
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
com.wepall
palle
0.4.0
com.thoughtworks.xstream
xstream
com.thoughtworks.xstream
xstream
1.4.9
palle
<!-- download source code in Eclipse, best practice -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<downloadSources>true</downloadSources>
<downloadJavadocs>false</downloadJavadocs>
</configuration>
</plugin>
<!-- Set a compiler level -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
<!-- Maven Assembly Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<!-- get all project dependencies -->
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- MainClass in mainfest make a executable jar -->
<archive>
<manifest>
<mainClass>com.wepall.palle.MainApp</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- bind to the packaging phase -->
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Any ideas?
thanks a lot!!
Best regards
You should add a build section to your pom.xml:
<build>
<directory>${basedir}/target</directory>
<resources>
<resource>
<targetPath>${basedir}/target/resources</targetPath>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
Further Reference:
POM Reference (Build Section)
I think that you should create a war instead of a jar, because you are talking about css and images and jars should not contains that kind of files (see jar vs war).
In maven you only need to change the <packaging> of the project inside the POM.

Maven ignored maven archiver

I'm using maven-jar-plugin in pom.xml.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<!-- DO NOT include log4j.properties file in your Jar -->
<archive>
<manifest>
<!-- Jar file entry point -->
<addClasspath>true</addClasspath>
<mainClass>com.example.Manager</mainClass>
<classpathPrefix>dependency-jar/</classpathPrefix>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
I can see in logs that maven execute it:
[INFO] [jar:jar {execution: default-jar}]
[INFO] Building jar: example.jar
[INFO] [jar:jar {execution: jar}]
but it don't put main class to MANIFEST.MF:
Manifest-Version: 1.0
Built-By: romkazanova
Build-Jdk: 1.7.0_65
Created-By: Apache Maven
Archiver-Version: Plexus Archiver
i don't understand why. I work with Idea.
You have to define the configuration in a pluginManagement area cause the maven-jar-plugin is already bound to the build life-cycle
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.Manager</mainClass>
<classpathPrefix>dependency-jar/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
The problem you have is that the execution you have defined means to have a supplemental execution as the log output shows and not change the configuration of the existing execution within the life cycle.
Furthermore you seemed to be running on Maven 2 instead of Maven 3 and you should update as soon as possible because Maven 2 has been defined EoL
You can of course add the version of maven-jar-plugin.
Try to compile manually by prompt: mvn compile
or try: mvn clean install -Dmaven.test.skip=true
What IDE are you using?
#khmarbaise is wrong in his definition of PluginManagement. According to the definition in Maven documentation, PluginManagement is intended to configure project builds that inherit from this one. In your pom.xml you have no needs to keep the PluginManagement node.
You only have to change the location of your configuration node from execution level to plugin level. You can see that #khmarbaise did that too.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<!-- DO NOT include log4j.properties file in your Jar -->
<archive>
<manifest>
<!-- Jar file entry point -->
<addClasspath>true</addClasspath>
<mainClass>com.example.Manager</mainClass>
<classpathPrefix>dependency-jar/</classpathPrefix>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Furthermore you don't have to keep the executions node anymore because maven-jar-plugin is already bound to the build life-cycle as #khmarbaise mentioned it.

Add subversion revision to war manifest using maven2

I want to find a maven native (i.e. without calling external programs) to inject the svn revision in the war manifest.
Does anybody know a way to do that?
I found mention to how to add the subversion revision to manifests in jar files but not with war files.
I searched SO but could not find this issue specifically.
I want to find a maven native (i.e. without calling external programs) to inject the svn revision in the war manifest.
This is possible with the Build Number Maven Plugin using the svnjava provider:
If you need to execute the plugin on
machine without any svn in the path
you can configure the mojo to use the
svnjava provider.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.0-beta-3</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
</execution>
</executions>
<configuration>
<doCheck>true</doCheck>
<doUpdate>true</doUpdate>
<providerImplementations>
<svn>javasvn</svn>
</providerImplementations>
</configuration>
</plugin>
</plugins>
</build>
The Build Number Maven Plugin sets the build number in the ${buildNumber} property that you can then use in your POM.
I found mention to how to add the subversion revision to manifests in jar files but not with war files.
Then, to add the build number in the MANIFEST of a war, configure the plugin as mentioned in the Usage page:
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Try this. About halfway down, look for maven-war-plugin
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Implementation-Build>${buildNumber}</Implementation-Build>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>

Categories