I have a java project that sends email built with maven (using Eclipse) and it works within Eclipse with no problem, but when trying to package a runnable jar, I am having an issue
Error: Unable to initialize main class com.my.package.MyClass
Caused by: java.lang.NoClassDefFoundError: javax/mail/MessagingException
I have this for my dependency:
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
</dependency>
and plugins set up like so:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mypackage.MyClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.mypackage.MyClass</mainClass>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
I can see javax.mail-1.6.2.jar in my maven dependencies, so not sure why I am unable to run the jar...is there a config option I missed?
thanks!
I searched around and tried numerous variations of the shade and jar plugins, I expected to be able to run the jar off the command line using java -jar myjar.jar. Most of the posts I found in my search recommended adding the mail jar to the classpath, but that looks like it's already done, as the jar is in the list of maven dependencies.
Update
Have tried multiple variations, as per suggestions below. Tried the maven-assembly-plugin making sure to add the <mainClass>com.etcetera.MyClass</mainClass> tag. With those variations I got no main manifest attribute, in myjar.jar. I then added in the maven-jar-plugin plugin, also adding the main class and I'm now back to the original error.
Update2
when I open up the archive, I see this:
Manifest-Version: 1.0
Created-By: Apache Maven 3.8.4
Built-By: myUserName
Build-Jdk: 15
which appears to be missing the Main-Class: com.javabyexamples.java.jar.HelloWorld line
Resolution
I resolved the issue by building the project twice in Eclipse: clean package and then clean compile assembly:single
When building a web app, dependencies are, of course, bundled in the .WAR/.EAR.
However, by default, Maven will not bundle dependencies inside your .jar file. (In other words, jars will not be put inside of other jars).
Nevertheless, you can use the jar-with-dependencies descriptor. More details can be found on the questions below:
Including dependencies in a jar with Maven
How can I create an executable/runnable JAR with dependencies using Maven?
Alternatively, you could add the mail-1.6.2.jar on the Java classpath like so:
java -jar "myjar.jar" -cp "./path/to/mail-1.6.2.jar:./path/to/other.jar"
It is not necessary to create an executable JAR. You can package a regular jar, allow Maven to generate the MANIFEST.MF, making sure to add the regular JAR to the Java classpath, and specify the class with the main function on the command line:
java -cp "./path/to/mail-1.6.2.jar:./path/to/other.jar:/path/to/myjar.jar" "com.mypackage.MyClass" "param1 param2 etc"
Please note that classpath separators are different on Linux (colon) vs Windows (semi-colon)
Related
I've spent the last 3 hours trying to get my Java program to interface with my Postgres server. I cannot get past the error message "No suitable driver found for jdbc:postgresql://localhost:5432/gis". It is a Bukkit plugin, and I am using IntelliJ IDEA.
The code:
try
{
//Class.forName("org.postgresql.Driver");
c = DriverManager.getConnection("jdbc:postgresql://localhost:5432/gis");
}
catch(Exception e)
{
getLogger().info(e.getMessage());
}
Things I have tried:
java -cp ./path/to/postgresjdbc.jar -jar spigot-1.15.2.jar
adding the jdbc file internals directly to my jar file
adding the jdbc file as a dependency within the IntelliJ project
switching to maven, and putting the following in pom.xml:
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.1</version>
</dependency>
</dependencies>
I am unable to get past the error I posted. At this point, it has taken over my entire evening.
I've stumbled with this issue several times when developing Bukkit/Spigot plugins that make use of MySQL databases. The process for Postgres should be the same.
Usually, this error happens when your plugin can't find the PostgresqlJDBC driver. You have two workarounds:
Option 1. Adding the .jar to the plugin's classpath:
It's recommended that you set the libraries inside plugins/lib as then your server won't try to load the libraries as a Bukkit plugin. Add the prefix lib/ to your classpath by adding this configuration in your pom.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath> <-- don't know if this is needed -->
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
Then make sure to put your postgresjdbc.jar inside a folder called lib inside your plugin's folder.
Option 2. Add dependencies directly in your jar:
Note that this option will increase your plugin's jar size.
This can be done via Maven's assembly plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>your.main.class</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
If you open your plugin's jar with a file compressor like 7-zip you should there should the driver's classes in it apart from your plugin ones.
Let me know if this solved your issue.
I have a Maven project that depends on spring-boot and all the Vaadin required dependencies. The structure of the project is:
src/
main/
java/ (all java files here)
resources/ (all properties/yml files here for Spring)
webapp/VAADIN/themes/myapp/ (all webapp stuff here, including HTML templates)
I use embedded tomcat to host the application.
I create a fat jar using maven-jar-plugin, and deploy this to an external server. I thought I would need webapp and compiled classes folder on the classpath too, so I do the following to start the application:
java -Dspring.profiles.active=prod -classpath "classes;webapp" -jar app.jar
Now the application does start up. However it seems that the compiled stuff doesn't get picked up. E.g. in the log file I see:
CustomLayout not found: layouts/login.html
And the resulting login webpage has the text (without theme):
Layout file layouts/login.html is missing. Components will be drawn for debug purposes.
NB I've tried to do this without the maven jar plugin too, but still hit the same issue
I get the distinct feeling I'm just going this wrong. I think I should be packaging the VAADIN compilation into the jar (how to do this?).
Additional Info
Maven plugins (for running from IDE and packaging fat jar):
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>8.0.5</version>
<executions>
<execution>
<goals>
<goal>clean</goal>
<goal>resources</goal>
<goal>update-theme</goal>
<goal>update-widgetset</goal>
<goal>compile-theme</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<mainClass>my.domain.MyApp</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Other dependencies:
spring-boot-starter-parent
spring-boot-starter
vaadin-spring-boot-starter
vaadin-themes
other internal deps
When I create a jar file I want to fit inside my dependencies. For that, I use maven-assembly-plugin such as follows:
<build>
...
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<finalName>${project.artifactId}-GUI</finalName>
<archive>
<manifest>
<mainClass>gui.MyMainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<!-- <appendAssemblyId>false</appendAssemblyId>-->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
This code works OK and it does what it's expected to do. However, this creates a new jar called myjar-GUI-jar-with-dependencies.jar. I would like to eliminate that "jar-with-dependencies" ending. Does anybody knows how to do that?
I have used that commented line you can see on my code, but that produces the following warning that I don't know how to solve it:
[WARNING] Configuration options: 'appendAssemblyId' is set to false, and 'classifier' is missing.
Instead of attaching the assembly file: [myJar-GUI].jar, it will become the file for main project artifact.
NOTE: If multiple descriptors or descriptor-formats are provided for this project, the value of this file will be non-deterministic!
[WARNING] Replacing pre-existing project main-artifact file: [myJar].jar with assembly file: [myJar-GUI].jar
EDITED
After the solution the user Tunaki suggested, I used a different pluggin and maven works as I want it to do it. The code is as follows:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>gui.SparkISGUI</mainClass>
</transformer>
</transformers>
</configuration>
</plugin>
First, you need to understand why you are getting this warning.
The Maven convention is that one project should create a single main artifact. For a project of packaging jar, the main artifact is the result of the maven-jar-plugin. This plugin will package as a JAR the classes contained in your project only.
One project can eventually generate additional artifacts that will be distinguished from the main one by their classifier:
Beside the main artifact there can be additional files which are attached to the Maven project. Such attached filed can be recognized and accessed by their classifier.
The classifier is an identifier than will be appended to the main artifact name.
So what happens when you want to create an uber-jar? Somehow, your project needs to generate two jars. The main one will be a JAR containing the classes of your project and the second one will be the uber-jar resulting of maven-assembly-plugin. To distinguish this secondary additional artifact from the main one, the classifier jar-with-dependencies is added.
So when you remove the classifier, you effectively replace the main artifact with the uber-jar. maven-assembly-plugin will emit a warning in this case, and that's the warning you are having. You can ignore it completely: it just reminds you that you are replacing the main artifact of the project by an additional artifact.
Besides the maven-assembly-plugin, do note that you can also generate an uber-jar with the maven-shade-plugin:
This plugin provides the capability to package the artifact in an uber-jar, including its dependencies and to shade - i.e. rename - the packages of some of the dependencies.
It actually took me a long while to notice. When I run the project in netbeans, it works just as expected. But when I do the Build I get PROJECTNAME-1.0-SNAPSHOT.jar file that doesn't do anything. When unpacked, it looks like this:
This is suspicious, before Maven, my compiled file looked like this:
Shouldn't the Main class be in the jar file root? How does JVM know which main class to run?
There's something disturbing about the MANIFEST.MF too:
Old manifest
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.1
Created-By: 1.7.0_45-b18 (Oracle Corporation)
Class-Path: lib/alloy.jar lib/jna-platform.jar lib/jna.jar
X-COMMENT: Main-Class will be added automatically by build
Main-Class: Main
New manifest
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Jakub
Build-Jdk: 1.8.0_31
Seems like Main-Class entry is missing...
Use maven-jar-plugin for make your jar executable. For me actual code below:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>my.main.class</mainClass>
</manifest>
</archive>
<outputDirectory>${project.build.directory}/result</outputDirectory>
</configuration>
</plugin>
Alse usefull exec-maven-plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<mainClass>my.main.class</mainClass>
<!--
<commandlineArgs>-d 5409 -c 467 -t 2 -dlg true</commandlineArgs>
-->
</configuration>
</plugin>
Sadly many IDE's provide a simple mechanism for packaging all of your library jars into your main build jar. This is both frowned-upon and potentially hazardous to your deployable - you should really deploy all of the used libraries separately and use your class-path to join them all up.
As Maven attempts to make doing it right the easiest way it is designed to by default build your jar to contain just your code and no more. If you can stick with this solution then it may be worth your while doing so.
However, sometimes it is necessary to make this happen, perhaps to duplicate existing build results while switching to Maven or maybe deployment is enough of a nightmare without having to deploy dozens of libraraies too. To achieve this you can build what the Maven community call an Uber-Jar using the Maven Shade plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<!-- Make sure jaxb is included. -->
<artifact>com.sun.xml.bind:jaxb-impl</artifact>
<includes>
<include>*.*</include>
</includes>
</filter>
<filter>
<!-- Make sure jtds is included. -->
<artifact>net.sourceforge.jtds:jtds</artifact>
<includes>
<include>**</include>
</includes>
</filter>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/*.sf</exclude>
<exclude>META-INF/*.dsa</exclude>
<exclude>META-INF/*.rsa</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
Note that building uber-jars is generally not the best approach - there are many discussions about this online. Also there are many relational problems with the maven-shade-plugin itself as it interferes with Maven's mechanism for determining dependencies.
That said - if you must do it then the shade plugin is your guy.
NB: Just because this excludes licences does not mean this is a good idea - this is there to avoid duplicate file name issues in the uber jar.
See this interesting blog by MKYong about the pros and cons of using assembly/shade/one-jar.
I need some help trying to run the following maven project using the command line:
https://github.com/sarxos/webcam-capture, the webcam-capture-qrcode example is the one I'm trying to run. I have it running using an the Eciplse IDE but need to move it over to just using the command line. I have the jar's created by maven.
I'm trying
java -classpath ./webcam-capture/target/webcam-capture-0.3.10-SNAPSHOT.jar com.github.sarxos.webcam.WebcamQRCodeExample
but I keep getting the
Exception in thread "main" java.lang.NoClassDefFoundError: com/github/sarxos/webcam/WebcamQRCodeExample
Caused by: java.lang.ClassNotFoundException: com.github.sarxos.webcam.WebcamQRCodeExample
Just use the exec-maven-plugin.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>com.example.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Then you run you program:
mvn exec:java
1st Step: Add this content in pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
2nd Step : Execute this command line by line.
cd /go/to/myApp
mvn clean
mvn compile
mvn package
java -cp target/myApp-0.0.1-SNAPSHOT.jar go.to.myApp.select.file.to.execute
Use this command.
mvn package
to make the package jar file. Then, run this command.
java -cp target/artifactId-version-SNAPSHOT.jar package.Java-Main-File-Name
after mvn package command. Target folder with classes, test classes, jar file and other resources folder and files will be created.
type your own artifactId, version and package and java main file.
I am not sure in your case. But as I know to run any jar file from cmd we can use following command:
Go up to the directory where your jar file is saved:
java -jar <jarfilename>.jar
But you can check following links. I hope it'll help you:
Run Netbeans maven project from command-line?
http://www.sonatype.com/books/mvnref-book/reference/running-sect-options.html