rob*_*ert 5 java ant schematron
这个特殊问题已被问过几次,但并不令我满意.我对提出的解决方法并不感兴趣,但是如何做我真正想做的事情.
想要一个令人满意的解释为什么这是不可能的,如果不是,并且因为我建议自己提交一个解决方案,我想了解为什么没有尝试过看起来那么简单的东西.
目前,为了确保ant可以使用一组jar,必须采用以下方法之一:
CLASSPATH环境变量 - 文档中的"不推荐"$ANT_HOME/lib或~/.ant/lib- 需要在构建环境中进行配置-lib在ant调用时设置参数最后一个选项是我已经确定的首选选项,但它仍然需要调用构建的人进行一些干预(我已经ant在我的开发存储库中的包装器脚本中捕获了它).
特别是我试图调用Schematron Ant任务,该任务应根据以下文档设置:
<taskdef name="schematron"
classname="com.schematron.ant.SchematronTask"
classpath="lib/ant-schematron.jar"/>
Run Code Online (Sandbox Code Playgroud)
但是这对撒克逊人有一个传递依赖,所以如果没有saxon.jar可用的CLASSPATH,那么构建失败:
java.lang.NoClassDefFoundError: net/sf/saxon/TransformerFactoryImpl
Run Code Online (Sandbox Code Playgroud)
在蚁文件本身继续提出,它应该是需要这些额外的本身的taskdef CLASSPATH条目,但我已经与Schematron的蚂蚁任务无济于事尝试这个.
关键问题是它是否应该是支持这个的schematron ant任务,或者ant build.xml是否可以在其自身内配置其全局类路径?
似乎这是人们想要经常做的事情,并且由于ant文档本身建议不使用CLASSPATH本身,我很惊讶build.xml本身没有其他选择!
这似乎是 Schematron 任务中的一个错误。Ant 任务加载 Saxon XSLT 处理器的方式将要求 Saxon 位于系统类路径上,即使任务本身位于辅助类加载器上。
乍一看,ValidatorFactory 中的这段代码看起来很合理:
private TransformerFactory _factory = TransformerFactoryImpl.newInstance();
Run Code Online (Sandbox Code Playgroud)
(其中TransformerFactoryImpl是 Saxon 的实现TransformerFactory),但实际上TransformerFactoryImpl没有定义newInstance()自己的方法,因此这是继承newInstance自TransformerFactory,它将根据系统属性的值查找合适的工厂javax.xml.transform.TransformerFactory。Ant 任务确实设置了此系统属性:
System.setProperty("javax.xml.transform.TransformerFactory",
"net.sf.saxon.TransformerFactoryImpl");
Run Code Online (Sandbox Code Playgroud)
但TransformerFactory.newInstance()会在系统类加载器上查找此类,而不一定在加载 schematron 任务的类加载器上查找。
解决方法是将ValidatorFactory第 120 行更改为简单的
private TransformerFactory _factory = new TransformerFactoryImpl();
Run Code Online (Sandbox Code Playgroud)
这将绕过所有动态查找并直接实例化正确的类。完成此修复后
<taskdef name="schematron"
classname="com.schematron.ant.SchematronTask"
classpath="lib/ant-schematron.jar:lib/saxon9he.jar"/>
Run Code Online (Sandbox Code Playgroud)
会正常工作。
我建议您向开发人员报告该错误,但该项目看起来并不特别活跃,因此您可能只需要构建自己的本地分支...
| 归档时间: |
|
| 查看次数: |
4870 次 |
| 最近记录: |