Missing JAR with Maven AddJar Plugin - java

When i run my jar file an it comes during runtime to access a class from a dependency (which is included by the maven-addjars-plugin), i get a java.lang.NoClassDefFoundError error.
Note: i also include some jars normaly by just specifying the dependency in the POM.xml, i only use the addjar plugin for the custom jars which i only have locally.
Part of POM.XML (If you need more information, pls tell)
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${project.artifactId}-${project.version}</finalName>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>Swapper</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>com.googlecode.addjars-maven-plugin</groupId>
<artifactId>addjars-maven-plugin</artifactId>
<version>1.0.5</version>
<executions>
<execution>
<goals>
<goal>add-jars</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${basedir}/my-repo</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
....
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-codegen</artifactId>
<version>2.1.4-SNAPSHOT</version>
</dependency>
The swagger lib was copied into "target/com.googlecode.addjars-maven-plugin" folder which idk is the right place to have those libs since i dont see the libraries that are downloaded from maven repository. But the class is not found during runtime.
UPDATE:
When running with mvn exec instead of java -jar the program runs.
Anyone has an idea what i did wrong?

Related

Maven deploy:deploy-file publishes all files instead of one

I am building my Java application using Maven and the Maven Assembly Plugin to create an executable jar.
As a result, the target folder contains multiple jars and other files. However, I only want to deploy the executable jar file built via the Assembly Plugin.
To do this, I have tried to use mvn deploy:deploy-file and provided it with the following properties:
file
repositoryId
url
artifactId
groupId
version
However, when I execute the command, Maven deploys all files instead of only the executable jar.
I also tried disabling the default build step:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<!-- disable standard deploy -->
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
The build part of my pom.xml looks like this:
<build>
<!--suppress UnresolvedMavenProperty -->
<finalName>${project.artifactId}-${BUILD_DATE}</finalName>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>src</directory>
<filtering>true</filtering>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>main.PAtrackMain</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<!--suppress UnresolvedMavenProperty -->
<Implementation-Build>${BUILD_DATE}</Implementation-Build>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>true</appendAssemblyId>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<!-- disable standard deploy -->
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
How can I deploy only the executable jar without the other files?
That is much simpler than you might think.
There are two kinds of artifacts, produced by maven project:
main: ${artifactId}-${version}.${packaging} - this one you would like to not publish
supplemental: everything else produced by plugins (javadoc, sources, assembly, etc)
If project/module packaging is pom, that means following:
project/module may not have main artifact, only supplemental ones
some plugins are not enabled by default (https://maven.apache.org/ref/3.8.6/maven-core/default-bindings.html - compare default bindings for pom and jar packaging)
Thus, all what you need is:
switch module packaging from jar to pom
enable missing plugins: maven-compiler-plugin, maven-resources-plugin, maven-jar-plugin, etc
extra configuration of maven-deploy-plugin is not required

Use Maven Jar plugin and Spring boot maven plugin simultaneously

I am trying to create jar for my spring boot server using spring boot maven plugin and my test automation framework jar from same project and pom file. To read external resources I am trying to defined manifest entries in maven jar plugin but this is causing spring server to not find application.properties in its default locations when run as a linux service using /etc/init.d/my-jar start.
Here is snippet of my pom file
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.3</version>
<configuration>
<descriptors>
<descriptor>src/assembly/dep.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>com.myorg.mainclass</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<finalName>${project.artifactId}-${project.version}-main-only</finalName>
<archive>
<manifest>
<mainClass>com.myorg.mainclass</mainClass>
</manifest>
<manifestEntries>
<Class-Path>./config/</Class-Path>
</manifestEntries>
</archive>
<excludes>
<exclude>**/application-test.properties</exclude>
</excludes>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
I have tried changing phase of my maven assembly and jar plugin to verify but the problem still persists. Removing manifest entry seems to work but then my external resource files are not read.
To solve the problem I removed the manifest entries from maven jar plugin and then while running the test jar. I added the external resource directory path into classpath as follows:
java -classpath my/external/resource/directory/path -jar my-tests.jar

Building an executable jar with maven depencies and external jars

I have an application where Im using maven dependecies and Im also using an external jar of a project which is located in my computer, the project is added to the application manually. The problem is whenever I export the project with maven, It only exports all maven dependencies, not the externatl jar that I have included manually. Is there anyway that I can export it?
Here is my pom.xml:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/libs
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
com.cristianruizblog.loginSecurity.LoginSecurityTutorialApplication
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Thanks for reading. If anyone can help I would be so happy!
As stated by #M. Deunum, try to get your external jar into a Maven repository to avoid enable any machine to build your jar. If this is no option, you can use the Maven system dependency scope to include the jar. Note that this is only a temporary solution as this scope has been marked as depricated.

Maven add dependencies to project

In eclipse you can easily add dependencies (i.e. a JAR file) to you're project.
Right click on the project and click -> Build Path-> add libraries.
Now a hidden file is createn inside the project, ".classpath".
Inside this file is a classpathEntry added so now I can use the libraries by adding it in a java file:
import foo.bar.*;
This "application" can now be exported to a single jar.
How can I achieve this with Maven and without eclipse?
I switched to emacs... :)
With the command:
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-cli -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
I get myself a sample start application.
inside a src folder is a App.java file writing "hello World" on a commandline.
with the following in the pom.xml I obtain myself a jar inside my project(maven indedependent deployment) successfully:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.mycompany.third-party</groupId>
<artifactId>commons-cli-archetype</artifactId>
<version>1.0-SNAPSHOT</version>
<type>jar</type>
<overWrite>false</overWrite>
<!--${project.basedir} ${project.build.directory} -->
<outputDirectory>${project.basedir}/resources/repo</outputDirectory>
<destFileName>optional-new-name.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.basedir}/resources/repo</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
Now how can I use this jar inside my App.java?
Do I have to create a .classpath file manually?
How can I arrange my classpathentries automatically?
I have been trying to create a manifest.MF with the classpassentries but with no success. I have tried several tutorials.
I had no success with:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<includes>
<include>${project.basedir}
/resources/repo/optional- new-name.jar</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true
</addDefaultImplementationEntries>
<addClasspath>true</addClasspath>
<mainClass>your.main.Class</mainClass>
</manifest>
<manifestEntries>
<Class-Path>${project.basedir}/resources/repo</Class-Path>
</manifestEntries>
<manifestFile>
<!--
${project.build.outputDirectory}/META-INF/MANIFEST.MF
-->
${project.basedir}/META-INF/MANIFEST.MF
</manifestFile>
</archive>
<!--
<archive>
<manifest>
<mainClass>com.mkyong.core.App</mainClass>
</manifest>
</archive>
-->
</configuration>
after creating the manifest.MF manually.
after the command
mvn clean install
the manifest.MF remains empty.
+1 for not using eclipse ;^)
If you are looking to reference code from another JAR then try adding the following to your POM:
<dependencies>
<dependency>
<groupId>xxx</groupId>
<artifactId>yyy</artifactId>
<version>zzz</version>
</dependency>
</dependencies>
Where xxx, yyy and zzz are the maven coordinates for the JAR you want to import. You can get these from your Nexus
Edit:
So for example if you were looking to import Joda time it would be
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.6</version>
</dependency>
If you are looking to combine the contents of all your dependencies with your code and release them as a single JAR then you might want to take a look at the maven-shade-plugin. See How to package a jar and all dependencies within a new jar with maven
And one other thing, you should never play with the .classpath file. This is something Eclipse specific. Changing it won't effect Maven and will probably confuse Eclipse
Got it!
I followed this tutorial until step 5.
http://www.mkyong.com/maven/maven-create-a-fat-jar-file-one-jar-example/
Instead of doing step 5 I added:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
To the pom.
and voila:
mvn package
and
java -jar target/dateutils.jar
Now it works.
So thanks for you're help Stormcloud!
So what happened? Still no resources spotted in my .jar.
The jar got shaded.
https://maven.apache.org/plugins/maven-shade-plugin/
What if I want to export my jar on a server without maven. So how to export a complete working jar?
Thanks again!

Maven adding mainClass in pom.xml with the right folder path

I want to get a working jar file with my maven project.
The build part is:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.14</version>
<dependencies>
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>6.4.1</version>
</dependency>
</dependencies>
<configuration>
<consoleOutput>true</consoleOutput>
<configLocation>${basedir}/src/test/resources/checkstyle_swt1.xml</configLocation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptor>src/assembly/src.xml</descriptor>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
<addClasspath>true</addClasspath>
<mainClass>org.jis.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
So my problem right now is that I don'T know how to implement the mainclass properly into my pom.xml and later into my jar file.
The Folder Structure is: src/main/java/org/jis/Main.java
but if I add the following line
<mainClass>src.main.java.org.jis.Main</mainClass>
It doesn't work.
First, your main class doesn't include src/main/java. Look at the package declaration in that Java file. For example, package org.jis;, then add the main class to that. In other words, it's only org.jis.Main.
You need to configure the maven-jar-plugin instead the of the maven-compiler-plugin. The jar-plugin is the one which is responsible for packaging and creating the manifest.MF.
From http://maven.apache.org/shared/maven-archiver/examples/classpath.html
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
...
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
...
</plugin>
</plugins>
</build>
You may mention as below if it's a spring boot application.
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.test.MainClass</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Basically Maven is a framework which have a collection of maven-plugin for each and every action performed to build a project.
Each Build Phase is performed by corresponding maven-plugin using project's description Project Object Model(POM)
So maven-compiler plugin is just responsible to compile the project and it won't create the manifest file.
maven-jar-plugin is responsible for creating the manifest file of the project.
Just leaving this here for individuals who were as frustrated as I was trying to get an incredibly simple example to work.
The issue I was having is that the maven jar archiver had some bad information cached, so if you are giving it the proper main class (or in my case you don't actually need to do that with the proper maven version and settings).
Try blowing away the "target" directory if you are using IntelliJ and have one. The "target" directory being the one maven default places the jar for instance.
You have to use the fully qualified name of your main class:
<mainClass>org.jis.Main</mainClass>
It seems that some time has passed since the question but I'll share the solution I've reached for future readings.
I'm using a Maven Project in the IntellJ IDE. Even using the full path copied from the operation system like: C:\Users\Rogerio\Desktop\Script\src\main\java\Controller\MainClass.java, with or without .java or even trying the com.src... approach the main class was not found while creating the jar file for my application.
The solution was putting the CDATA tag inside the mainClass tag of the maven-jar plugin, as follows:
My file structures:
[A directory imagem structure on IntelliJ][1]
[1]: https://i.stack.imgur.com/LHCWc.jpg
Inside my maven-jar plugin on pom.xml:
`<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass><![CDATA[Controller.MainClass]]></mainClass>
</manifest>
</archive>
</configuration>
`
In case, You are using Spring Boot Application. Add the below in pom.xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
This will add the Main-Class entry in MANIFEST.MF file.

Categories

Resources