gpt4 book ai didi

xslt - 使用 JDK 内部 Xalan 和 SecurityManager 从 XSL 样式表内部加载外部 Java 方法

转载 作者:行者123 更新时间:2023-12-03 06:34:47 26 4
gpt4 key购买 nike

在我们的项目中,我们目前已迁移到 Java 8,并且现在希望使用内部 XML 库而不是其他库。为此,我们删除了例如我们的 xalan.jar 来 self 们的类路径。

这会在尝试渲染 XML 文件时导致 ClassNotFoundExceptions。在 XSL 样式表中,我们用来转换 XML 文件,我们还调用外部 Java 方法,如下例所示:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:java="http://xml.apache.org/xalan/java">

...

<xsl:template name="example">
<fo:block>
<xsl:value-of select="java:my.package.name.JavaClass.testMethod('test')"/>
</fo:block>
</xsl:template>
...

但是,总是当外部方法 testMethod()如果应该调用,则进程会因 ClassNotFoundException 而停止。我调试了com.sun.org.apache.xalan.internal.xsltc.compiler.FunctionCall中的代码类并发现 XSLTC 尝试实例化 my.package.name.JavaClass以便调用 testMethod() 。这没关系。但是...

尝试在以下代码 com.sun.org.apache.xalan.internal.utils.ObjectFactory 中实例化/加载该类:

/**
* Find a Class using the same class loader for the ObjectFactory by default
* or boot class loader when Security Manager is in place
*/
public static Class<?> findProviderClass(String className, boolean doFallback)
throws ClassNotFoundException, ConfigurationError
{
return findProviderClass (className,
findClassLoader (), doFallback);
}

进一步调用findClassLoader()获得正确的类加载器来加载我的 JavaClass :

/**
* Figure out which ClassLoader to use. For JDK 1.2 and later use
* the context ClassLoader.
*/
public static ClassLoader findClassLoader()
{
if (System.getSecurityManager()!=null) {
//this will ensure bootclassloader is used
return null;
}

// Figure out which ClassLoader to use for loading the provider
// class. If there is a Context ClassLoader then use it.
ClassLoader context = SecuritySupport.getContextClassLoader();
ClassLoader system = SecuritySupport.getSystemClassLoader();

ClassLoader chain = system;
while (true) {
if (context == chain) {
...loop to get correct class loader
}

现在,在我们的项目中,我们遇到了一个“问题”,即我们有一个 SecurityManager 实现,这意味着上面的实现只返回 null而不是上下文类加载器。

顺便说一句:我还希望在这里获得上下文类加载器,但是如果 SecurityManager 允许加载类,稍后会进行额外的检查,为什么它在这里只返回 null?

这再次意味着我的类尝试使用引导类加载器加载,但引导类加载器不知道我的类,因此会引发异常。删除 SecurityManager 返回上下文类加载器,它能够加载我的类并且可以成功转换 XML。

那么 - 如果您还在这里 sleep - 有没有办法仍然能够在 XSL 样式表中使用我的外部 Java 方法?在这种情况下有办法加载我的类吗?我考虑了以下可能的解决方案,但它们都不能真正令我满意:

  • 修补 ObjectFactory,删除或扩展对 SecurityManager 的检查,并将其放在我的应用程序的启动类路径中,使其在原始应用程序之前加载(脏黑客)
  • 删除 SecurityManager(目前或多或少是一个虚拟实现,但这不是永久解决方案)
  • 将 Java 方法编写为 XSL 中的扩展函数(不确定这是否适用于我们拥有的所有方法,并且会非常耗时且容易出错;而且我也不确定这是否真正解决了问题)<
  • 按以下方式使用反射在 XSL 中创建 JavaClass 的实例:

但是,最后一种方法也不起作用,因为该类也是通过 AppClassLoader 加载的,并且在解析过程中可能也不可用。但也许有类似的解决方案?

提前致谢。

最诚挚的问候,延斯

最佳答案

类似这样的工作:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:myHelper="http://xml.apache.org/xalan/java/my.package.name.JavaClass">

...

<xsl:template name="example">
<fo:block>
<xsl:value-of select="myHelper:testMethod('test')"/>
</fo:block>
</xsl:template>

如何在样式表声明中指定命名空间(在本例中为 myHelper)取决于您用来处理 XSL 的内容,上面的示例适用于 Xalan。

关于xslt - 使用 JDK 内部 Xalan 和 SecurityManager 从 XSL 样式表内部加载外部 Java 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29171010/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com