Reputation: 98
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.
Upvotes: 5
Views: 3018
Reputation: 22969
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
Upvotes: 2
Reputation: 1204
Your manifest
file is seem to be wrong. You have Main-Class: exe.myMain
=> java but have type of exe? Recommend for you is you should using eclipse to export your jar file it will auto create all things for you, you don't have to manually create manifest file so you can make mistake. See the detail as follow:
I have tested by created a java project with eclipse => using export function of eclipse to export a runnable JAR => using the 3rd option (copy required libraries into a sub-folder...). After exported I got the jar with name myJarName.jar
and a folder with name myJarName_lib
. Open the jar with 7zip
program => under the META-INF
=> open the MANIFEST.MF
=> and here is the structure of it:
Manifest-Version: 1.0
Class-Path: . myJarName_lib/gson-2.8.0.jar myJarName_lib/jsoup-1.8.3.jar myJarName_lib/commons-cli-1.2.jar myJarName_lib/jackson-core-2.8.8.jar
Main-Class: upwork.Main
Upvotes: 0