Search code examples
javajaxbwildfly

PropertyException after wildfly update: property CharacterEscapeHandler must be an instance of type CharacterEscapeHandler


Some time ago I implemented a CustomCharacterEscapeHandler and it worked fine up-to Wildfly-18.0.1. Now when updating to Wildfly 19 or higher I get the following exception:

javax.xml.bind.PropertyException: property "com.sun.xml.bind.marshaller.CharacterEscapeHandler" must be an instance of type com.sun.xml.bind.marshaller.CharacterEscapeHandler, not my.package.CustomCharacterEscapeHandler
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.setProperty(MarshallerImpl.java:489)

But my CustomCharacterEscapeHandler implements exactly the mentioned interface!

The maven pom.xml looks like this:

<dependency>
 <groupId>javax.xml.bind</groupId>
 <artifactId>jaxb-api</artifactId>
 <version>2.2.12</version>
</dependency>
<dependency>
 <groupId>com.sun.xml.bind</groupId>
 <artifactId>jaxb-impl</artifactId>
 <version>2.2.11</version>
</dependency>
<dependency>
 <groupId>com.sun.xml.bind</groupId>
 <artifactId>jaxb-core</artifactId>
 <version>2.2.11</version>
</dependency>
<dependency>
 <groupId>com.sun.xml.bind</groupId>
 <artifactId>jaxb-xjc</artifactId>
 <version>2.2.11</version>
</dependency>

I researched a lot and did try out all the solutions I could find (1, 2, 3, 4, 5) but many questions remain unanswered (6,7,8,9,10) and the things mentioned did not work. So I tried:

  • added jaxb.properties containing javax.xml.bind.context.factory=com.sun.xml.bind.v2.ContextFactory
  • updated to newer JAXB Versions
  • added a startup property -Djavax.xml.bind.context.factory=com.sun.xml.bind.v2.ContextFactory
  • added the EscapHandler as inline code jaxbMarshaller.setProperty(CharacterEscapeHandler.class.getName(), (CharacterEscapeHandler) (chars, start, length, b, writer) -> ... );
  • tried adding exclusion(s) in the jboss-deployment-structure (com.sun.xml.bind, javax.xml.bind.api,...) and also tried the opposite to add them as dependencies

However nothing worked so far. Any ideas how to fix this?


Solution

  • I found two working solutions:

    1. Adding a startup property to the wildfly startscript -Djavax.xml.bind.JAXBContextFactory=com.sun.xml.bind.v2.ContextFactory
    2. Aligning the JAXB libraries of my application with the wildfly JAXB libs

    Background and some details for the 2nd solution:

    The JAXB used in wildfly 19 has been updated (cp. 1,2). Since nothing worked I started debugging it. First the working version on wildfly 18 and then the non working version. The corresponding code is :

     MarshallerImpl.java:
     ...
     if( ENCODING_HANDLER.equals(name) || ENCODING_HANDLER2.equals(name)) {
                if(!(value instanceof CharacterEscapeHandler)) //<- fails here!
                    throw new PropertyException(
                        Messages.MUST_BE_X.format(
                                name,
                                CharacterEscapeHandler.class.getName(),
                                value.getClass().getName() ) );
                escapeHandler = (CharacterEscapeHandler)value;
                return;
            }
    

    But for the non working version the debugger jumped into an area which was obviously incorrect thus I knew that a different version of JAXB was used. So I did the following:

    1. I checked what jaxb version is bundled with wildfly. WILDFLY_HOME/modules/system/layers/base/com/sun/xml/bind/main
    2. I used the exact same versions in my pom.xml file

    => Then it was working!

    What I don't understand is that I tried excluding the wildfly-packaged-jaxb but that didn't help. So this will remain a mystery why my exclusion of JAXB via the jboss-deployment-structure? didn't work...