You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Java 8迁移至Java 11后XSLT转换出现ClassGenException问题求助

Java 8迁移至Java 11后XSLT转换异常排查

问题背景

系统从Java 8迁移到Java 11后,XSLT响应转换功能出现异常,该功能在Java 8环境下可正常运行。XSLT与XML文件体积较大,相关代码及错误栈如下:

相关代码

public static void main(String[] args) {
 try {
    String data = readFileAsString("Sample.xml");
    String dataxsl = readFileAsString("Test.xsl");
    transform(data, dataxsl);
} catch (Exception e) {
        e.printStackTrace();
    }

}
 public static String readFileAsString(String fileName) throws Exception {
    String data = "";
    data = new String(Files.readAllBytes(Paths.get(fileName)));
    return data;
}

public static String transform(String dataXML, String inputXSL) throws TransformerConfigurationException, TransformerException {

        Source xslt = new StreamSource(new File(inputXSL));
        Source text = new StreamSource(new File(dataXML));
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer(xslt);
        StringWriter out = new StringWriter();
        transformer.transform(text, new StreamResult(out));
        return out.toString();

    }

错误栈信息

com.sun.org.apache.bcel.internal.generic.ClassGenException: Not targeting 459415: nop0, but null
    at java.xml/com.sun.org.apache.bcel.internal.generic.BranchInstruction.updateTarget(BranchInstruction.java:217)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator.outline(MethodGenerator.java:1721)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator.outlineChunks(MethodGenerator.java:1168)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator.getGeneratedMethods(MethodGenerator.java:1882)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator.addMethod(ClassGenerator.java:137)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.Mode.compileNamedTemplate(Mode.java:536)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.Mode.compileTemplates(Mode.java:545)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.Mode.compileApplyTemplates(Mode.java:804)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.Stylesheet.compileModes(Stylesheet.java:622)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.Stylesheet.translate(Stylesheet.java:735)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC.compile(XSLTC.java:503)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC.compile(XSLTC.java:570)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:1018)
    at java.xml/com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl.newTransformer(TransformerFactoryImpl.java:817)

异常成因分析

  1. 代码逻辑错误:transform方法接收的是XML和XSLT的字符串内容,但代码错误地将这些字符串当作文件名传入StreamSource,而非直接使用字符串内容。这个问题在Java 8中可能未触发明显异常,但Java 11的文件处理或XSLT实现更严格,间接加剧了后续的字节码生成问题。

  2. XSLTC字节码生成兼容问题:Java 11中默认的TransformerFactory是Xalan的XSLTC实现,它依赖BCEL库生成字节码处理XSLT。当XSLT文件体积大、逻辑复杂时,生成的方法字节码长度可能超出内部处理限制,或者分支指令的目标地址处理出现异常,从而抛出ClassGenException。此外,Java 8到Java 11的模块化变更,导致BCEL的内部调用逻辑调整,进一步触发了该兼容问题。

解决方向

  • 修正代码逻辑:将字符串内容直接通过StringReader传入StreamSource,替换原有的File方式:
public static String transform(String dataXML, String inputXSL) throws TransformerConfigurationException, TransformerException {
    Source xslt = new StreamSource(new StringReader(inputXSL));
    Source text = new StreamSource(new StringReader(dataXML));
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer(xslt);
    StringWriter out = new StringWriter();
    transformer.transform(text, new StreamResult(out));
    return out.toString();
}
  • 切换到Xalan解释器模式:避免使用XSLTC的字节码编译,指定传统的解释器实现:
    • 代码中设置:TransformerFactory factory = TransformerFactory.newInstance("org.apache.xalan.processor.TransformerFactoryImpl", null);
    • 或添加JVM参数:-Djavax.xml.transform.TransformerFactory=org.apache.xalan.processor.TransformerFactoryImpl
  • 升级Xalan版本:替换JDK自带的Xalan为最新独立版本,独立版本对Java 11的兼容性更好,能解决部分字节码生成的兼容问题。

内容的提问来源于stack exchange,提问作者Mahajan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 04:35:18