运行Ant taskdef时有多个类路径?

时间:2018-12-10 19:32:27

标签: java jar ant classpath

我有一个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目录包含几个jars

  • A.jar-我的图书馆
  • B.jar-第三方库
  • C.jar-第三方库,与B.Jar不同。

这些罐子都很好地加载到了类路径$ {ant.classpath}中。

工作流程如下: A.jar叫B.jar,而B.jar叫C.jar。

因此,A.jar调用B.jar中的类没有问题。它使用JAVA中的import语句来调用这些类:

import B.SomeClass;

这很好用。

但是,B.jar调用C.jar并失败。

我能够检查两个第三方库的源代码,并了解到B.jar使用Java的Classloader类从C.jar调用了类。它不使用导入语句。

下面是来自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.jar中确实存在C.SomeClass。

我怀疑它正在加载与ant taskdef提供的类路径不同的类路径。当我尝试使用ClassLoader从我的库(A.jar)中加载C.jar类时,出现了相同的异常。但是导入效果很好。

我不知所措,因为我无法让B.jar通过Ant正确加载C.jar。

编辑:

如果有用,我正在使用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 :(得分:0)

因此,我在A.jar中弄乱了,并了解到getClass()。getClassLoader()和Thread.currentThread()。getContextClassLoader()返回不同的东西。 getClass()。getClassLoader()包含我在ANT脚本中设置的ANT类路径,而Thread类加载器则没有。

由于它是第三方库,因此我无法更改B.jar中的代码,但是,我可以使用以下代码在我的代码中设置线程的类加载器:

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

我在代码调用B.jar和C.jar之前将其放入代码中。效果很好!

相关问题