Java ClassLoader Не Находит Ожидаемый Ресурс

У меня есть файл jar, который содержит следующее:

LibJar Contents

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

Моя программа java (мы можем назвать ее ProgJar, но я также запускаю ее в IDE Netbeans) имеет следующую структуру пакетов:

ProgJar

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

Единственной общей структурой пакета между ProgJar и LibJar является «dir1/dir1-1/Class1-1-1». Все остальное с префиксом P уникально для ProgJar, а все с префиксом L уникально для LibJar.

Я использую LibJar как библиотеку в ProgJar.

Это фрагмент кода, который я запускаю в 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());

Когда я запускаю это в Netbeans, я получаю следующие выходные данные:

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

Когда я запускаю как ProgJar как встроенный jar за пределами netbeans, я получаю:

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

Я ожидаю увидеть следующее:

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

Я прочитал несколько разных статей, но эта, кажется, имеет отношение к этому конкретному вопросу:

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

Как я могу достигнуть моего определенного выхода?

1 ответ

  1. Ниже код не делает то, что вы ожидаете от него сделать:

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

    Здесь clP amd clL являются такими же экземплярами Classloader (вы system/application classloader должны быть конкретными).Чтобы проверить, просто см. (clP == clL)should return true.

    Чтобы загрузить библиотеку, необходимо использовать пользовательский загрузчик классов (URLClassLoader should do). Затем системный загрузчик классов, который загрузил ваш ProgJar, и пользовательский загрузчик классов будут отличаться. Затем остальная часть кода должна работать так, как ожидалось.