Broshet
Broshet

Reputation: 289

Java migration JDK 11 to JDK 17 fail Junit Test with Jakarta Marshal

I have an application on JDK11 with Spring Boot 2.7.11 and a Junit Test that use jaxb javax.xml.bind.Marshaller. All is OK

But I have to migrate to JDK17 with Spring Boot 2.7.18. So I have replace all my import of javax.xml.bind by jakarta.xml.bind.

After that, my Junit Test is failed becaus marshal produce XML object with wrong encoding char

 try {
      final JAXBContext jaxbContext = getJaxbContext(classes);
      marshaller = jaxbContext.createMarshaller();
      marshaller.marshal(object, bos);
    } catch (final JAXBException ex) {
      throw new HttpMessageConversionException(
          "Could not create Marshaller for class [" + classes + "]: " + ex.getMessage(), ex);
    }

On marshaller.marshal(object, bos);, object contain all correct charecter but after marshaller, charter ar not ok

Before Marshal : lorsDe=Retour à la maison

After Marsha in XML : <LORS_DE>Retour à la maison</LORS_DE>

I don't understand where is the problem. Can you help me ?

Upvotes: 0

Views: 2446

Answers (5)

Swavek L
Swavek L

Reputation: 21

I was migrating to Spring 6 and Java 17, compiling under Java 17. My solution was to create a special CharacterEscapeHandler class and pass it via properties to the marshaller & unmarshaller.

The default MinimumEscapeHandler wasn't handling \t character translation, only \r\n was working correctly. It took me a while to track down this handler. My needs were special because my attribute value contained \t. This may not be needed if you don't anticipate to handle this character.

Upvotes: 0

Serkan
Serkan

Reputation: 1225

The issue is with JDK17.

The default file encoding was UTF8 before JDK17, now it’s not UTF8 anymore.

You have to set it explicitly to UTF8 with:

‘java -jar -Dfile.encoding=UTF-8 myapp.jar”

You have to set this in your Dockerfile and also for your unit tests via the Maven surefire plugin.

Upvotes: 2

Laurent Schoelens
Laurent Schoelens

Reputation: 2848

If you're targeting SpringBoot 2.7.18 (even with JDK17), you should stick to javax imports.

jakarta support was introduced in SpringBoot 3.x as part of the Spring 6 plan to move to JakartaEE9 and JDK17 baseline

See this post from Spring blog for reference

Upvotes: 1

Broshet
Broshet

Reputation: 289

I found it !

MArshaller work well, but just after, xml is return with bos.toString. I have to indicate it that it's UTF8

return bos.toString(StandardCharsets.UTF_8);

Upvotes: 0

Aamir Ali
Aamir Ali

Reputation: 1

It seems like you're facing an issue with character encoding after migrating from javax.xml.bind to jakarta.xml.bind. In newer versions, there might be changes in default settings that affect the encoding behavior.

Try setting the encoding explicitly in your Marshaller:

try {
     final JAXBContext jaxbContext = getJaxbContext(classes);
      marshaller = jaxbContext.createMarshaller();

      // Set encoding explicitly
     marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

     marshaller.marshal(object, bos);
} catch (final JAXBException ex) {
     throw new HttpMessageConversionException(
        "Could not create Marshaller for class [" + classes + "]: " + 
     ex.getMessage(), ex);
}

Make sure to replace "UTF-8" with the appropriate encoding you are using in your application.

Additionally, check if there are any other properties that need to be set for compatibility with the new version. You can refer to the documentation or release notes of the Jakarta XML Binding (JAXB) implementation you are using for any additional configuration changes.

Upvotes: 0

Related Questions