Dear all I have a maven project and I need to run it using apache-maven I'm using the command mvn install to compile and add it to .m2 repository but how can I run this maven project via apache-maven server without using IDE's
Thanks in advance
In order to run a simple Java project, you have to identify the Main class. If you are using Maven for the build, the packaging will have to specify which class contains the main method.
You can do the above in Maven POM by adding a manifest in the configuration for the maven-jar-plugin which is responsible for the packaging. In other words, you simply add the following to your POM.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>libs/</classpathPrefix>
<mainClass>
org.baeldung.executable.ExecutableMavenJar
<!--Full classified name of the class that contains the main method -->
</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Once the JAR is created, you can execute it by invoking the following:
java -jar jarName.jar
You can find more details on the topic at http://www.baeldung.com/executable-jar-with-maven
You can follow these steps to find the solution of the main question:
https://www.mkyong.com/maven/how-to-deploy-maven-based-war-file-to-tomcat/
Related
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).
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.
I am working in Java Maven project. There is a .bat file in the root of the project which invokes a Java class with some arguments something like this:
java my.package.MyClass abc hi 1
Now, my project jar is built in the target directory of that project when I do mvn clean install. When I run that .bat file it gives me the below error
Error: Could not find or load main class my.package.MyClass
Project's pom.xml only contains jars as dependency.
Do I need to do something in pom.xml to make it work?
please provide your pom.xml so we can look for it,
anyway,
do you use maven-jar-plugin?
something like this
<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>your.main.class.package.ClassName</mainClass> // your main class
</manifest>
</archive>
</configuration>
</plugin>
and try to run your *.jar with command java -jar yourjar.jar
I have been trying for several days now to create an executable jar file for my muli-module maven project. However, when I try to run this jar file I get "Could not find or load main class src.main.java.com.domain.Mainclass" (I have changed the name domain and MainClass for my company's privacy sake)
I have searched for days and none of the obvious tips seem to work.
My project has a main maven project that downloads all of the dependencies (packaging:POM)
and several module projects (Packaging:Jar).
Everything seems to work fine, and all of the files are compiled into class files, but somehow the main class is not being added to the pom.
My Pom File 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.domain.project.MainClass</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
The Commands I Use: mvn clean package, then I cd into the target folder and do: java -jar jarfilename.jar
Any tips or help would be most welcomed!
Edit:
My current configuration creates a 2 jar files for every module:
projectname-jar-with-dependencies.jar
projectname.jar
When I navigate to the target folder of the module with my main class, I can successfully run the jar file. However, when I try to run the jar file of my parent maven project (the one with packageing:pom) I still get the same error. Does anyone know why the main jar file cannot find the main class?
Thanks!
You should not have src.main.java as part of the package name of your main class. It's just part of the default maven project folder structure convention. Your configuration should probably read:
<archive>
<manifest>
<mainClass>com.domain.project.MainClass</mainClass>
</manifest>
</archive>
I'm going to necro this post because it is important to have 3 different things set properly:
MainClass.java needs to be in <project_root>/src/main/java/com/domain/project/
Maven assembly plugin needs <mainClass>com.domain.project.MainClass</mainClass>
Your package should be set to com.domain.project
When those three match, Maven should package an executable JAR file.
it seems like you have one of the plugins missing. add the bellow to pom.xml file
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>yourclassnameKt</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
The plugin will add MANIFEST.mf file, which will tell the Java runtime which class to execute.
There is another issue that has the same problem ->
Kotlin + Maven assembling: no main manifest attribute
Reference: https://michaelrice.com/2016/08/hello-world-with-kotlin-and-maven/
I have a bit of a different but similar scenario so I thought I would share. I have a primary maven application packaged into a war through the build (pom.xml packaging configuration). I wanted to add a jar file that is created from one package within our source code, and added into the assembled output along with the webapp war. This allows us to deliver the web application along with a cli tool separately. I didn't want to reconfigure the pom.xml to be multi-module, but just to add a jar as a separate executable within our existing structure. I was banging my head against this for a while.
First, I ended up deleting my entire .m2 directory with maven repositories locally. It appears there may have been an issue for me here, because my ultimate code that worked seems to be the same as what wasn't working originally. I suspect the reasoning for this was I was trying different versions of libraries and was creating conflicts, but who knows. First suggestion I have if you are having issues is delete your .m2 folder and try from scratch.
Also reference #Adam Howell's answer because that is the fundamentals. I created a simplified example project to figure out why nothing was happening and in there I realized i forgot to prefix the folder structure as src/main/java... doh! Of course in my existing project, this was not the case.
And here is my plugin code i inserted in my pom.xml that worked:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.myCompany.app.cli.CLITool</mainClass>
</manifest>
</archive>
<outputDirectory>${project.build.directory}</outputDirectory>
<finalName>our-cli</finalName>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
I am pretty sure you can change the phase you want this done in, I figured earlier on in compile made since to ensure it was available for packaging later. I'm not very experienced with Maven though, so note that this may not be semantically in-line with Maven conventions.
And it worked! Not sure why this took me hours to work out although it did. This I just updated my bin.xml to include the jar file in my assembled deliverable, and Voilah! I have a jar executable separate from my webapp that I can use as a command-line interface tool.
I recently just started toying around with Maven in java. Time comes to test my project, it works fine in the NetBeans window, running the main class found in App.java (com.MyCompany.App), but when I try to run it from a command line I get an error:
java -jar fileName.jar
"No Main Manifest Attribute" in fileName.jar
I have tried adding a manifest.mf file specifying what main is, I've also been into project properties and added it as the main file...
What's going on?
You need the maven-jar-plugin (see Maven's example). This plugin will create the required entries in the manifest file when the project is built.
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>fully.qualified.MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
You need the version, otherwise, the project won't build. The fully.qualified.MainClass starts at the package hierarchy.
Hope there is a problem in your manifest file. Some basic checks might solve your problem.
it should under /META-INF/MANIFEST.MF
Content should have Main-Class:com.MyCompany.App
If you are using any IDE, there should be an option to export project as runnable jar, you can make use of that to let the IDE take care of correct manifest.
From command line jar cfm filename.jar Manifest.txt com/MyCompany/*.class which generates the Manifest file with following contents
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Main-Class: com.MyCompany.App
And then you can run jar command java -jar fileName.jar.
These type of problems are trivial but kills lot of time, just ensure your contents and location of the file is correct.
You could just use this for command line:
java -cp jarFileName.jar full.package.className
You wouldn't have to go into specifics of the Manifest file in this case.
Setting an Entry Point with the JAR Tool:
The 'e' flag (for 'entrypoint') creates or overrides the manifest's Main-Class attribute. It can be used while creating or updating a JAR file. Use it to specify the application entry point without editing or creating the manifest file.
For example, this command creates app.jar where the Main-Class attribute value in the manifest is set to MyApp:
jar cfe app.jar MyApp MyApp.class
You can directly invoke this application by running the following command:
java -jar app.jar
If the entrypoint class name is in a package it may use a '.' (dot) character as the delimiter. For example, if Main.class is in a package called foo the entry point can be specified in the following ways:
jar cfe Main.jar foo.Main foo/Main.class
If you look at the properties dialog for the project (from project tab, right click on your project and select properties) you'll see that there is a "run" item in the "Categories" window. Click on it and you'll see a dialog where you can specify the Main Class for the jar. That information will end up in your manifest.
I have been having this problem with Netbeans 8.0 and the built-in Maven project for the "Java Application" project prototype. Also I have Maven 3 and I found some of the suggestions on the web don't match the maven code used with Netbeans as well.
Anyway here's a simple recipe for having JAR file to run the main-class and embed dependent libraries. I made this work by comparing other project POM files for projects I found that worked with sub-project JAR-s so if someone with better Maven knowledge spots a gottcha, please speak. Also, I left in some normal stuff to provide context. Example follows:
<properties>
<packageName>trials.example</packageName>
<mainClass>${packageName}.CmdApp</mainClass>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<slf4jVersion>1.7.7</slf4jVersion>
<log4jVersion>1.2.17</log4jVersion>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
This section tells Maven about the project.
packageName ... Is the Java package for the main-class
mainClass ..... The fully qualified name for class with main() method.
You will see these used in the maven-jar-plugin.
The other thing the built-in example prototype didn't do was to package my sub-projects into the JAR so I can run from the command line. This is done with the maven-dependency-plugin below. The interesting bit is in the where we don't need to package the system stuff, and we want the dependant classes wrapped into our JAR.
These are used as follows:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<excludeScope>system</excludeScope>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<useDefaultManifestFile>true</useDefaultManifestFile>
<archive>
<manifest>
<mainClass>${mainClass}</mainClass>
<packageName>${packageName}</packageName>
<addClasspath>true</addClasspath>
<classpathPrefix>classes/</classpathPrefix>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
Hope that saves you the few hours of checking and testing to make it happen. Cheers, Will.