MrJman006
MrJman006

Reputation: 770

Java ClassLoader Not Finding Expected Resource

I have a jar file that contains the following:

LibJar Contents

dir1
   |dir1-1
   |     |Class1-1-1
   |     |LClass1-1-2
   |Ldir1-2
         |LClass1-2-1
Ldir2
   |LClass2-1

My java program (we can call it ProgJar, but I also run it in Netbeans IDE) has the following package structure:

ProgJar

dir1
   |dir1-1
   |     |Class-1-1
   |     |PClass1-1-2        Different file name from LibJar
Pdir2
   |PClass2-1

The only shared package structure between ProgJar and LibJar is "dir1/dir1-1/Class1-1-1". Everything else prefixed with a P is unique to ProgJar and everything prefixed with a L is unique to LibJar.

I use LibJar as a library in ProgJar.

This is the snippet of code I run in ProjJar:

ClassLoader clP = Pdir2.PClass2-1.class.getClassLoader();
ClassLoader clL = Ldir2.LClass2-1.class.getClassLoader();

URL u1 = clP.getResource("dir1/dir1-1");
URL u2 = clL.getResource("dir1/dir1-1");

System.out.printf(u1.toExternalForm());
System.out.printf(u2.toExternalForm());

When I run this in Netbeans I get the following output:

Netbeans Output:
jar:file:/C:/path/to/project/lib/LibJar.jar!/dir1/dir1-1
jar:file:/C:/path/to/project/lib/LibJar.jar!/dir1/dir1-1

When I run as a ProgJar as a built jar outside of netbeans, I get:

Jar Output:
jar:file:/C:/path/to/ProgJar/ProgJar.jar!/dir1/dir1-1
jar:file:/C:/path/to/ProgJar/ProgJar.jar!/dir1/dir1-1

What I expect to see is the following:

Netbeans Output:
jar:file:/C:/path/to/project/build/classes/dir1/dir1-1
jar:file:/C:/path/to/project/lib/LibJar.jar!/dir1/dir1-1

Jar Output:
jar:file:/C:/path/to/ProgJar/ProgJar.jar!/dir1/dir1-1
jar:file:/C:/path/to/ProgJar/libs/LibJar.jar!/dir1/dir1-1

I read through a few different articles, but this one seems somewhat relevant to this particular issue:

http://jeewanthad.blogspot.com/2014/02/how-to-solve-java-classpath-hell-with.html

How am I able to achieve my specified output?

Upvotes: 0

Views: 227

Answers (1)

Darshan
Darshan

Reputation: 2333

Below code is not doing what you are expecting it to do:

ClassLoader clP = Pdir2.PClass2-1.class.getClassLoader();
ClassLoader clL = Ldir2.LClass2-1.class.getClassLoader();

Here clP amd clL are same Classloader instances(you system/application classloader to be specific).To verify, just see (clP == clL) should return true.

What you want to do is, use a custom classloader(URLClassLoader should do) to load your library. Then, the system classloader that loaded your ProgJar and your custom classloader will be different. Then rest of your code should work as expected.

Upvotes: 1

Related Questions