Recommand · October 14, 2021 0

JAXB Marshaller cannot set property for CharacterEscapeHandler

We have a non-Spring application running with JDK 11. In our pom.xml file we have the following:

<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>2.3.3</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-core</artifactId>
    <version>2.3.0</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.3.3</version>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.3</version>
</dependency>

We have code to to a Marshalling of a java object to xml as follows:

Marshaller marshaller = JAXBContext.newInstance(Ratings.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, schemaLocation);
marshaller.setProperty(CharacterEscapeHandler.class.getName(), 
                        new CDATACharacterEscapeHandler());
        
StringWriter writer = new StringWriter();
marshaller.marshal(ratings, writer);        
return writer.toString();

The code fails when we try to set the CharacterEscapeHandler. We get the following error:

Caused by: javax.xml.bind.PropertyException: name: 
com.mycode.server.utils.CDATACharacterEscapeHandler value: 
com.mycode.server.utils.CDATACharacterEscapeHandler@74921b67
at javax.xml.bind.helpers.AbstractMarshallerImpl.setProperty
(AbstractMarshallerImpl.java:343)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.setProperty
(MarshallerImpl.java:516)

I can tell you about our custom CDATACharacterEscapeHandler as follows:

// this is the only class that I could find with this name.
//  even when I pull in com.sun.xml.bind.jaxb-core 2.3.0
import org.glassfish.jaxb.core.marshaller.CharacterEscapeHandler;

public class CDATACharacterEscapeHandler implements CharacterEscapeHandler  {
    @Override
    public void escape(char[] ch, int start, int length, boolean isAttVal, Writer writer) throws IOException
    {
      ...
    }
}

You can see that our CDATACharacterEscapeHandler extends a standard CharacterEscapeHandler.

I’ve spent about 5 hours research between StackOveflow and the Internet in general. I have been to the JAXB official site. And I know I have tried a lot of things such as:

marshaller.setProperty(CDATACharacterEscapeHandler.class.getName(), new CDATACharacterEscapeHandler());

marshaller.setProperty("com.sun.xml.bind.characterEscapeHandler", new CDATACharacterEscapeHandler());

And nothing seems to work. I one point I tried moving to the latest 3.0.2 versions of code, and that also did not work. It made more of a hassle because the java.xml.bind package was changed to jakarta.xml.bind and I didn’t want to update all our code at this time. That can be another effort later.

I have bookmarked other questions on Stackoverflow where someone got answers, and I tried those efforts, but nothing here seemed to work.