Java7 Update4中的SecurityManager和XSLT扩展是否存在问题?

4

Java应用程序FreeMind使用XSLT更新旧文件。XSLT使用静态java函数简化字符串操作。这在Java 7更新2之前都运行良好,并在Windows下的Java 7更新4中给出以下异常:

STDERR: ERROR:  'The first argument to the non-static Java function 'replaceSpacesToNonbreakableSpaces' is not a valid object reference.'
STDERR: FATAL ERROR:  'Could not compile stylesheet'May 26, 2012 10:50:06 PM freemind.main.Resources logException
SEVERE: An exception occured: 
javax.xml.transform.TransformerConfigurationException: Could not compile stylesheet
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(Unknown Source)
    at com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(Unknown Source)
    at freemind.main.Tools$1TransformerRunnable.run(Tools.java:1023)
    at java.lang.Thread.run(Unknown Source)

将问题简化后,发现原因是自定义的SecurityManager造成了问题。如果设定了自定义SecurityManager,则代码会失败;如果将其注释掉,则代码可以正常工作。有人知道java7中2号和4号更新之间的安全系统发生了什么变化,或者还有什么其他可能引起该问题的原因吗?

以下是更为简单的示例:

package freemind.main;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public final class FreeMindSecurityTest  {

    public static void main(String[] args) throws Exception {
        // if commented out, this program works as expected.
        System.setSecurityManager(new SecurityManager());
        String input = "<map version=\"0.9.0\">"
                + "</map>";
        String xslt = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "     <xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" xmlns:FreeMindSecurityTest=\"xalan://freemind.main.FreeMindSecurityTest\" exclude-result-prefixes=\"FreeMindSecurityTest\">"
                + "         <xsl:template               match=\"/ | node() | @* | comment() | processing-instruction()\">"
                + "             <xsl:value-of select=\"FreeMindSecurityTest:replaceSpacesToNonbreakableSpaces('test')\"/>"
                + "         </xsl:template>" + "        </xsl:stylesheet>";
        StringWriter writer = new StringWriter();
        final Result result = new StreamResult(writer);

        final StreamSource sr = new StreamSource(new StringReader(input));
        // create an instance of TransformerFactory
        TransformerFactory transFact = TransformerFactory.newInstance();
        Transformer trans = transFact.newTransformer(new StreamSource(
                new StringReader(xslt)));

        trans.transform(sr, result);

        System.out.println("Transformed: " + writer.getBuffer());
        writer.close();
    }

    public static String replaceSpacesToNonbreakableSpaces(String input) {
        return input;
    }



}

简而言之,Java认为该方法不是静态的(但实际上是静态的),并且缺少对象引用。
谢谢,来自FreeMind的Chris
编辑:添加了最短的示例(只需设置普通安全管理器的副本即可)。

当堆栈跟踪是德语时,没有人会阅读您的代码。您能否缩小代码范围并在此处放置它们?如果您不确定如何使用堆栈溢出,请先阅读此文http://stackoverflow.com/faq - gigadot
谢谢,以上已编辑并提供了英文输出。 - Chris from FreeMind
问题是 XSLT 在安全管理器内部被调用失败了,还是在安全管理器生效时其他 XSLT 调用也失败了? - bmargulies
@bmargulies:我不理解这个问题。但事实证明,即使设置正常的SecurityManager也会导致此XSLT转换失败。 - Chris from FreeMind
@ChrisfromFreeMind:它也不支持Java 7 Update6 Build 11 :( - tuergeist
显示剩余2条评论
1个回答

2
可能存在一个问题在JAXP 1.4.6 (Java 7 Update 4中)。Java 7u4的一个变化是升级到了JAXP 1.4.6,详见Java Release Notes
解决方法(也许不是最佳选择)是使用没有额外补丁的Xalan 2.7.1通过Java endorsed folder。(将xalan 2.7.1 jars复制到jre/libs/endorsed) 或者使用Xalan作为第三方库。
对我来说,在Linux64上使用J7U4和Xalan 2.7.1可行。
Transformed: <?xml version="1.0" encoding="UTF-8"?>test

Java认可的文件夹有一个小错误:它实际上应该是jre/lib/endorsed - rhlobo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接