使用 org.eclipse.persistence.oxm.XMLBinder 跨模块出现 ClassCastException

问题描述 投票:0回答:1

我正在尝试读取 docx 文件并用常量字符串替换作者姓名。 这是我的 main 函数中的代码。

import jakarta.xml.bind.JAXBException;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.CTTrackChange;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;


public class App {

    public static void main(String[] args) throws IOException, Docx4JException {
        try {
            // Replace "path/to/your/document.docx" with the actual file path
            String inputFilePath = "src/main/java/shapes.docx";
            String outputFilePath = "output_no_user_info.docx";

            // Load the document
            WordprocessingMLPackage wmlPackage = WordprocessingMLPackage.load(new File(inputFilePath));

            // Remove user information
            removeUserInfo(wmlPackage);

            // Save the modified document
            FileOutputStream fos = new FileOutputStream(outputFilePath);
            wmlPackage.save(fos);
            fos.close();

            System.out.println("User information removed successfully. Saved as: " + outputFilePath);

        } catch (Docx4JException | JAXBException e) {
            e.printStackTrace();
            System.err.println("Error processing the document: " + e.getMessage());
        }
    }

    public static void removeUserInfo(WordprocessingMLPackage wmlPackage) throws Docx4JException, JAXBException {
        MainDocumentPart documentPart = wmlPackage.getMainDocumentPart();
        List<Object> trackedChanges = documentPart.getJAXBNodesViaXPath("//w:ins | //w:del", true);

        for (Object change : trackedChanges) {
            if (change instanceof CTTrackChange) {
                CTTrackChange trackChange = (CTTrackChange) change;
                trackChange.setAuthor("External");
            }
        }
    }
}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>Docx4jTest</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>Archetype - Docx4jTest</name>
  <url>http://maven.apache.org</url>


  <dependencies>
    <dependency>
      <groupId>org.docx4j</groupId>
      <artifactId>docx4j-core</artifactId>
      <version>11.4.9</version>
    </dependency>
    <dependency>
      <groupId>org.docx4j</groupId>
      <artifactId>docx4j-JAXB-MOXy</artifactId>
      <version>11.4.5</version>
    </dependency>
    <dependency>
      <groupId>org.eclipse.persistence</groupId>
      <artifactId>org.eclipse.persistence.moxy</artifactId>
      <version>4.0.2</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.11.0</version>
        <configuration>
          <source>11</source>
          <target>11</target>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

我观察到的错误如下所示,当文档中存在任何形状时就会出现该错误。我看到 CTWordprocessingShape 和 org.eclipse.persistence.internal.oxm.Root 是要转换的不同类,并且代码在这行 (AbstractMarshalRecordImpl:211) 中被破坏。

 Root xr = (Root) originalObject;

AbstractMarshalRecordImpl 代码的链接:- https://github.com/payara/patched-src-eclipselink/blob/master/foundation/org.eclipse.persistence.core/src/org/eclipse/persistence/internal/oxm /记录/AbstractMarshalRecordImpl.java

我对图书馆相当陌生,请告诉我是否有任何解决办法可以绕过该问题。 我尝试使用 ReferenceImpl 而不是 Moxy,ReferenceImpl 不会导致以下问题。

错误信息:- 类 org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape 无法转换为类 org.eclipse.persistence.internal.oxm.Root (org.docx4j.com.microsoft.schemas.office.word .x2010.wordprocessingShape.CTWordprocessingShape 和 org.eclipse.persistence.internal.oxm.Root 位于加载器“app”的未命名模块)

Exception in thread "main" java.lang.ClassCastException: class org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape cannot be cast to class org.eclipse.persistence.internal.oxm.Root (org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape and org.eclipse.persistence.internal.oxm.Root are in unnamed module of loader 'app')
    at org.eclipse.persistence.internal.oxm.record.AbstractMarshalRecordImpl.addXsiTypeAndClassIndicatorIfRequired(AbstractMarshalRecordImpl.java:211)
    at org.eclipse.persistence.oxm.record.XMLRecord.addXsiTypeAndClassIndicatorIfRequired(XMLRecord.java:406)
    at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:462)
    at org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping.buildCompositeRow(XMLAnyCollectionMapping.java:683)
    at org.eclipse.persistence.oxm.mappings.XMLAnyCollectionMapping.writeFromObjectIntoRow(XMLAnyCollectionMapping.java:554)
    at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.writeOutMappings(XMLObjectBuilder.java:349)
    at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:465)
    at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:445)
    at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.buildCompositeRowForDescriptor(XMLCompositeObjectMapping.java:466)
    at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.buildCompositeRow(XMLCompositeObjectMapping.java:447)
    at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.writeSingleValue(XMLCompositeObjectMapping.java:680)
    at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.writeFromObjectIntoRow(XMLCompositeObjectMapping.java:645)
    at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.writeOutMappings(XMLObjectBuilder.java:349)
    at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:465)
    at org.eclipse.persistence.internal.oxm.XMLObjectBuilder.buildIntoNestedRow(XMLObjectBuilder.java:445)
    at org.eclipse.persistence.oxm.mappings.XMLCompositeObjectMapping.buildCompositeRowForDescriptor(XMLCompositeObjectMapping.java:466)
eclipse eclipselink docx4j moxy java-platform-module-system
1个回答
0
投票

org.docx4j.com.microsoft.schemas.office.word.x2010.wordprocessingShape.CTWordprocessingShape and org.eclipse.persistence.internal.oxm.Root are in unnamed module of loader 'app'
建议您最后可能存在 JPMS(模块化)配置问题。

使用 docx4j-JAXB-MOXy 和

module-info.java
文件对我有用,其中包括:

requires org.docx4j.JAXB_MOXy;

参见示例https://github.com/plutext/docx4j/blob/VERSION_11_5_2/docx4j-samples-docx4j/src/main/java/module-info.java

请注意,您只需要

docx4j-JAXB-MOXy
;无需同时添加
docx4-core
org.eclipse.persistence.moxy
。 也不要混合不同的版本(11.4.5 与 11.4.9 混合)。

我在 Java 17 上使用 11.5.1 进行了测试。

© www.soinside.com 2019 - 2024. All rights reserved.