1

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?

Lonzak
  • 9,334
  • 5
  • 57
  • 88
  • Might be a classloading problem, one option that could work is to set all jaxb dependencies as provided – k5_ Nov 15 '21 at 15:48
  • That is not possible since the deployment package is deployed on many different JEE application servers Wildfly, jboss, websphere, weblogic ...) and sometimes different versions of a server. The solution can only be to exclude the wildfly provided packages... – Lonzak Nov 15 '21 at 17:48

2 Answers2

1

I was able to fix this adding the following jboss-deployment-structure.xml to the application (in WEB-INF folder):

<?xml version="1.0"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <deployment>
        <exclude-subsystems>
            <subsystem name="webservices" />
        </exclude-subsystems>
        <exclusions>
            <module name="javax.xml.bind.api" />
        </exclusions>
    </deployment>
</jboss-deployment-structure>
xonya
  • 2,146
  • 29
  • 37
0

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...

Lonzak
  • 9,334
  • 5
  • 57
  • 88