best way to deploy a package - java

When I finished to write my classes I put them into a package structure and then I jarred all.
Now which is the best way to deploy and use my jar?
setting classpath;
use CLASSPATH variable;
using the extension mechanism.

Don't update the user's CLASSPATH environment variable because there is a risk that your deployed application will interfere with other Java applications that the user might want to run.
Don't deploy using the Extension mechanism because there is a risk that you will interfere with applications run by any user using the JVM that you have "extended".
The best solution is to create and deploy a wrapper script that uses the "-cp" argument, or a shortcut that runs a self-launching JAR file ... as suggested by other answers.

I you have a main class in that jar that you want to run the best approach is to put a META-INF/MANIFEST.MF file in the jar and launch your class using java -jar mypackage.jar
The manifest should contain a Class-Path and a Main-Class attribute
See http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html#JAR%20Manifest

If you mean by 'deploy and use' that you want to use it in another application, set it on the classpath of that application.
If you use the extension mechanism (I assume you mean putting the jar in pathtojava/lib/ext) every application using that jvm will have the jar loaded, the samecounts for the CLASSPATH as system variable. That is most likely not necessary?
If you ment to execute/use the jar as standalone application; just run it commandline, no classpath stuff needed. If you want to deploy on a server you probably wanted to make a war or ear fiel instead.

Best to my opinon is to provide batch files and shell scripts to start the application.
Sophisticated scripts check for environment variables like $JAVA_HOME (%JAVA_HOME%) and use them, if defined or use a default value.
Inside the script you could build the classpath in an internal variable and start the app with a line like
%JAVA_HOME%\bin\java.exe -cp %LIBRARIES% com.example.Main
I would prefer this solution over the java -jar Application.jar alternative, because this one requires that you setup the classpath inside the jars manifest. So deploying an application that depends on existing libraries on the target system is pretty difficults, just because you have to know the library paths before you build the application.

Setting the classpath (using -cp) is the best way, as you can have a different classpath for each application. The CLASSPATH environment variable is global for all Java applications running on the machine, as is the extension mechanism so you probably don't want to use those.
If your code is executable (ie it has a public static void main(String[] args) method) then you can also specify the class that the main method is in, and the associated classpath within the manifest file inside the Jar file. Once you have done that you can do this:
java -jar myJar.jar
And Java will work out the rest.

Related

Add resources to System PATH

I have a Maven application that includes .bat files, for usage in Window's CLI.
I'm considering having my .exe export (using launch4j) to request admin permissions and copy the resources to a subfolder in Program Files, is this good practice or should I move them somewhere else? If it is, how could I add the folder's /bin path to the PATH environmental variable?
For more clarification, I want to do this with java.
Did you try the maven exec plugin?
You can potentially execute any command using the exec plugin but specifically if you want to invoke your own Java program which is the output of your build, you can use the exec:java target. Instead of executing your jar, you can directly mention the main class of your application and also furnish it with vm arguments.
Detailed documentation is here
Please note that you can include the environment variables while invokign the exec target with the help of maven's own environment property access methods.
There is a lot more you can do with this plugin (create different run-modes using the configurations, run servers from within your project dependencies, redirect output to an error file (redirect the mvn output itself) and so on... Read the plugin documentation and try them all out..

How to link java application against 3rd party libs within deployment environment

Let's say I have a web-app.war containing Spring Boot application with libraries (.jar files) inside WEB-INF/lib. Then Someone has removed some of the libs from web-app.war. I put this archive on the deployment server and I have all the dependencies on that server (e.g. somewhere in /3rdparty/*.jar). I need to run my app with command java -jar web-app.war. I've read about classpath and I tried to do the following: java -cp /3rdparty/*.jar -jar web-app.war However I got the error: Could not find or load main class. I cannot rebuild my app within deployment server, I cannot avoid the situation that I described above, so is it possible to achieve my goal?
P.S. Probably this is a kind of dummy question but I really did not find anything non-trivial regarding this problem.
I think you can try use loader.path to add external jar. Also here some example

Specifying a javaagent within the jar file to be run

I'm developing an OpenJPA application (no webserver, regular java se app). In order to make OpenJPA work with my application, I need to set the openjpa-all-2.3.0.jar as a javaagent.
java -cp ... -javaagent:/full/path/to/openjpa-all-2.3.0.jar -jar app.jar
As I am packaging the openjpa.jar within the app.jar anyway, I am now wondering how it is possible to specify the javaagent, as a jar within my application jar file.
This didn't work
java -cp ".;.\app.jar" -javaagent:openjpa-all-2.3.0.jar pckg.Main
There's no way to do it.
The JVM does not look at the classpath to find the specified agent; it is expecting a file path, and you also cannot specify file paths inside jar files.
JDK-4648386 is the related feature request, and was closed Won't Fix after 18 years.
However, what you can do is write code to copy the agent jar from a classpath resource to a temporary file, and then attach it to the current running JVM. The ByteBuddy Agent library provides tooling to do this.

Where is the CLASSPATH?

I would like to use the library "Lucene" with java. The instructions to use it tell me I have to put the jar's cointaining the classes inside the CLASSPATH.
The CLASSPATH is the directory containing all the default classes of Java? Or the directory of my specific project? I'm using Eclipse as IDE.
Really confused about that! Thank you.
USEFUL SOLUTION: http://www.avajava.com/tutorials/lessons/how-do-i-use-lucene-to-index-and-search-text-files.html
The Classpath is a collection of directories and JAR files inside which the Java runtime will look for classes.
It can be configured via an environment variable named CLASSPATH, but this usage is not recommended, as it tends to constantly result in problems.
The preferred way to configure the classpath when running a Java program is to pass it via the -cp command line switch when you start the Java interpreter. Usually you write a shell script so you don't have to type it out every time.
If your issue is with using the classes inside the IDE where you write your code, then it depends of course on the IDE. For eclipse, the "Java Build Path" tab of the project properties is where you configure the classpath.

Differences between "java -cp" and "java -jar"?

What is the difference between running a Java application withjava -cp CLASSPATH and java -jar JAR_FILE_PATH? Is one of them preferred to the other for running a Java application? I mean which one of these ways is more expensive for JVM (according to their machine resources usage)?
Which one will cause JVM to spawn more threads while trying to run the application?
I prefer the first version to start a java application just because it has less pitfalls ("welcome to classpath hell"). The second one requires an executable jar file and the classpath for that application has to be defined inside the jar's manifest (all other classpath declaration will be silently ignored...). So with the second version you'd have to look into the jar, read the manifest and try to find out if the classpath entries are valid from where the jar is stored... That's avoidable.
I don't expect any performance advantages or disadvantages for either version. It's just telling the jvm which class to use for the main thread and where it can find the libraries.
With the -cp argument you provide the classpath i.e. path(s) to additional classes or libraries that your program may require when being compiled or run. With -jar you specify the executable JAR file that you want to run.
You can't specify them both. If you try to run java -cp folder/myexternallibrary.jar -jar myprogram.jar then it won't really work. The classpath for that JAR should be specified in its Manifest, not as a -cp argument.
You can find more about this here and here.
PS: -cp and -classpath are synonyms.
When using java -cp you are required to provide fully qualified main class name, e.g.
java -cp com.mycompany.MyMain
When using java -jar myjar.jar your jar file must provide the information about main class via manifest.mf contained into the jar file in folder META-INF:
Main-Class: com.mycompany.MyMain
java -cp CLASSPATH is necesssary if you wish to specify all code in the classpath. This is useful for debugging code.
The jarred executable format: java -jar JarFile can be used if you wish to start the app with a single short command. You can specify additional dependent jar files in your MANIFEST using space separated jars in a Class-Path entry, e.g.:
Class-Path: mysql.jar infobus.jar acme/beans.jar
Both are comparable in terms of performance.
Like already said, the -cp is just for telling the jvm in the command line which class to use for the main thread and where it can find the libraries (define classpath). In -jar it expects the class-path and main-class to be defined in the jar file manifest. So other is for defining things in command line while other finding them inside the jar manifest. There is no difference in performance. You can't use them at the same time, -jar will override the -cp.
Though even if you use -cp, it will still check the manifest file. So you can define some of the class-paths in the manifest and some in the command line. This is particularly useful when you have a dependency on some 3rd party jar, which you might not provide with your build or don't want to provide (expecting it to be found already in the system where it's to be installed for example). So you can use it to provide external jars. It's location may vary between systems or it may even have a different version on different system (but having the same interfaces). This way you can build the app with other version and add the actual 3rd party dependency to class-path on the command line when running it on different systems.
There won't be any difference in terms of performance.
Using java - cp we can specify the required classes and jar's in the classpath for running a java class file.
If it is a executable jar file . When java -jar command is used, jvm finds the class that it needs to run from /META-INF/MANIFEST.MF file inside the jar file.

Categories

Resources