2

我有以下代码

SAXTransformerFactory stfactory;
stfactory = (SAXTransformerFactory) TransformerFactory.newInstance();

/// ClassLoaderUriResolver is another class.
 stfactory.setURIResolver(new ClassLoaderUriResolver()); 

 InputStream is = this.getClass().getClassLoader().getResourceAsStream("xsl/Hello.xsl");
 StreamSource streamSource = new StreamSource(is);

  mergeHandler = stfactory.newTransformerHandler(streamSource);

 XMLReader xmlReader = XMLReaderFactory.createXMLReader();

还有一些代码......

问题出在行 mergeHandler = stfactory.newTransformerHandler(streamSource);

当我在 JBOSS IDE 中使用相同的 jar 集将该程序作为独立的 JAVA 程序运行时

  • xalan-2.7.0.jar
  • xercesImpl-2.7.1.jar
  • xml-apis-1.3.04.jar
  • xml-apis-ext-1.3.04.jar

我看到调用 stfactory.newTransformerHandler(streamSource);

返回
org.apache.xalan.transformer.TransformerHandlerImpl

并且我的 XLST 翻译可以作为一个简单的 java 程序正常工作

在 Jboss AS 7 容器上运行相同的代码时,我看到调用 stfactory.newTransformerHandler(streamSource);

返回
org.apache.xalan.transformer.TransformerIdentityImpl(不是 TransformerHandlerImpl)

结果,当我作为 Web 应用程序的一部分在 Jboss AS 7 Container 上运行时,XSLT 转换没有发生,我没有看到任何错误。我的 XLS FO 文档未翻译。

如何强制代码使用org.apache.xalan.transformer.TransformerHandlerImpl

4

1 回答 1

2

我让它工作了。

在 jboss 中,除了我们可以排除的模块之外,还有另一个位于根 C:\jboss-eap-6.0\jboss-modules.jar 的 jar。在这个 jar 中,有一个名为“__redirected”的文件夹,其中包含一个类 __TransformerFactory.class,代码如下。

Class clazz = __RedirectedUtils.loadProvider(id, javax/xml/transform/TransformerFactory, loader);

这会强制从 C:\jboss-eap-6.0/jboss-modules.jar 加载“org.apache.xalan.processor.TransformerFactoryImpl”

然而,这不是一个模块,所以我不能使用 jboss-deployment-structure.xml 排除它,尽管我已经排除了以下用于 Xalan、Xercel 和 XML api 的 jboss 模块。因为我们在 EAR 库中有一个特定的 jars 来满足这一点。

jboss-部署-结构.xml

<jboss-deployment-structure xmlns:p="urn:jboss:deployment-structure:1.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <deployment>
                            <exclusions>
                                          <module name="org.apache.xerces" />
                                            <module name="org.apache.xalan" />
                                            <module name="org.apache.xml-resolver" />
                            </exclusions>

            </deployment>

所以我评论了以下代码

  stfactory = (SAXTransformerFactory) TransformerFactory.newInstance();

并添加

  Class clazz = Class.forName("org.apache.xalan.processor.TransformerFactoryImpl");
  stfactory = (SAXTransformerFactory) clazz.newInstance();

现在我看到了

  • org.apache.xalan.processor.TransformerFactoryImpl 正在从 C:/jboss-eap-6.0/standalone/deployments/TST.ear/lib/xalan-2.7.0.jar 加载

  • 调用 stfactory.newTransformerHandler(streamSource) 返回“org.apache.xalan.transformer.TransformerHandlerImpl”而不是“org.apache.xalan.transformer.TransformerIdentityImpl”</p>

所以我相信 jar “C:\jboss-eap-6.0\jboss-modules.jar” 是类加载器的一部分,在 EAR 类加载器之上。所以它没有将 Xalan.2.7.0.jar 用于“org.apache.xalan.processor.TransformerFactoryImpl”。然而,当我们调用 stfactory.newTransformerHandler(streamSource) 时,它会返回“org.apache.xalan.transformer.TransformerIdentityImpl”。

对于这种行为,C:\jboss-eap-6.0\jboss-modules.jar 中可能有一些东西。

我不明白的是在我确实使用 Xalan.2.7.0.jar 的一项测试中,并在 java.endorsed.dir 中添加了它仍在使用 C:\jboss-eap-6.0\jboss-modules.jar 这是一点也不奇怪,因为我认为认可的 jar 甚至会在 C:\jboss-eap-6.0\jboss-modules.jar 之前加载。

但无论如何,当前的修复解决了这个问题,它只发生在 Jboss 应用程序服务器 7 上。代码在 Webspshere 7.0 中没有任何变化,当我作为独立的 java 程序运行它时也可以工作。

于 2013-09-25T19:26:39.193 回答