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.
Related
Case: all external jar files are in the folder
/usr/lib/jvm/jre-1.8.0-oracle-1.8.0.151-1jpp.5.el7.x86_64/lib/ext
I need to run my executable JAR that uses these jar files internally. Do I need to specify them when explicitly starting my jar, or since they are inside the JRE directory, will they be automatically pulled up?
The jar files inside the jre folder will be found automatically because you must have set the path of java to the folder in the system path.
I have created a JavaFX application using NetBeans IDE and below is my folder structure.
I want to a build a single jar file including all dependencies for this jar to work properly.
This jar requires testplanner and batch folder from project root directory and files inside dist folder to work properly.
How can I package all this to a single jar file?
Theoretically JAR files cannot contain dependencies within, as java does not support it out of the box. WAR and EAR archives can. What You want to do is not standard, but is named fat jar. Fat jars are used i.e. by spring-boot maven plugin, but you could try this:
https://dzone.com/articles/how-build-fat-jar-using
And some more explanation:
NetBeans - deploying all in one jar
Use tecreations Deploy. Put all your sources into a path declared as Tecreations.getProjectPath(), run BuildAll to create your corresponding classes, put your jars in projectpath/jars and select the appropriate settings, whether to include jars, sources or classes. Select your main class and click Deploy. Unsigned and signed output jars are produced in user/Documents.
Download: https://tecreations.ca/java/downloads/release.
The structure of my first app is simple:
libs
opencsv-3.8.jar
yamlbeans-1.0.jar
out
artifacts
...
production
...
src
META-INF
MANIFEST.MF
pl.krzysiu
App.java
CsvReplacer.java
Everything is fine during the compile and running the program. After building artifact jar file in the default out\artifacts directory, I get
java.lang.NoClassDefFoundError: net/sourceforge/yamlbeans/YamlException
when I try to run it by java -jar CsvReplacer.jar command
The libraries are included inside the jar file (they are there after unpacking it) - they are added to Libraries section in Project Structure (separately - one file per one lib), the whole libs dir is included in the Dependencies tab of Modules section (with export checkbox checked) and the libs dir is added in Output Layout of Artifacts section similarily.
The manifest file contains:
Manifest-Version: 1.0
Class-Path: libs\yamlbeans-1.0.jar libs\opencsv-3.8.jar
Main-Class: pl.krzysiu.App
Why the libs aren't visible for the App? If I copy this dir manually to the CsvReplacer.jar file's location - everything works fine.
The structure inside CsvReplacer.jar file looks like:
libs
opencsv-3.8.jar
yamlbeans-1.0.jar
META-INF
MANIFEST.MF
pl
krzysiu
App.java
CsvReplacer.java
IDE: Intellij IDEA 2016.3
The standard Java classloaders cannot find a JAR file embedded inside another JAR file.
You have two choices when making an executable JAR with dependencies.
Create a so-called uberJAR file by merging the contents of the dependent JARs into your main JAR.
References:
IntelliJ IDEA export Runnable program as Uber Jar
https://blog.jetbrains.com/idea/2010/08/quickly-create-jar-artifact/
Give your JAR a "Class-Path" manifest attribute to tell it where the (external!) dependent JARs are located.
You can't give a -cp and a -jar option together. But another alternative would be to get rid of the -jar option and use a -cp argument to specify the classpath.
Alternatively, you could implement a custom classloader that can load from a jar inside a jar, or use something like one-jar or Spring Boot.
I am using Java Simple Plugin Framework. I export a jar that has my plugin implementation. The implementation depends on a library, which I have as a jar. That jar gets exported within the lib directory of my jar, and added to the classpath of my jar.
But when I load my jar with JSPF, it fails with "NoClassDefFound" because it can't find the jar in the lib director of my jar.
My apologies if my approach off base; I just need to know how this is supposed to be done. How should I bundle my plugin implementation as a jar if it depends on another jar?
I used JSPF and achieved this requirement the following way:
place the library jar file in a folder called lib outside the plugin jar file. (So that
the lib folder and the plugin jar file is in the same folder). Then I added lib/"name_of_libjar" to the classpath entry in the manifest.mf file of the plugin jar file (Which should be inside the plugin jar files META-INF folder), and it worked fine for me.
I am using maven build tool.
The following two are my intentions.
1) To move some of the third party library jars out of my war from WEB-INF/lib folder [note: These jars are common between more than 2 war files (or artifacts)]
2) To make the war file small in size.
Is it possible to move those jars out of war and put it into a folder and these jars should be referred in the classpath only by the wars which require it.
I have tried adding the path to the jars in the Class-Path: of MANIFEST.MF of war files but it did not work out. Please help me out.
I assume the jars in question are necessary for compiling the code that make up the web application. If the third-party jars are necessary for compilation but you don't want them in your war file, you have two options:
In the <dependency></dependency> section for the third-party jar, add "<scope>provided</scope>".
Configure the maven war plugin to exclude the jars you don't want in the war. See http://maven.apache.org/plugins/maven-war-plugin/examples/skinny-wars.html for the details.
How you get the jar files that you exclude from the war into the web container's classpath depends on your environment. If you are using ear files, the Maven docs above talk about how to get the jars included in the ear file. If you are not using ear files, you will have to come up with your own way to get the jars into the container's lib directory.