8

I'm trying to set a jar manifest so it loads all the libraries (jars) within a folder next to the jar.

The manifest looks like this:

Manifest-Version: 1.0
Class-Path: libs/
Main-Class: path.to.my.class.Main

The layout is as follows:

- MyJar.jar
- libs/
-----lib1.jar
-----lib2.jar

And I'm trying to run like this:

java -jar MyJar.jar

And I get NoClassDefinition errors about classes in the jar within the folder.

In case someone is curious, this folder might contain optional jars that are processed during class loading. That' swhy I can't use the hardcoded or autogenerated ones.

Any idea?

Update Rephrased the question as this is not currently possible from the manifest itself. The answer was the only really viable without the need of extracting the jars, although it also works.

So as a summary the answer is no, this can't be done from manifest file alone if you have unespecified dependencies.

javydreamercsw
  • 5,363
  • 13
  • 61
  • 106
  • AFIK JAR's classpath starts at the root of the `JAR` file. You can't put classes or JARs in sub directories unless you're going to load them dynamically like `Spring Boot` or `OSGI` containers. – 11thdimension Oct 03 '16 at 20:32
  • Turns out, it can be done, you have to specify path with the JAR name. Check this link http://todayguesswhat.blogspot.com/2011/03/jar-manifestmf-class-path-referencing.html?_sm_au_=ivVTSRf571T1SvZP – 11thdimension Oct 03 '16 at 20:45
  • I ran across that link earlier and my manifest above is based on that but it doesn't work. It only finds the files within that folder that are defined in the classpath. The folder alone doesn't seem to work. (i.e. libs/ or ./libs/) – javydreamercsw Oct 03 '16 at 21:01
  • According to the link `Class-Path: ./libs/lib1.jar` should work. – 11thdimension Oct 03 '16 at 21:03
  • Yes it does, but I don't know the dependencies before hand. I would like to use all jars in there without the need of knowing before hand. Is for a plugin system. – javydreamercsw Oct 03 '16 at 21:05

3 Answers3

2

You should define your Manifest classpath as

Class-Path: libs/lib1.jar libs/lib2.jar

See Oracle documentation for more details https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html

Issam El-atif
  • 2,366
  • 2
  • 17
  • 22
1

Try extracting these jars. It looks like you cannot add all jars from directory but you can add all classes. You lose obviously all configuration in manifest, however, if you are interested in jars' code content only, it might work.

I tested that with these simple classes

import pkg.B;

public class A {
  public static void main(String[] args) {
    System.out.println(B.class.getName());
  }
}

package pkg;

public class B {}

now I try to separate the classes. I have jarred them into

$ jar tf libA.jar 
META-INF/
META-INF/MANIFEST.MF
A.class
$ jar tf libB.jar 
META-INF/
META-INF/MANIFEST.MF
pkg/B.class

no Class-Path in any manifest. I can run A with java -cp libB.jar:libA.jar A. Now I create another jar with Class-Path set to lib/

$ cat manifest 
Class-Path: lib/
$ jar cfm empty.jar manifest

my directory tree look like

$ ls -R
.:
A.java  empty.jar  lib  lib.jar  manifest  pkg

./lib:
libA.jar  libB.jar

./pkg:
B.java

Now I try jar

$ java -jar empty.jar 
Error: Could not find or load main class A

Hopeless, right? Then I extracted libA.jar and libB.jar into lib (same as [this guy][2]). Now all is fine

$ java -jar empty.jar 
pkg.B
lord.didger
  • 1,357
  • 1
  • 17
  • 31
  • This just won't work for my scenario as non-technical users won't be able to do this. Asking them to put jars in a directory is hard enough. Thanks – javydreamercsw Oct 04 '16 at 18:08
-1

java does not know the jar files in the libs directory. If you are using java 1.6+, You can run program as

java -cp lib/* -jar MyJar.jar

kevin
  • 570
  • 4
  • 22