这个问题已经被问过几次了,但不是很令我满意。我对提出的解决方法并不真正感兴趣,但对如何做我真正想做的事情不感兴趣。
想要一个令人满意的解释,说明为什么这不可能,如果不可能的话,并且由于我建议自己提交一个修复程序,所以我想了解为什么看起来如此简单的事情没有被解决尝试过。
目前,要确保一组 jar 可用于 ant,必须应用以下方法之一:
- 添加到
CLASSPATH
环境变量 - 在文档中“不推荐” - 添加到
$ANT_HOME/lib
或~/.ant/lib
- 需要在构建环境中配置 - 在
ant
调用中设置-lib
参数
最后一个选项是我已经确定的首选选项,但它仍然需要调用构建的人进行一些干预(我在开发中的 ant
包装器脚本中捕获了它存储库)。
特别是我正在尝试调用 Schematron Ant应根据the documentation设置的任务像这样:
<taskdef name="schematron"
classname="com.schematron.ant.SchematronTask"
classpath="lib/ant-schematron.jar"/>
但是这对 saxon 具有传递依赖性,因此如果 CLASSPATH
上没有可用的 saxon.jar
,构建将失败:
java.lang.NoClassDefFoundError: net/sf/saxon/TransformerFactoryImpl
ant documentation itself继续建议它应该是 taskdef 本身获取这些额外的 CLASSPATH
条目,但我已经用 schematron ant-task 尝试了这个但没有成功。
关键问题是 schematron ant 任务是否应该支持这一点,或者 ant build.xml 是否可以在其自身内部配置其全局类路径?
这似乎是人们经常想做的事情,而且由于 ant 文档本身建议不要自己使用 CLASSPATH,我很惊讶在 build.xml 本身中没有其他选择!
最佳答案
这似乎是 Schematron 任务中的错误。 Ant 任务加载 Saxon XSLT 处理器的方式要求 Saxon 位于系统类路径上,即使任务本身位于辅助类加载器上也是如此。
乍一看this code in ValidatorFactory看起来足够明智:
private TransformerFactory _factory = TransformerFactoryImpl.newInstance();
(其中 TransformerFactoryImpl
是 Saxon 对 TransformerFactory
的实现),但实际上 TransformerFactoryImpl
并没有定义 newInstance()
方法,所以这是从 TransformerFactory
继承的 newInstance
,它将根据 javax.xml 的值查找合适的工厂。 transform.TransformerFactory
系统属性。 Ant 任务 does set this system property :
System.setProperty("javax.xml.transform.TransformerFactory",
"net.sf.saxon.TransformerFactoryImpl");
但 TransformerFactory.newInstance()
将在系统类加载器上查找此类,不一定在加载 schematron 任务的类加载器上查找。
修复方法是将 ValidatorFactory
行 120 简单地更改为
private TransformerFactory _factory = new TransformerFactoryImpl();
这将绕过所有动态查找并直接实例化正确的类。有了这个修复
<taskdef name="schematron"
classname="com.schematron.ant.SchematronTask"
classpath="lib/ant-schematron.jar:lib/saxon9he.jar"/>
会正常工作。
我建议您向开发人员报告错误,但该项目看起来并不特别活跃,因此您可能只需要构建自己的本地分支...
关于java - 在 build.xml 中设置 ANT CLASSPATH,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23132201/