java.lang.NoClassDefFoundError: org/telegram/telegrambots/meta/exceptions/TelegramApiException - java

I'm trying to deploy my first java application using Maven. In this case, this is just a simply telegram bot, but I get this error when trying to run it locally. After a little investigation, I found that java.lang.NoClassDefFoundError is an error that occurs when a jar file is not able to access a specific class in runtime, and in order to solve this, is necessary to add that class on classpath.
I understand that when working on Maven, there is a simple way to add classes on the classpath, and it's by adding the right dependency on the pom.xml file.
So this is what i've added:
<dependencies>
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-abilities</artifactId>
<version>5.0.1.1</version>
</dependency>
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots</artifactId>
<version>5.0.1</version>
</dependency>
<dependency>
<groupId>org.telegram</groupId>
<artifactId>telegrambots-meta</artifactId>
<version>5.0.1.1</version>
</dependency>
</dependencies>
And I think it was successfully added on the classpath because this is what I get when I read the MANIFEST.MF file on my jar file:
Manifest-Version: 1.0
Created-By: Apache Maven 3.6.3
Built-By: agujared
Build-Jdk: 15.0.1
Class-Path: telegrambots-abilities-5.0.1.1.jar commons-lang3-3.11.jar ma
pdb-3.0.8.jar kotlin-stdlib-1.2.71.jar kotlin-stdlib-common-1.2.71.jar
annotations-13.0.jar eclipse-collections-api-11.0.0.M1.jar eclipse-coll
ections-11.0.0.M1.jar eclipse-collections-forkjoin-11.0.0.M1.jar lz4-1.
3.0.jar elsa-3.0.0-M5.jar slf4j-api-1.7.30.jar telegrambots-5.0.1.jar j
ackson-annotations-2.11.3.jar jackson-jaxrs-json-provider-2.11.3.jar ja
ckson-jaxrs-base-2.11.3.jar jackson-module-jaxb-annotations-2.11.3.jar
jackson-core-2.11.3.jar jakarta.xml.bind-api-2.3.2.jar jakarta.activati
on-api-1.2.1.jar jackson-databind-2.11.3.jar jersey-hk2-2.32.jar jersey
-common-2.32.jar osgi-resource-locator-1.0.3.jar jakarta.activation-1.2
.2.jar hk2-locator-2.6.1.jar aopalliance-repackaged-2.6.1.jar hk2-api-2
.6.1.jar hk2-utils-2.6.1.jar javassist-3.25.0-GA.jar jersey-media-json-
jackson-2.32.jar jersey-entity-filtering-2.32.jar jersey-container-griz
zly2-http-2.32.jar jakarta.inject-2.6.1.jar grizzly-http-server-2.4.4.j
ar grizzly-http-2.4.4.jar grizzly-framework-2.4.4.jar jakarta.ws.rs-api
-2.1.6.jar jersey-server-2.32.jar jersey-client-2.32.jar jersey-media-j
axb-2.32.jar jakarta.annotation-api-1.3.5.jar jakarta.validation-api-2.
0.2.jar json-20180813.jar httpclient-4.5.13.jar httpcore-4.4.13.jar com
mons-logging-1.2.jar commons-codec-1.11.jar httpmime-4.5.13.jar commons
-io-2.8.0.jar telegrambots-meta-5.0.1.1.jar guava-30.0-jre.jar failurea
ccess-1.0.1.jar listenablefuture-9999.0-empty-to-avoid-conflict-with-gu
ava.jar jsr305-3.0.2.jar checker-qual-3.5.0.jar error_prone_annotations
-2.3.4.jar j2objc-annotations-1.3.jar
Main-Class: domain.Main
As you can see, telegrambots-meta-5.0.1.1.jar is part of the classpath attribute.
How can I solve this?
By the way, I'm using Heroku Cloud to deploy this

Sounds like you want and need to create a runnable/ executable JAR file (with external dependencies).
This requires your build process to be enhanced by this step, regardless of where it is executed Heroku, Jenkins, Bamboo or on your local - this is a maven setting and will affect each of them.
Also on your local you can run the build of your project by executing mvn clean package in your IDE and afterwards to run the created JAR from the target folder with: java -jar ${yourJarName}. It'll likely fail for the same reason.
This is, because Maven dependencies are added with a so called scope. These are for example:
compile
provided
runtime
test
Whereby compile is the default one and being implicitly applied in case you don't specify it - like in your case. (You can read more about the scopes here)
This means Maven will add your dependency to your IDE at compile time, but it will be missing at the runtime, when your trying to execute it.
The solution is to create a runnable/ executable JAR file (also called *fat JAR *) containing all the needed dependencies.
You can do it directly within Maven with the help of the maven-assembly-plugin like so:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
Then you need to build your JAR like:
mvn clean compile assembly:single
Note: The compile goal must be added before assembly:single or otherwise the code on your own project is not included.
To ease the handling of the process this goal commonly is tied to a Maven build phase to execute automatically. This ensures the JAR is built when executing mvn clean package, mvn clean install or performing a deployment/ release:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</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>
</plugins>
</build>
Like this you can simply build your project with the mvn clean package command (probably the most common one) and it'll include the creation of the runnable/ executable JAR file. This will include all your needed dependencies and should resolve your java.lang.NoClassDefFoundError issue.
Just a short additional note
Creating runnable/ executable JAR file respectively fat JAR is not the only solution and maybe in some contexts unwanted. Since fat JAR files include all their needed dependencies, they are fairly big with all the related drawbacks (requires more bandwith to transmit, download size increases, same dependencies might be carried in multiple different JARs, ...).
For this reasons the fat JAR creation is avoided in Web Application Development with Java EE. Dependencies are only added at compile time, since it is known that a Servlet Container or Application Container like Tomcat or Wildfly will provide these at runtime to avoid the java.lang.NoClassDefFoundError. Therefore the different applications (JARs or in this context called WARs) don't need to provide the dependencies themself.
In your case it might also be the solution that you'll still build the thin JAR, but will provide the needed dependencies at runtime (e.g. separately downloading it and then specifying in the classpath before the execution).

Related

How to use an entire Java project inside another Java project and instantiate and use classes and methods?

I came out with a situation i have a maven proyect with several clases and methods... and i need to have the same project classes and methods across some other projects that needs them.
After reading some about Git submodules, and Git Subtrees, and other ways to acomplish this. what i decided was to export a Jar file with its dependencies, and copy it to all other projects in the '${basedir}/lib/' subdirectory. This way i keep it simple enough for all the devs in my QA team (we are not SO much experienced devs, as we came from QA world) and also i can control that all of them use the same libs in all projects.
I exported to Jar file with the assembly maven plugin, adding this to my POM file in the first repo:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
And running
$ mvn clean compile assembly:single
I have the Jar file in the 'target' directory which i copied to all other repos. in the 'lib' directory of each repo.
Then in the POM files of the other repos i added to their POMs dependencies section:
<dependency>
<groupId>myDep</groupId>
<artifactId>myDep</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${basedir}/lib/myDep-1.0-SNAPSHOT-jar-with-dependencies.jar</systemPath>
</dependency>
The thing is that i could not figure it out how to import the Jar in my classes to use the methods i need from this imported Jar. As i tried to import like
import myDep.*
But its not working.
Could you point me in the right direction? thank you so much!
Usually, before you start using Maven, you set up some infrastructure:
a Nexus or Artifactory server for the artifacts (jars, wars etc.)
a build server like Jenkins.
Then you build your jars (without anything like maven assembly plugin) on the Jenkins with mvn clean deploy. Then they are avaible in the Nexus/Artifactory.
If the developers have a settings.xml pointing to the right Nexus/Artifactory, they can then just add
<dependency>
<groupId>myDep</groupId>
<artifactId>myDep</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
to their pom.xml without specifying any path or copying anything around. Maven will then do the magic to resolve that dependency from Nexus/Artifactory.

Maven Exception NoClassDefFoundError ClassNotFoundException but Maven Dependency Exists Command Line

I am having a problem with maven. I have included a dependency as such in my pom.xml:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.6</version>
</dependency>
I am using Intellij as an IDE, and I get no compile warnings there or anything. I am using the command line to run the maven commands, and I can run mvn install compile package all without trouble.
However, when I try running the jar as such:
java -cp target/stride-1.0-SNAPSHOT.jar com.myapp.maven.App
I get this error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/csv/CSVFormat
at com.stride.maven.App.parseCsv(App.java:43)
at com.stride.maven.App.main(App.java:25)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.csv.CSVFormat
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
Clearly, maven cannot find that path. I tried deleting the .m2, rebuilding, and mostly everything I have found on stackoverflow, but I cannot find the issue, or get visibility into the issue. Note, in my Intellij I can see the dependency in the external libraries.
I have also tried using shade to copy the dependancies to the jar:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<transformers>
<transformer implementation=
"org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.myapp.maven.App</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
Following which I reran mvn clean install package and then my build command. No luck.
I have also tried Maven Assembly plugin. Guess what, no luck!
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
com.myapp.maven.App
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
I confirmed the dependencies are not even getting built in.
Thanks!
Maven works great in this case.
However, you seem to miss the point of dependency.
When you define a dependency maven uses it during the compilation (hence no errors in both intelliJ and when you execute mvn install)
But this doesn't mean that dependency is placed right into the jar.
There are more complicated packaging types of application where it indeed works like this (dependant jars are included into the artifact) for example Spring boot application, Web Archives (WAR) and so forth. But since you compile a regular JAR it will include only the classes of your module and won't include classes of commons-csv in this case.
So in order to be able to run this application you should chose one of:
Put Jar of commons-csv (as well as other dependencies that you might have) into class path: java -classpath <path-to-commons-csv> -jar YourApp
Use Maven Shade Plugin to create a jar that will indeed include all the dependencies as classes
As mentioned in the other answers, you need to package up your dependencies in your executable jar (a.k.a. Uber-JAR). You mention you have tried two ways: using the Maven assembly with a descriptorRef jar-with-dependencies and the Maven shade plugin.
First global remark: Maven plugin configuration can be defined in a <pluginManagement> block or directly in the <build> part of a POM. I would suggest to put them in the <build>, and I assume you already put them there, but I can't verify that since you only pasted a part of it in your question.
When using the jar-with-dependencies descriptorRef in the Maven assembly plugin, two jar files will be created in your target/ folder: stride-1.0-SNAPSHOT.jar and stride-1.0-SNAPSHOT-with-dependencies.jar. You should use the -with-dependencies.jar, so run java -cp target/stride-1.0-SNAPSHOT-with-dependencies.jar com.myapp.maven.App
The Shade plugin offers more options than the Maven assembly plugin. However in the code you pasted you have not bound the execution of the Maven Shade plugin to the package phase of Maven's lifecycle. If you run a mvn package you will NOT see the Maven shade plugin as part of the build steps that Maven did. If you look more closely to mkyongs guide, you'll see that you need to include a <phase>package</phase> in your <execution> block.
Hi the problem is that when the jar is getting created the dependencies being downloaded is not being attached to the executable jar that is why there error is showing up we can add the below section in the build tag to get the dependencies attached to the executable jar and then you can execute the jar with java -jar command
maven-assembly-plugin
package single
... wow.dxdatagenerator.App
jar-with-dependencies
-->

a maven program is able to run successfully from eclipse but not from command prompt [duplicate]

My first use of Maven and I'm stuck with dependencies.
I created a Maven project with Eclipse and added dependencies, and it was working without problems.
But when I try to run it via command line:
$ mvn package # successfully completes
$ java -cp target/bil138_4-0.0.1-SNAPSHOT.jar tr.edu.hacettepe.cs.b21127113.bil138_4.App # NoClassDefFoundError for dependencies
It downloads dependencies, successfully builds, but when I try to run it, I get NoClassDefFoundError:
Exception in thread "main" java.lang.NoClassDefFoundError: org/codehaus/jackson/JsonParseException
at tr.edu.hacettepe.cs.b21127113.bil138_4.db.DatabaseManager.<init>(DatabaseManager.java:16)
at tr.edu.hacettepe.cs.b21127113.bil138_4.db.DatabaseManager.<init>(DatabaseManager.java:22)
at tr.edu.hacettepe.cs.b21127113.bil138_4.App.main(App.java:10)
Caused by: java.lang.ClassNotFoundException: org.codehaus.jackson.JsonParseException
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
... 3 more
My pom.xml is like this:
<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>
<groupId>tr.edu.hacettepe.cs.b21127113</groupId>
<artifactId>bil138_4</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>bil138_4</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.6</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Can anyone help me?
By default, Maven doesn't bundle dependencies in the JAR file it builds, and you're not providing them on the classpath when you're trying to execute your JAR file at the command-line. This is why the Java VM can't find the library class files when trying to execute your code.
You could manually specify the libraries on the classpath with the -cp parameter, but that quickly becomes tiresome.
A better solution is to "shade" the library code into your output JAR file. There is a Maven plugin called the maven-shade-plugin to do this. You need to register it in your POM, and it will automatically build an "uber-JAR" containing your classes and the classes for your library code too when you run mvn package.
To simply bundle all required libraries, add the following to your POM:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Once this is done, you can rerun the commands you used above:
$ mvn package
$ java -cp target/bil138_4-0.0.1-SNAPSHOT.jar tr.edu.hacettepe.cs.b21127113.bil138_4.App
If you want to do further configuration of the shade plugin in terms of what JARs should be included, specifying a Main-Class for an executable JAR file, and so on, see the "Examples" section on the maven-shade-plugin site.
when I try to run it, I get NoClassDefFoundError
Run it how? You're probably trying to run it with eclipse without having correctly imported your maven classpath. See the m2eclipse plugin for integrating maven with eclipse for that.
To verify that your maven config is correct, you could run your app with the exec plugin using:
mvn exec:java -D exec.mainClass=<your main class>
Update: First, regarding your error when running exec:java, your main class is tr.edu.hacettepe.cs.b21127113.bil138_4.App. When talking about class names, they're (almost) always dot-separated. The simple class name is just the last part: App in your case. The fully-qualified name is the full package plus the simple class name, and that's what you give to maven or java when you want to run something. What you were trying to use was a file system path to a source file. That's an entirely different beast. A class name generally translates directly to a class file that's found in the class path, as compared to a source file in the file system. In your specific case, the class file in question would probably be at target/classes/tr/edu/hacettepe/cs/b21127113/bil138_4/App.class because maven compiles to target/classes, and java traditionally creates a directory for each level of packaging.
Your original problem is simply that you haven't put the Jackson jars on your class path. When you run a java program from the command line, you have to set the class path to let it know where it can load classes from. You've added your own jar, but not the other required ones. Your comment makes me think you don't understand how to manually build a class path. In short, the class path can have two things: directories containing class files and jars containing class files. Directories containing jars won't work. For more details on building a class path, see "Setting the class path" and the java and javac tool documentation.
Your class path would need to be at least, and without the line feeds:
target/bil138_4-0.0.1-SNAPSHOT.jar:
/home/utdemir/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.9.6/jackson-core-asl-1.9.6.jar:
/home/utdemir/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.9.6/jackson-mapper-asl-1.9.6.jar
Note that the separator on Windows is a semicolon (;).
I apologize for not noticing it sooner. The problem was sitting there in your original post, but I missed it.
You have to make classpath in pom file for your dependency. Therefore you have to copy all the dependencies into one place.
Check my blog.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>$fullqualified path to your main Class</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
This is due to Morphia jar not being part of your output war/jar. Eclipse or local build includes them as part of classpath, but remote builds or auto/scheduled build don't consider them part of classpath.
You can include dependent jars using plugin.
Add below snippet into your pom's plugins section
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
For some reason, the lib is present while compiling, but missing while running.
My situation is, two versions of one lib conflict.
For example, A depends on B and C, while B depends on D:1.0, C depends on D:1.1, maven may
just import D:1.0. If A uses one class which is in D:1.1 but not in D:1.0, a NoClassDefFoundError will be throwed.
If you are in this situation too, you need to resolve the dependency conflict.
I was able to work around it by running mvn install:install-file with -Dpackaging=class. Then adding entry to POM as described here:
Choosing to Project -> Clean should resolve this

Running JAR with maven-dependencies not contained in this JAR

So i have a following problem:
I have a maven-project with several maven-dependencies. When i run mvn install it'll be packaged as .jar and the .jar together with the .pom-File will be placed inside my maven-repository. Now, this .jar does not contain other dependencies (and is also not supposed to!). Now, given that i have all the dependencies needed installed in my maven repository (which obviously maven will take care of), how can i run this jar on the command line without setting the classpath to point to every damn jar in the maven-repository? Is there any other way? mvn exec:java only seems to work within the maven-source directory, where it looks for the "pom.xml". But after installing, "pom.xml" becomes "name-version.pom" and i have a .jar instead of direct source/class-files. Is there any other way to point mvn exec:java to work with the .jar and .pom-File within the maven repository? Or maybe some other and better approach to do so?
Thanks in advance :)
EDIT1: I'll just put my comment from below in here to avoid further misunderstandings:
I do not want to put the dependency jars somewhere. I want to use the repository maven already takes care of.Theoretically given, that i have ALL libraries i will ever need already in my local maven repository. I want to be able to download any other maven project, that might be using some of the libraries i already have installed in my local repository, also install it using "maven install", then remove the source i downloaded and then execute the .jar created by maven and tell java or maven (depending on what the best approach is) to look for the dependencies of that project in my local maven repository.
I hope i made it clear enough :)
EDIT 2: So i decided to use mvn install to install the projects into my local .m2 repo and also keep the projects unpackaged in some defined folder.Then i can just call mvn exec:java inside those projects to run them and maven will resolve all the dependencies for me.
You may exclude some dependency that you don't want to be in your project like this -
<project>
...
<dependencies>
<dependency>
<groupId>sample.ProjectA</groupId>
<artifactId>Project-A</artifactId>
<version>1.0</version>
<scope>compile</scope>
<exclusions>
<exclusion> <!-- declare the exclusion here -->
<groupId>sample.ProjectB</groupId>
<artifactId>Project-B</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
For more information you may check the link
Make a Jar executable and define classpath dependencies with maven can be done using maven-jar-plugin to create a manifest file. The manifest file is usually used for that
example
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<!-- It define the classpath dependencies -->
<addClasspath>true</addClasspath>
<classpathPrefix>dependency-jars/</classpathPrefix>
<!-- it makes the jar executable -->
<mainClass>com.mycompany.App</mainClass>
</manifest>
<!-- it define some entries about your artifact -->
<manifestEntries>
<Build-Maven>Maven ${maven.version}</Build-Maven>
<Build-Java>${java.version}</Build-Java>
<Build-OS>${os.name}</Build-OS>
<Build-Label>${project.version}</Build-Label>
</manifestEntries>
</archive>
</configuration>
</plugin>
When you run the command mvn package|install, the following meta-inf/manifest.mf file will be created and added into the Jar.
If you need the dependency jar be in somewhere, that can be done easily, you will use maven-dependency-plugin to copy project dependencies to somewhere you want. you can copy into your project build directory into the manifest prefix folder defined
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/dependency-jars/
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
all dependencies will be in {project}/target/dependency-jars/
That approach not include any dependency into the jar all will be out the jar in somewhere you define.
You can configurate your projects using this approach as you need
whit this approach you only have to do mvn clean install and execute your jar
I hope this aproach be the solution that you need.

Building war and runnable jar with Maven

I have started a new Java project using Maven.
I wrote a set of core functionalities, a REST web service which use them, and a command line interface.
When I run maven package, I would like to be able to:
Build a war with the web service, AND
Build a runnable jar which packs the dependencies and starts the command line interface
How have I to configure Maven in order to reach the goal?
Let me add some details.
I already know how to produce only a WAR, and how to produce only a JAR.
What I need is to produce BOTH with ONE maven package.
The WAR have to be deployable on a Tomcat, which should display the index.jsp page.
The JAR have to be runnable from the console.
With regards to the Runnable JAR (point 2), you should use maven-assembly-plugin, which will create a JAR with all the dependencies you need, and you can run it from the command line. On the plugins section of your pom.xml, you have to add something like this:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
The you can run:
mvn clean compile assembly:single
More info, can be found here.
Hope it helps!
For point 1, I would start by using Maven itself to create a pom.xml that can be used to build your web app.
$ mvn archetype:generate -DgroupId={project-packaging}
-DartifactId={project-name}
-DarchetypeArtifactId=maven-archetype-webapp
-DinteractiveMode=false
See this link for more.
Once you've added your code to the source tree appropriately and built the WAR, you can copy it to your application server and it should be ready to go.

Categories

Resources