Let's say I have:
core.jar
client.jar (contains main-method) (uses core.jar)
super_mega_client.jar (uses core.jar, client.jar)
To run my program I use "java -jar super_mega_client.jar"
How could I get the manifest-file from "super_mega_client.jar" knowing nothing about it's name and content?
Actualy I need to create an util in core.jar which will work with the jar, executed with "java -jar ***.jar"
OK, here is proper question:
I have main.jar with main-method (lets say in my.app.Main class)
I also have fisrt.jar(with some classes and resources) and second.jar (with some other classes and resources). Both have no main-classes, both have "main.jar" in CLASSPATH, both have Main-Class property defined as "my.app.Main".
I can run my app by executing "java -jar first.jar" or "java -jar second.jar"
In my my.app.Main.main(String[] args) method (contained in main.jar) I want to know the name of the executed jar (I want to get either "first.jar" or "second.jar")
How could I do it?
In any jar that declares its main class, the location and name is fixed by the standard to META-INF/MANIFEST.MF
You can retrieve the manifest file using the jar command that comes with the Java SDK (any zip tool that you can run from the command might suffice too) by running:
jar -xvf anyjar.jar META-INF/MANIFEST.MF
this will create the META-INF directory and put the manifest file in it. You can leave out the -v if you want less verbose output.
Not quite sure I understand what you need here, but check out this article (for instance)
http://java.sun.com/j2se/1.5.0/docs/guide/lang/resources.html
You ask the CLASSLOADER (so use a class you have loaded already and request what classloader it used is probably good enough) to load the resource for you.
You can use the -verbose option of the java command to see the names of all loaded classes.
Related
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.
I am relatively new to Java but have a fair understanding about how the class path works with respect to providing a list of folder and jars that make classes available to other classes.
I have compiled a JAR (lets say example.jar) that has a main function where execution normally begins. Sometimes I want execution to begin in a different class (lets say myAlternateClass.java), with its own main. I can achieve this by doing using the -cp argument when executing the jar, for example;
java -cp example.jar myAlternateClass
This works as I require but I am unsure of what exactly is happening here.
I'm not 100% sure on exactly what you're looking for, but I'll give it a shot.
There are two ways to use a jar file. If the jar file has a Main-Class specified in its META-INF/MANIFEST.MF file, then you can load java with the jar file and execution will start in the main method of that class.
java -jar example.jar
On the other hand, a jar file can simply be loaded onto the classpath, which makes all of the classes within it available for use. This is the example you are giving:
java -cp example.jar org.somewhere.MySecondClass
The -cp example.jar puts all of the classes within the jar on the class path and the second argument org.somewhere.MySecondClass gives the class at which execution should begin. This second argument would have to be within the jar since specifying a classpath overrides the default (which is just the current directory). In this case, java ignores any Main-Class specified in the MANIFEST.MF file of the jar (if one even is specified).
Multiple jar files as well as directories of java files not in a jar can be specified by putting colons between them. So,
java -jar example.jar:. MyClass
could launch MyClass from the current directory, but place example.jar on the classpath so that MyClass could create instances of whatever classes are available within example.jar.
Is there a way to pass an external jar file when running a .jar application?
I'm trying to run my jar like this:
java -jar myJar.jar -cp externalJar.jar
The jar file executes fine but I want to look for classes in the external file. I can't include the other classes into my jar, because I want to be able to put any jar file in the same folder as my Jar file and look for classes in there.
The only way to do this right now is by running my app like this:
java -cp myJar.jar;externalJar.jar MainClass
I do not want to explicitly enter the path to my MainClass to run it's main method.
It really seems that the -cp option is completely ignored when you use the -jar option. At least this is what you can read on the manpage of java about the -jar option:
Execute a program encapsulated in a JAR file. The first argument is
the name of a JAR file instead of a startup class name. In order for
this option to work, the manifest of the JAR file must contain a line
of the form Main-Class: classname. Here, classname identifies the
class having the public static void main(String[] args) method that
serves as your application's starting point. See the Jar tool
reference page and the Jar trail of the Java Tutorial for information
about working with Jar files and Jar-file manifests.
When you use this option, the JAR file is the source of all user classes, and other user
class path settings are ignored.
Note that JAR files that can be run with the "java -jar" option can
have their execute permissions set so they can be run without using
"java -jar". Refer to Java Archive (JAR) Files.
I found this in this blogpost here: http://happygiraffe.net/blog/2009/04/30/java-jar-blats-your-classpath/
Did you try adding a specific folder to the classpath during startup and then add your jar file to the folder at later point ?
I have created an executable jar file that contains two main classes. All libraries are included in the jar and the main Main-Class works fine when executing like this:
java -jar MyApplication.jar
But when I try to run the other main class like this:
java -cp MyApplication.jar my.other.mainClass
It does not include the classpath of the manifest.mf and it can not find the libraries that are in the jar file.
Is there a simple way so that the other main class can use the classpath from the manifest.mf? or should I create two separate executable jars?
You could write a class that invokes the main method of whatever class is passed as its first argument using Reflection - and configure this as the Main-class in your jar. This way you can invoke multiple main methods from the same jar with java -jar file.jar my.other.mainClass
Is there a simple way so that the other main class can use the classpath from the manifest.mf? or should I create two separate executable jars?
The JAR manifest classpath is only used if you use -jar option, and conversely the command line argument is only interpreted as a classname if -jar is NOT used. You cannot mix the two approaches.
However, this doesn't mean you have to create a second JAR file. For instance, you could write a simple shell script to launch the JVM using the classpath copied from the manifest and the secondary entry point classname.
Are you sure your problem is with libraries within the jar? What version of java are you using?
I suggest you try the following:
java -cp MyApplication.jar <add external libraries here> my.other.mainClass
So you only need to add paths to classes that are not already in the jar. You can use wild cards to shorten the list.
Here is another interesting option, Enable your unrunnable JARs to run with the java -jar command. It describes how to select a main class in the jar file and make another runnable copy.
I'm having a little trouble running some Java code, which requires three .jar files to be used. I'm at a lost as to what to do with them--I've tried setting the CLASSPATH (and following the instructions for how to do so in the readme files), but to no avail.
I was wondering if someone could walk me through it? I'd imagine three .jar files would be an easy install for someone who knows what they're doing.
If it helps, I'm using Ubuntu pretty much right out of the box (but I do have JDK and Eclipse installed!)
Runtime library: http://cogcomp.cs.illinois.edu/download/software/20
Additional .jar needed: http://cogcomp.cs.illinois.edu/download/software/23
Program I ultimately need to run: http://cogcomp.cs.illinois.edu/download/software/26
If you're willing to help, I can't thank you enough--you deserve a million kudos!
G
Those are all JAR files. When you execute a JAR file by doubleclicking or using java -jar, the CLASSPATH environment variable and the -cp and -classpath arguments are ignored. The classpath should be defninied in META-INF/MANIFEST.MF file of the JAR. In this particular case, only the second and third JAR have a Class-Path entry in the manifest file:
Class-Path: LBJ2Library.jar
Which is the first JAR. The classpath is telling that it is expecting the LBJ2Library.jar to be in the same folder as the JAR you'd like to execute (either the second or third one).
So, just drop them all in the same folder and execute by java -jar LBJPOS.jar.
If you are using java -jar to run your jar files, then the CLASSPATH variable is ignored. If you are using java -jar, you have two options:
Combine the three jars into one jar.
Run the main class directory and don't use -jar.
Use of the CLASSPATH environment variable is generally discouraged nowadays. This is how it's done (on Linux):
java -cp library1.jar:library2.jar:mainapp.jar <fully qualified name of main class>
You need to set the CLASSPATH .place all the 3 jars in a folder , name it as lib
See below to set classpath
set CLASSPATH=%CLASSPATH%:lib;