首页 > 解决方案 > JAXB 在类路径上使用 (SAXON-HE) 解组非常慢

问题描述

我发现在使用 JAXB 解组 XML 的项目中将 quickfixj-all 作为 maven 依赖项会导致解组速度极慢。

这是当 quickfixj-all 不在类路径上时单元测试的控制台输出:

2019-12-15 20:02:26.067  INFO 1676 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loaded Repository XML in 506ms
2019-12-15 20:02:26.067  INFO 1676 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loading Phrases XML
2019-12-15 20:02:26.068  INFO 1676 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loading from /C:/Users/Beirti/git/jaxb-performance/target/test-classes/FIX.5.0SP2_EP249_en_phrases.xml
2019-12-15 20:02:30.081  INFO 1676 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loaded Phrases XML in 4013ms
2019-12-15 20:02:30.081  INFO 1676 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loaded JAXB Objects

但是,当您在类路径中包含 quickfixj-all 时,需要的时间要长得多。

2019-12-15 20:03:39.403  INFO 2912 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loaded Repository XML in 881ms
2019-12-15 20:03:39.403  INFO 2912 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loading Phrases XML
2019-12-15 20:03:39.404  INFO 2912 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loading from /C:/Users/Beirti/git/jaxb-performance/target/test-classes/FIX.5.0SP2_EP249_en_phrases.xml
2019-12-15 20:06:49.584  INFO 2912 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loaded Phrases XML in 190180ms
2019-12-15 20:06:49.584  INFO 2912 --- [           main] c.b.fix.repository.FIXRepositoryHelper   : Loaded JAXB Objects

这似乎是由于传递依赖quickfixj-all -> quickfixj-codegenerator -> Saxon-HE:9.8.0-4。您可以通过单独包含此依赖项来复制问题。

我可以在 Saxon-HE jar 中看到 META-INF 中的一个文件,它覆盖javax.xml.transform.TransformerFactory并将其设置为com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl. 如果我直接从 jar 中删除该文件并重新运行我的测试,它会很快完成。

有没有办法在我自己的项目中覆盖这个 TransformerFactory 而不会破解 Saxon jar?(我尝试将默认的添加到 src/main/resources/META-INF/services 但它不起作用)

该项目包含一些演示该问题的类和配置:https ://github.com/beirtipol/jaxb-performance

标签: javaxmljaxbsaxonquickfixj

解决方案


我从对原始问题的评论中尝试了一些建议:

  • 在撒克逊的错误报告中没有什么明显的。我不确定这本身是一个错误,还是只是 TransformerFactory 的撒克逊实现的性能不佳。
  • 在运行时使用系统属性覆盖 TransformerFactory 是有问题的,因为默认情况下 Java 11 不再包含一些 XML 处理 jar,并且很难在运行时保持兼容
  • 破解 Saxon jar 以从“services”文件夹中删除 TransformerFactory 覆盖是非常糟糕的,除非您正在执行某种着色或 jar-of-dependencies 构建,而您不想保留原始依赖项。

正如 QFJ 团队之一所建议的那样,Saxon 仅在代码生成时需要,而不是运行时依赖项,因此针对此特定问题的最佳解决方案是将 Saxon complete 从 quickfixj-all 依赖项中排除。这解决了我使用 QuickFixJ 的具体问题,但我并不完全高兴没有办法覆盖 ServiceLoader。

    <dependency>
        <groupId>org.quickfixj</groupId>
        <artifactId>quickfixj-all</artifactId>
        <version>2.1.1</version>
        <exclusions>
            <exclusion>
                <artifactId>Saxon-HE</artifactId>
                <groupId>net.sf.saxon</groupId>
            </exclusion>
        </exclusions>
    </dependency>

推荐阅读