Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java ignoring Class-Path entry in jar file's manifest

I have searched the internet and I have searched stackoverflow and found many many posts asking this question, yet there isn't ever a concrete answer.


The short version is: I have a jar file which references other jar files in the manifest. I then run the jar file with java -jar test.jar, but it doesn't add the jar dependencies to the classpath.


Long version: I made a little experiment in order to confirm that it wasn't something special about my project. I created a simple Java Project in eclipse, with only 1 class. All this class does is write the classpath to std-out:

package test;

import java.net.URL;
import java.net.URLClassLoader;

public class Test {
  public static void main(String[] args){
    ClassLoader cl = ClassLoader.getSystemClassLoader();
    URL[] urls = ((URLClassLoader)cl).getURLs();
    for(URL url: urls){
      System.out.println("CP: "+url.getFile());
    }
  }
}

Then I created a "lib" folder and put a random jar file inside and added it to the classpath. The folder structure now looks like this:

Test
|- src/test/Test.java
|- lib/mysql-connector-java-3.1.14-bin.jar

Now when I run it from Eclipse I get the following output:

CP: /home/username/workspace/Test/bin/
CP: /home/username/workspace/Test/lib/mysql-connector-java-3.1.14-bin.jar

Ok, now I use Eclipse to export the project to a runnable jar. I choose the option "Copy required libraries into sub-folder next to the generated jar".

This creates the following structure:

/tmp/Test
|- test.jar
|- test_lib/mysql-connector-java-3.1.14-bin.jar

If I look into the Test.jar that was created by Eclipse, it looks like this:

test.jar
|- test/Test.class
|- META-INF/MANIFEST.MF

The contents of the MANIFEST.MF are:

Manifest-Version: 1.0
Class-Path: . test_lib/mysql-connector-java-3.1.14-bin.jar
Main-Class: test.Test

And yes, there is an empty line after the Main-Class attribute (I mention this because some people posted online that the cause could be a missing newline at the end).

So, everything looks fine. I run it with java -jar test.jar and get the following output:

CP: /tmp/Test/test.jar

So the classpath contains only the jar file that I want to run. The Class-Path: attribute in the MANIFEST is completely ignored. The same thing happens if I run it with java -cp test.jar test.Test

How does one use the Class-Path attribute in the MANIFEST.MF properly? I can't figure it out for the life of me. Especially since -cp and -jar are not compatible, I don't know how I could specify the classpath while also using the -jar argument.

Thanks a lot in advance.


A few more things I can answer in advance:

  • "Is there a line break after the last line?" - Yes
  • "Could it be eclipse malforms the MANIFEST.MF?" - Could be, but I have the same problem when I make the jar with ant. So if both eclipse and ant malform the manifest, I don't know how I should format it.
  • "What platforms, Java versions have you tried?" - I tried Java8 on Windows 10, as well as Java6, Java7 and Java8 on Fedora Linux.
like image 247
RHS Avatar asked Nov 10 '22 06:11

RHS


1 Answers

Ok, thanks to JB Nizet's comment I figured out that everything is working fine. It doesn't print out the classpath but I can access the classes from the library. So my experiment was set up wrong. This is bad news for me, as my other project still doesn't work, and it is too complex to post here.

like image 78
RHS Avatar answered Nov 14 '22 23:11

RHS