First post, so sorry for my poor formatting. I have a java program that I developed in eclipse. I exported the program as a jar (myJar.jar), and then I put all of the external jars that my program depends on into a folder called lib that lives in the same location as myJar.jar. In order to set my classpath I have a manifest file with the following format:
Main-Class: exe.myMain
Class-Path: lib/jar_1.jar lib/jar_2.jar ... lib/jar_n.jar
Manifest-Version: 1.0
However, when I attempt to run the program using "java -jar myJar.jar" the classes from the jars that live in lib are not being loaded (I'm getting a ClassNotFoundException) . I used the following code in my program to print the classpath:
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url:urls){
System.out.println(url.getFile());
}
And when I run this code the classpath is simply "myJar.jar".
I have two questions:
1.) Does the above code actually give me the classpath for the JRE at run time, or am I simply being given the address of my main class?
2.) Given the above code does indeed give me the classpath for the JRE at run time, am I doing anything wrong?
Please feel free to ask for more information, and I will happily provide what you need.
What you are doing sounds correct.
For some reason the Class-Path
entry in the manifest does not show up when inspecting the classpath (e.g. here and here; those examples use the property "java.class.path"
but my testing shows that ClassLoader.getURLs()
behaves the same). It should still get searched for classes though. I don't know how to obtain the true classpath that includes the Class-Path
entry from the manifest.
The first thing I'd like to check is that the file META-INF/MANIFEST.MF
inside myJar.jar
matches the manifest that you created. You can open myJar.jar
by renaming it to have a .zip
file extension.
I tried to replicate your problem but the classes in lib/jar_1.jar
were loaded for me, so if META-INF/MANIFEST.MF
is correct I'll describe what I did in detail so you can find what we are doing differently.
Edit:
Here are the steps I used:
Create a new directory called "experiment". The following steps are all to be done in that directory.
Create new directories called "jar_1", "lib", and "exe"
Create a file called "ClassInJar1.java" in directory "jar_1" with the following content:
package jar_1;
public class ClassInJar1 {
public static void method() {
System.out.println("Hello from ClassInJar1");
}
}
Run javac jar_1/ClassInJar1.java
Run jar cf lib/jar_1.jar jar_1/ClassInJar1.class
Create a file called "myMain.java" in directory "exe" with the following content:
package exe;
import java.net.*;
import jar_1.ClassInJar1;
public class myMain {
public static void main(String[] args) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
System.out.println(url.getFile());
}
ClassInJar1.method();
}
}
Run javac exe/myMain.java
Create a file called "manifest" in the "experiment" directory with the following content:
Main-Class: exe.myMain
Class-Path: lib/jar_1.jar lib/jar_2.jar
Manifest-Version: 1.0
Run jar cfm myJar.jar manifest exe/myMain.class
Run java -jar myJar.jar
Output:
/.../experiment/myJar.jar
Hello from ClassInJar1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With