Let's say we have a simple Java project compiles into a simple.jar with its POM depends on log4j.jar. When I open the simple-1.0.jar, inside there is no log4j.jar. And then we upload this simple-1.0.jar onto Nexus.
Now when deploy this simple-1.0.jar to the target server, how do we deploy the log4j.jar?
Thanks
Jirong
You can either package the dependencies with your application (i.e. create an uber-jar, WAR, or EAR file) or you can deploy the dependent jars to a location on the server and then set that location as the classpath when you run the jar.
Packaging an application as an Uber-JAR
One way of creating an uber-jar with Maven would be to use the maven-shade-plugin
Deploying the dependent jars and setting classpath
In this scenario you would create a "libs" folder somewhere on the target machine and copy all of the dependent jars into this folder.
Then when you launch your application you would set the classpath like so:
java -classpath /{libs directory} -jar simple-1.0.jar
Multiple classpath entries can be specified by separating them with a : like also:
java -classpath /{directory1}:/{directory2} -jar simple-1.0.jar
You can have Maven list the resolved dependencies using the dependency plugin:
mvn dependency:list
Related
I have a executable jar containing an embedded Tomcat which is created thanks to tomcat7-maven-plugin: tomcat7:exec-war.
I need to provide an additional classpath for some Jar because I cannot include them directly in my executable Jar. How can I provide this classpath ?
I cannot execute export CLASSPATH before I launch my executable Jar because catalina.sh/.bat erase the CLASSPATH value.
I cannot provide a setenv.sh/.bat because the executable Jar is created by the maven plugin.
I cannot update property common.loader from catalina.properties because I don't have control on this file which is generated by maven plugin.
Note: I don't want to specify a hardcoded path to the lib in the executable Jar.
Actually whatever jar files are inside WAR file at WEB-INF/lib are in classpath for WAR file classloader.
So, you can package your additional jar into war.
I'm not familiar with maven tomcat plugin, but just look to its options. It must have ability to put additional jars into war file (maybe just through dependencies in compile or 'runtime` scope. It is a standard feature.
If your additional jar must be outside of war you have to give it in system classpath for Java when you run your executable jar (through -cp parameter, I guess). Or you can define path to it in the MANIFEST.MF file of your jar.
I have a Java console application, till now it was developed in Netbeans IDE. When Netbeans builds application, it creates dist directory and builds an app into this directory as a jar archive and into dist/lib copies all dependencies. This this directory could be copied into final destination and run.
Now I'm trying to transfer this project into Maven. Everything goes ok, I can compile and package my app and a jar is created into target directory. I use maven-jar-plugin to set main class in manifest and maven-shade-plugin to package all sources into one jar file.
I would like to ask you how is such Maven project deployed in the real world? Should I use all target directory, copy it ad the final destination and run as I have been used to do with Netbeans? What are consequences when I don't use maven-shade-plugin - where are all libraries defined as dependencies located? I am asking, because in my testing project these libraries don't exist in target directory.
My question - I have a Java console application "A" packaged via Maven (without maven-shade-plugin) and Linux server "S" where this application should run. Can I copy all target directory manually to server "S" or is there some better / more automatic way how is this solved in the real world?
Simply copying over the target directory will not solve your problem. I have packaged many standalone applications using Maven and I have used Maven Assembly Plugin for it. You can create a distribution archive (zip, tar.gz) using the assembly plugin which your customer can unzip and start running.
It depends on you, how you want your target application directory structure (release). I usually end up with something like
bin/
conf/
lib/
log/
The bin directory contains a shell / batch script to run your program by calling your main class, setting appropriate classpath, providing relevant memory settings etc. I prefer using classworlds (which is used by Maven) to bootstrap my application and simplify writing of start scripts.
conf directory contains configuration files for your application as well as logging configuration files like log4j etc. This directory I add on classpath to make it easier to access configuration resources at runtime.
lib directory contains all the dependency jars a well as jar file for your code.
log is where your logging configuration will point to output log files.
Note that this structure is good for standalone server like applications. Also having a bin directory and run scripts allows you to add this directory to PATH on Windows / Linux to ensure you can run the application from anywhere.
If you are packaging a command line utility, simple shaded jar may work for you. Personally, I am not the biggest fan of java -jar application.jar
The question is too broad to be answered comprehensively, but I would like to provide an example of real-world maven deployment.
There are maven plugins for all major application servers. They have defined targets for local and remote deployment. One such plugin is the jboss-as-maven plugin. You can define the deployment properties (IP, port etc.) in your .pom or directly from command line, e.g.
mvn jboss-as:deploy -Dpassword=mypassword
There is also the cargo plugin that specializes in application deployment.
I have a jar that uses a manifest for some of its dependencies which are packed up into a jar using maven.
Is it possible to run the jar with both the internal packaged up jars, which are described in the manifest, and jars that I pass using -cp at application launch?
Or is it one or the other?
I have added to my pom.xml a section that specifies the mainClass and allows it to essentially create an executable jar. I have included a bunch of dependencies that maven manages as well. It compiles, and if I run the program with no options, it executes fine, displaying usage information. However, if I actually pass in the parameters, it fails and says NoClassDefFoundError: com/sas/isd/midasapi/ParticipantDetailExt, which is in a jar I included as an external jar. I am confused that it compiled and runs to show usage information, but it fails to find the class after as the ParticipantDetailExt is a class that is imported. Wouldn't it identify that it was not found during compiling? How do I get it so that my on jar with ParticipantDetailExt is seen when I run my exectutable jar? Is there a classpath thing or pom thing I need to do in addition to the adding jar as external jar?
I assume that you are running mvn clean package or mvn clean install to create your jar.By default the jar created by a maven project does not include dependencies in that jar.
Option 1# create a jar-with-dependencies, see: How can I create an executable JAR with dependencies using Maven?.
Option 2# If you are just looking to copy dependencies to a lib folder see: http://maven.apache.org/plugins/maven-dependency-plugin/copy-dependencies-mojo.html
I am doing some basic spring stuff and stuck at some point.
I am getting ClassNotFoundException whenever I deploy my application on Tomcat.
I observed that the jars are not copied to Tomcats lib folder.
When I copied the jars manually to Tomcats lib folder it works fine.
Please let me know if I am making any blunder.
PS - I am using Spring tool suite 2.6.0,Tomcat 6 and its a Maven project.
Thanks.
Go to "Project properties -> Deployment Assembly page".
This page describes how your application will be packaged for deployment or export. And added new source "Maven dependency".
From Deployment Assembly page, Click Add... button
Then select "Java Build Path Entries"
"Maven dependency" should be in the list
It solves the issue and all jar got copied to tomcat
If you define "war" packaging for your maven project then your dependent libraries should be automatically copied to the WEB-INF/lib directory of the created .war file by the Maven WAR plugin.
Put your jars in the WEB-INF/lib directory:
In Project properties -> Deployment Assembly you should have a Source of /web with a Deployment Path of /. If this is there then any jars in the web/WEB-INF/lib directory will get deployed and picked up by the class loader. Note that sub-directories will not be picked up though, so put your jars directly in the lib directory.
You run three command in cmd or bash(where your pom.xml file placed) to get jar file and copy it into your WEB-INF/lib folder
mvn compile
mvn package
mvn install
I find only this way for resolved my problem:
java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener