run a java program using -cp option and classpath in manifest file - java

I plan to run a java class like
java -cp myjar.jar MyClass
myjar.jar will have a manifest file with classpath entry in it.
Is it a valid use case? I have a doubt since I have only seen usage of manifest when using java -jar myjar.jar

You cannot use -cp (or the CLASSPATH enviromment variable) together with -jar. If you need to specify a classpath to make an executable JAR file work, you can specify a Class-Path attribute in the JAR file's manifest.
On the other hand, the Class-Path attribute in a JAR file manifest is only used for classes loaded from the JAR file itself. (But it is not restricted to use with -jar option.)
For more details, refer to the JAR file specification and How classes are found.

Related

java -cp option seems not to work in Java 14 (Preview Enabled) [duplicate]

I've compiled a JAR file and specified the Main-Class in the manifest (I used the Eclipse Export function). My dependencies are all in a directory labeled lib. I can't seem to get a straight answer on how to execute my JAR file while specifying it should use the lib/* as the classpath.
I've tried:
]$ java -jar -cp .:lib/* MyJar.jar
]$ java -cp .:lib/* -jar MyJar.jar
]$ java -cp .:lib/* com.somepackage.subpackage.Main
etc...
Each gives an error saying:
Error: Could not find or load main class ....
or gives the NoClassDefFoundError indicating the libraries are not being found.
I even tried remaking the JAR file and included the lib directory and contents, but still no dice...
How can I execute a JAR file from the command line and specify the classpath to use?
When you specify -jar then the -cp parameter will be ignored.
From the documentation:
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
You also cannot "include" needed jar files into another jar file (you would need to extract their contents and put the .class files into your jar file)
You have two options:
include all jar files from the lib directory into the manifest (you can use relative paths there)
Specify everything (including your jar) on the commandline using -cp:
java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main
Run a jar file and specify a class path like this:
java -cp <jar_name.jar:libs/*> com.test.App
jar_name.jar is the full name of the JAR you want to execute
libs/* is a path to your dependency JARs
com.test.App is the fully qualified name of the class from the JAR that has the main(String[]) method
The jar and dependent jar should have execute permissions.
You can do these in unix shell:
java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main
You can do these in windows powershell:
java -cp "MyJar.jar;lib\*" com.somepackage.subpackage.Main
Alternatively, use the manifest to specify the class-path and main-class if you like, so then you don't need to use -cp or specify the main class. In your case it would contain lines like this:
Main-Class: com.test.App
Class-Path: lib/one.jar lib/two.jar
Unfortunately you need to spell out each jar in the manifest (not a biggie as you only do once, and you can use a script to build the file or use a build tool like ANT or Maven or Gradle). And the reference has to be a relative or absolute directory to where you run the java -jar MyJar.jar.
Then execute it with
java -jar MyJar.jar
You can do a Runtime.getRuntime.exec(command) to relaunch the jar including classpath with args.

Run a JAR file from the command line and specify classpath

I've compiled a JAR file and specified the Main-Class in the manifest (I used the Eclipse Export function). My dependencies are all in a directory labeled lib. I can't seem to get a straight answer on how to execute my JAR file while specifying it should use the lib/* as the classpath.
I've tried:
]$ java -jar -cp .:lib/* MyJar.jar
]$ java -cp .:lib/* -jar MyJar.jar
]$ java -cp .:lib/* com.somepackage.subpackage.Main
etc...
Each gives an error saying:
Error: Could not find or load main class ....
or gives the NoClassDefFoundError indicating the libraries are not being found.
I even tried remaking the JAR file and included the lib directory and contents, but still no dice...
How can I execute a JAR file from the command line and specify the classpath to use?
When you specify -jar then the -cp parameter will be ignored.
From the documentation:
When you use this option, the JAR file is the source of all user classes, and other user class path settings are ignored.
You also cannot "include" needed jar files into another jar file (you would need to extract their contents and put the .class files into your jar file)
You have two options:
include all jar files from the lib directory into the manifest (you can use relative paths there)
Specify everything (including your jar) on the commandline using -cp:
java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main
Run a jar file and specify a class path like this:
java -cp <jar_name.jar:libs/*> com.test.App
jar_name.jar is the full name of the JAR you want to execute
libs/* is a path to your dependency JARs
com.test.App is the fully qualified name of the class from the JAR that has the main(String[]) method
The jar and dependent jar should have execute permissions.
You can do these in unix shell:
java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main
You can do these in windows powershell:
java -cp "MyJar.jar;lib\*" com.somepackage.subpackage.Main
Alternatively, use the manifest to specify the class-path and main-class if you like, so then you don't need to use -cp or specify the main class. In your case it would contain lines like this:
Main-Class: com.test.App
Class-Path: lib/one.jar lib/two.jar
Unfortunately you need to spell out each jar in the manifest (not a biggie as you only do once, and you can use a script to build the file or use a build tool like ANT or Maven or Gradle). And the reference has to be a relative or absolute directory to where you run the java -jar MyJar.jar.
Then execute it with
java -jar MyJar.jar
You can do a Runtime.getRuntime.exec(command) to relaunch the jar including classpath with args.

Does java -jar option alter classpath options

I have a jar file which mentions the main class in the manifest.
When I try to execute the jar using the following command
java -cp .;./* com.foo.MainClass
The code executes and works.
When I try to execute the jar using the following command
java -cp .;./* -jar myjar.jar
I get class not found execptions for some jars which are in the same folder as myjar.jar. I hoping that the -cp option will include those jars in class path.
I modified my code to print java.class.path property. In the first case it listed all jars in the current directory, in second case it just listed myjar.jar
I also modified the manifest to add Class-Path element to it with all jars. Then the second command works. But in my code I am trying to load a aribtrary class whose name is provided at command prompt, so I want the class path to contain all jars in a folder. How do I make the second command work in this scenario?
From this,
An executable JAR must reference all the other dependent JARs it
requires through the Class-Path header of the manifest file. The
environment variable CLASSPATH and any class path specified on the
command line is ignored by the JVM if the -jar option is used.
You will need your own classloader to deal with this. -jar only respects the information in the Manifest and wildcards are not allowed there.
You might find the example of a reloadable class useful: http://www.exampledepot.com/egs/java.lang/ReloadClass.html
Here is a good discussion on this issue.

In Linux, how to execute Java jar file with external jar files?

In Linux, how to execute Java jar file with external jar files?
Either use the -cp flag:
java -cp /path/to/somefolder/*.jar:/path/to/otherfolder/*.jar com.YourMainClass
Or add a Class-Path: header to your jar's manifest (see Jigar's answer)
Note to others who answered with java -jar <etc>: The -jar flag deactivates the standard -cp flag and CLASSPATH environment variable, because it retrieves the classpath from the JAR manifest. Any answer that combines -jar and either -cp or $CLASSPATH will not work.
This information is well-hidden, but I finally found a reference:
-jar
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.
Source: java - the Java application launcher
java -jar /path/to/externalJarFile.jar
Update
You can add the required library in manifest with Class-Path: header
For example :
Class-Path: MyUtils.jar
See
Adding Classes to the JAR File's Classpath

failed to load main-class manifest attribute from abc.jar

HI,
I have created a runnable .jar file using eclipse and compiled it with jdk1.4.2, i am able to run it perfectly on windows but whenever i run it on unix it says "failed to load main-class manifest attribute from abc.jar" Why is it so
Please help
Saurabh
I usually avoid executable jars. Assuming, we have a class com.example.MyClass that has has main method, then the "executable jar"'s manifest (myapp.jar) needs the line
Main-Class: com.example.MyClass
Then you can start the application like this
java -jar myapp.jar
Apart from some classpath annoyances, this is pretty similiar to
java -cp myapp.jar com.example.MyClass
The "annoyance": if run the application with the -jar option, the classpath has to be defined in the manifest - it will ignore any CLASSPATH entry or -cp attribute. So if you have dependencies, you'll have to copy and paste them from the manifests classpath attribute to the -cp attribute:
java -cp myapp.jar;<other libs> com.example.MyClass

Categories