当前位置: 首页 > 知识库问答 >
问题:

运行蚂蚁taskdef时的多个类路径?

葛晔
2023-03-14

我有一个ANT脚本,它使用自定义类路径调用Java11类

<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-我的图书馆

这些jars都可以很好地加载到类路径${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调用类。它不使用import语句。

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

我怀疑它加载的类路径不同于ant taskdef提供的类路径。当我试图使用ClassLoader从我的库(A. jar)中加载C. jar类时,我得到了同样的异常。但是导入工作正常。

我有点不知所措,因为我不能让B. jar通过ant正确加载C. jar。

编辑:

如果有用的话,我使用的是Java11,而B.jar实际上是jaxb-api-2.4.0。jar(javax.xml.bind)和C.jar是jaxb-runtime-2.4.0。jar(com.sun.xml.bind)及其依赖项(jaxb核心、stax ex、txw2等)。当我调用时,我得到ClassNotFoundException:

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

它找不到com类。太阳xml。绑定v2。ContextFactory,我已经确认它确实存在。

共有1个答案

谢英光
2023-03-14

所以,我在A. jar中乱搞,了解到getClass()。getClassLoader()和Thread.currentThread()。getContextClassLoader()返回不同的东西。getClass()。getClassLoader()包含我在ANT脚本中设置的ANT类路径,线程类加载器不包含。

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

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

在我的代码调用B.jar,然后调用C.jar之前,我将其放入代码中。它工作得很好!

 类似资料:
  • 我不熟悉蚂蚁脚本。 以下是需求描述 在我的工作区中,有各种各样的项目,我必须在RAD和eclipse IDE以及Websphere、tomcat和jboss环境中进行项目工作。。我已经做了特定于项目的设置,以使项目在RAD、websphere、eclipse和tomcat n jboss上工作。。 但是在一些文件中有一些变化,比如classpath n和一些配置文件。 这就给我留下了三个版本的工作

  • 问题内容: 我有一个带命令的Apache Ant构建文件,该命令要求在构建中有四个特定的JAR 。我试图做到这一点: …但其中没有显示任何文件。如何在我的类路径中包含这些文件? 问题答案: 这是我当前正在从事的项目的示例。我怀疑您可以对其进行修改以适合您的情况。

  • 问题内容: 我必须 在ant中执行command:所以我尝试了这个任务: 但是我对管道有个异议-“ |” : 所以,这就是问题所在:) 问题答案: 管道(|)仅可用于Shell脚本。您将其作为参数传递给Java进程。 因此,您需要执行一个Shell脚本。您可以通过执行(说)并将上面的内容作为shell语句传递来做到这一点(尽管是 内联的 ,您可以编写一个单独的脚本文件,但这似乎有点麻烦)

  • 问题内容: 在定义顺序构建步骤时,我使用元素的属性。我最近看到了一个ant文件,其中的构建顺序是由目标内部的元素定义的。为了显示 : 与 两种方法之间是否有真正的区别?是其中之一更可取吗? 问题答案: 与这两种方法的主要区别在于目标是 始终 执行,而在目标只有在包含目标是执行。 一个澄清的例子: 在这里,将始终执行,而只有在定义时才会执行。 在此,仅当is即定义时才执行。

  • 我下载了最新版本的Eclipse(Mars),并在Eclipse中将所需的Java版本更改为1.6。ini文件,因为我的项目使用Java 1.6。 我将Eclipse中安装的JRE配置为使用Java 1.6。但当我尝试执行ant目标时,它会产生一个错误: 不支持低于1.7的JRE版本。 由于我目前无法升级到Java 1.7,在Mars版本中使用Java 1.6有什么解决方法吗?

  • 各位, 在Ant(Jenkins)中构建我们的Android应用程序时,我们遇到了一个属性范围问题。这打破了我们的emma单元测试覆盖率。 我们使用全局构建。xml文件,包含以下行: 如您所见,它在单个项目中启动目标。我们使用构建。 在构建过程中,我打印emma的值。已启用,由emma目标设置为true。然而,当Ant达到调试目标时,emma。已启用的不再设置。这导致我们的测试在没有启用emma覆