Несколько путей к классам при запуске Ant taskdef? - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть скрипт ANT, который вызывает класс Java 11 с использованием пользовательского пути к классу

<path id="ant.classpath">
        <fileset dir="${basedir}/lib/ant">
            <include name="*.jar" />
        </fileset>
</path>

<taskdef name="myTaskDef" classname="A.SomeClass" classpathref="ant.classpath" />

Каталог $ {basedir} / lib / ant содержит несколько jar

  • A.jar - Моя библиотека
  • B.jar - Сторонняя библиотека
  • C.jar - Сторонняя библиотека, отличная от B.Jar

Этивсе jars загружаются в classpath $ {ant.classpath} просто отлично.

Рабочий процесс выглядит следующим образом: A.jar вызывает B.jar, а B.jar вызывает C.jar.

Итак, A.jar называет классы в B.jar без проблем.Он использует оператор импорта в JAVA для вызова классов:

import B.SomeClass;

Это прекрасно работает.

Однако B.jar вызывает C.jar, и это не удается.

Я смог проверить исходный код обеих сторонних библиотек и узнал, что B.jar вызывает классы из C.jar, используя класс Classloader в Java.Он не использует оператор импорта.

Ниже приведен код из класса внутри B.jar

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
....
classLoader.loadClass("C.SomeClass");

Исключение, которое я получаю:

java.lang.ClassNotFoundException: C.SomeClass
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at B.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:122)

Мне удалось проверить, что C.SomeClass существует в C.jar.

Я подозреваю, что он загружает путь к другому классу, чем тот, который предоставляется ant taskdef.Когда я пытаюсь загрузить класс C.jar из моей библиотеки (A.jar) с помощью ClassLoader, я получаю то же исключение.Но импорт работает просто отлично.

Я немного растерялся из-за того, что делать, потому что не могу заставить B.jar правильно загрузить C.jar через Ant.

EDIT:

В случае, если это полезно, я использую Java 11, и B.jar действительно является jaxb-api-2.4.0.jar (javax.xml.bind), а C.jar является jaxb-runtime-2.4.0.jar (com.sun.xml.bind) плюс его зависимости (jaxb-core, stax-ex, txw2 и т. Д.).Я получаю ClassNotFoundException, когда я вызываю:

JAXBContext jc = JAXBContext.newInstance(Feature.class);

И он не может найти класс com.sun.xml.bind.v2.ContextFactory, который, как я подтвердил, действительно существует.

1 Ответ

0 голосов
/ 11 декабря 2018

Итак, я возился с A.jar и узнал, что getClass (). GetClassLoader () и Thread.currentThread (). GetContextClassLoader () возвращают разные вещи.GetClass (). GetClassLoader () содержит путь к классу ANT, который я установил в сценарии ANT, а загрузчик классов Thread - нет.

Я не могу изменить код в B.jar, поскольку он стороннийОднако в библиотеке я смог установить загрузчик классов Thread в своем коде, используя следующее:

ClassLoader cl = this.getClass().getClassLoader();
Thread.currentThread().setContextClassLoader(cl);

Я поместил это в код прямо перед тем, как мой код вызывает B.jar, а затем C.jar.Работало отлично!

...