Search code examples
springjakarta-eejaxbjava-17

jakarta.xml.bind.PropertyException: name: com.sun.xml.bind.namespacePrefixMapper value - com.abc$NamespacePrefixMapperImpl@65c3d713


Migrating to java17.So moved packages to Jakarta.*.

Versions : jakarta.xml.bind-api = 4.0.0 , com.sun.xml.bind/jaxb-impl = 2.0.1

Now facing issue as:

jakarta.xml.bind.PropertyException: name: com.sun.xml.bind.namespacePrefixMapper value: com.abc$NamespacePrefixMapperImpl@65c3d713 at jakarta.xml.bind.helpers.AbstractMarshallerImpl.setProperty(AbstractMarshallerImpl.java:355) at org.glassfish.jaxb.runtime.v2.runtime.MarshallerImpl.setProperty(MarshallerImpl.java:492)

If I moved - com.sun.xml.bind/jaxb-impl to 4.0.2, I don not see - NamespacePrefixMapper.

After changing to org.glassfish.jaxb:jaxb-runtime, I see errors as: "jakarta.xml.bind.PropertyException: name: org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper value: com.fusionone.wsg.provision.resource.BaseMarshaller$NamespacePrefixMapperImpl@4cd619db at jakarta.xml.bind.helpers.AbstractMarshallerImpl.setProperty(AbstractMarshallerImpl.java:355) at org.glassfish.jaxb.runtime.v2.runtime.MarshallerImpl.setProperty(MarshallerImpl.java:492)

More code :

     public static String      NAMESPACE_PROPERTY         = 
     "org.glassfish.jaxb.runtime.marshaller.
     NamespacePrefixMapper";
     public static String A1NAMESPACE  = "a1";
     public static String NO_NAMESPACE = "";
     public static String NAMESPACEURI                     ="http://www.example.com/xmlns/a1";

    public BaseMarshaller(JAXBContext jaxContext) throws         JAXBException {
        this(jaxContext, Constants.SCHEMA_LOCATION);
    }
    
    public BaseMarshaller(JAXBContext jaxContext, String             schemaLocation) throws JAXBException {
        m = jaxContext.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,            Boolean.TRUE);
        m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,            schemaLocation);
        m.setProperty(Constants.NAMESPACE_PROPERTY, new           NamespacePrefixMapperImpl());-> **this is giving exception**
    }


    new NamespacePrefixMapperImpl() calls , below :
        public static class NamespacePrefixMapperImpl  extends          NamespacePrefixMapper {
    
        @Override
        public String getPreferredPrefix(String namespaceUri,             String suggestion, boolean arg2) {
            if (Constants.NAMESPACEURI.equals(namespaceUri)) {
                return Constants.A1NAMESPACE;
            }      
                        return Constants.NO_NAMESPACE;
        }
    }

Solution

  • When moving to JAXB4, you should use the following instead of com.sun.xml.bind:jaxb-impl :

    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>4.0.4</version> <!-- latest version at the moment -->
    </dependency>
    

    You should also align major version number between api and impl.

    The namespace prefix mapper has been moved from com.sun.xml.bind.marshaller.NamespacePrefixMapper to org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper.