【问题标题】:Cannot use docx4j inside of JBoss 7无法在 JBoss 7 中使用 docx4j
【发布时间】:2013-04-25 00:46:22
【问题描述】:

我能够使用 docx4j (http://www.docx4java.org) 成功创建一个简单的项目。这个简单的项目成功地创建并写入了 .docx 文档。现在我正试图在一个更大的项目中完成同样的事情。这个更大的项目是一个运行在 JBoss AS 7.1 中的 webapp。但是,在我的第一个 docx4j 相关代码行:

WordprocessingMLPackage wmlp = WordprocessingMLPackage.createPackage();

遇到错误:

java.lang.NoClassDefFoundError: Could not initialize class org.docx4j.jaxb.Context
    at org.docx4j.openpackaging.parts.JaxbXmlPart.<init>(JaxbXmlPart.java:79) [docx4j-2.8.1.jar:]
    at org.docx4j.openpackaging.parts.JaxbXmlPartXPathAware.<init>(JaxbXmlPartXPathAware.java:64) [docx4j-2.8.1.jar:]
    at org.docx4j.openpackaging.parts.WordprocessingML.DocumentPart.<init>(DocumentPart.java:157) [docx4j-2.8.1.jar:]
    at org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart.<init>(MainDocumentPart.java:76) [docx4j-2.8.1.jar:]
    at org.docx4j.openpackaging.packages.WordprocessingMLPackage.createPackage(WordprocessingMLPackage.java:432) [docx4j-2.8.1.jar:]
    at org.docx4j.openpackaging.packages.WordprocessingMLPackage.createPackage(WordprocessingMLPackage.java:421) [docx4j-2.8.1.jar:]
    at foo.servlets.bar.DocxServlet.doGet(DocxServlet.java:101) [classes:]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:734) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.0.Final.jar:1.0.0.Final]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at foo.includes.other.ServletNameSetFilter.doFilter(ServletNameSetFilter.java:83) [fooClasses.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at foo.includes.other.HtmlEscapeFilter.doFilter(HtmlEscapeFilter.java:67) [fooClasses.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at foo.includes.other.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:64) [fooClasses.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
    at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:505) [jbossweb-7.0.13.Final.jar:]
    at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:445) [jbossweb-7.0.13.Final.jar:]
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
    at java.lang.Thread.run(Thread.java:636) [rt.jar:1.6.0_20]

另外,当我停止并重新启动我的服务器而不重建我的 EAR 时,这个错误不会出现,而是我从同一个方法调用 (createPackage()) 中得到一个 NoSuchElementException:

我认为这与 JBoss 有自己的 JAXB 实现有关,但 JAXBContext 是在 docx4j 库中初始化的。这是代码(来自http://www.docx4java.org/trac/docx4j/browser/trunk/docx4j/src/main/java/org/docx4j/jaxb/Context.java):

jc = JAXBContext.newInstance("org.docx4j.wml:" +
                "org.docx4j.dml:org.docx4j.dml.chart:org.docx4j.dml.chartDrawing:org.docx4j.dml.compatibility:org.docx4j.dml.diagram:org.docx4j.dml.lockedCanvas:org.docx4j.dml.picture:org.docx4j.dml.wordprocessingDrawing:org.docx4j.dml.spreadsheetdrawing:org.docx4j.dml.diagram2008:" +
                // All VML stuff is here, since compiling it requires WML and DML (and MathML), but not PML or SML
                "org.docx4j.vml:org.docx4j.vml.officedrawing:org.docx4j.vml.wordprocessingDrawing:org.docx4j.vml.presentationDrawing:org.docx4j.vml.spreadsheetDrawing:org.docx4j.vml.root:" +
                "org.opendope.xpaths:org.opendope.conditions:org.opendope.questions:org.opendope.components:org.opendope.SmartArt.dataHierarchy:" +
                "org.docx4j.math:" +
                "org.docx4j.sharedtypes:org.docx4j.bibliography",classLoader );
log.info("loaded " + jc.getClass().getName() + " .. loading others ..");

jcThemePart = jc; //JAXBContext.newInstance("org.docx4j.dml",classLoader );
jcDocPropsCore = JAXBContext.newInstance("org.docx4j.docProps.core:org.docx4j.docProps.core.dc.elements:org.docx4j.docProps.core.dc.terms",classLoader );
jcDocPropsCustom = JAXBContext.newInstance("org.docx4j.docProps.custom",classLoader );
jcDocPropsExtended = JAXBContext.newInstance("org.docx4j.docProps.extended",classLoader );
jcXmlPackage = JAXBContext.newInstance("org.docx4j.xmlPackage",classLoader );
jcRelationships = JAXBContext.newInstance("org.docx4j.relationships",classLoader );
jcCustomXmlProperties = JAXBContext.newInstance("org.docx4j.customXmlProperties",classLoader );
jcContentTypes = JAXBContext.newInstance("org.docx4j.openpackaging.contenttype",classLoader );

jcSectionModel = JAXBContext.newInstance("org.docx4j.model.structure.jaxb",classLoader );

jcXmlDSig = JAXBContext.newInstance("org.plutext.jaxb.xmldsig",classLoader );

根据我的观察,似乎我可能需要放置一个 jaxb.properties 文件,指定要在上面每个 JAXBContext 实例中列出的每个包中使用哪个 jaxb 实现。它是否正确?我有什么遗漏吗?

【问题讨论】:

  • 我有同样的问题,但在 tomcat 和 2019 年,下面的解决方案对我不起作用:/

标签: jboss7.x docx4j


【解决方案1】:

在 Maven pom.xml 中放置这些缺失的依赖项,问题就解决了(在 JBoss 7.1.3 上)

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.6.1</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2.7</version>
</dependency>
<dependency>
    <groupId>com.googlecode.jaxb-namespaceprefixmapper-interfaces</groupId>
    <artifactId>JAXBNamespacePrefixMapper</artifactId>
    <version>2.2.4</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.11.0</version>
</dependency>

【讨论】:

  • 请用英文发帖
  • 在尝试其他答案后,这对我在 JBoss EAP 6.0.1 - JDK 7 上有效
【解决方案2】:

JBoss AS7 有一个不同于以前版本的类加载机制。一般见https://docs.jboss.org/author/display/AS71/Class+Loading+in+AS7

它包括一个名为 javax.xml.bind.api 的模块;要让 docx4j 在您的 WAR 中工作,您只需要包含 WEB-INF/jboss-deployment-structure.xml 包含:

<deployment>
    <dependencies>

        <module name="com.sun.xml.bind" />

    </dependencies>
</deployment>

详情/讨论

modules\javax\xml\bind\api\main 说:

<dependencies>
    <module name="javax.activation.api" export="true"/>
    <module name="javax.xml.stream.api"/>
    <module name="com.sun.xml.bind" services="import"/>
    <module name="javax.api"/>
</dependencies>

<resources>
    <resource-root path="jboss-jaxb-api_2.2_spec-1.0.3.Final.jar"/>
    <!-- Insert resources here -->
</resources>

modules\com\sun\xml\bind\main 说:

<resources>
    <resource-root path="jaxb-impl-2.2.4.jar"/>
    <resource-root path="jaxb-xjc-2.2.4.jar"/>
    <!-- Insert resources here -->
</resources>

<dependencies>
    <module name="javax.api" />
    <module name="javax.xml.bind.api" />
    <module name="javax.xml.stream.api" />
</dependencies>

所以您可能认为以下方法也可以:

<deployment>
    <dependencies>

        <module name="javax.xml.bind.api" />

    </dependencies>
</deployment>

但它似乎没有,也许是因为被赋予了效果?

【讨论】:

    【解决方案3】:

    我假设您使用的是 Java 7。 我能够通过在

    上运行的 JBoss EAP 6.2 解决这个问题
    java version "1.7.0_55"
    OpenJDK Runtime Environment (IcedTea 2.4.7) (7u55-2.4.7-1ubuntu1~0.13.10.1)
    OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)
    
    1. 定义以下 JBoss 模块:

      <!-- module.xml content -->
      <module xmlns="urn:jboss:module:1.1" name="org.docx4j-compat">
          <dependencies>
              <module name="sun.jdk"/>
              <system export="true">
                  <paths>
                      <path name="com/sun/xml/internal/bind/marshaller"/>
                  </paths>
              </system>
          </dependencies>
      </module>
      
    2. 将此模块的依赖添加到您的 WEB-INF/jboss-deployment-structure.xml。

    【讨论】:

      【解决方案4】:

      所以经过一些研究我们发现 docx4j 的解决方案可以在 jboss 上运行

      你需要在 jboss 中定义新模块,我们称之为 org.docx4j-compat

      它将位于 \system\layers\base\org

      现在将所有相关的 jars 添加到主文件夹和 module.xml

      module.xml:

      <resources>
          <resource-root path="docx4j-3.1.0.jar"/>
          <resource-root path="docx4j-ImportXHTML-3.0.1.jar"/> 
          <resource-root path="jaxb-api-2.1.jar"/>
          <resource-root path="jaxb-svg11-1.0.2.jar"/>
          <resource-root path="jaxb-xmldsig-core-1.0.0.jar"/>
          <resource-root path="jaxb-xslfo-1.0.1.jar"/>
      </resources>
      
      <dependencies>
          <module name="org.slf4j"/>
          <module name="org.apache.commons.io"/>
          <module name="sun.jdk"/>
          <system export="true">
              <paths>
                  <path name="com/sun/xml/internal/bind/marshaller"/>
              </paths>
          </system>
          <module name="javax.xml.bind.api"/>
          <module name="javax.api"/>
          <module name="com.sun.xml.bind" />
      </dependencies>
      

      希望对你有帮助:)

      【讨论】:

        【解决方案5】:

        请查看docx4j JBOSS deployment forum

        例如,来自其中一篇文章:

        我的 Serializer 和 Xalan jar 的版本。我每个都有 2.7.1 作为 指示,但我的应用服务器(JBoss 5.1.0)有不同的版本 (未编号:serializer.jar 和 xalan.jar)在根 lib/endorsed 覆盖这些的文件夹。当我用 2.7.1 版本完美运行。

        请让我们知道那里的建议是否适合您。

        【讨论】:

        • 我得到了同样的错误,我尝试了你的解决方案但它不起作用,同样的错误。
        【解决方案6】:

        这两个最小步骤对我有用(JBOSS 7.1.3、DOCX4J 3.2.2):

      • 配置 `WEB-INF\jboss-deployment-structure.xml` 文件
        <?xml version="1.0" encoding="UTF-8"?>
        <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
            <deployment>    
                <dependencies>
                    <module name="com.sun.xml.bind" />
                </dependencies>
            </deployment>
        </jboss-deployment-structure>
        
      • 修改我的 pom.xml
                <dependency>
                    <groupId>com.googlecode.jaxb-namespaceprefixmapper-interfaces</groupId>
                    <artifactId>JAXBNamespacePrefixMapper</artifactId>
                    <version>2.2.4</version>
                    <scope>runtime</scope>
                </dependency>
        
      • 【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-28
          • 2013-05-25
          • 2012-12-04
          • 1970-01-01
          • 2018-12-05
          • 2012-01-30
          相关资源
          最近更新 更多