<property name="namespacePrefixes" ref="namespaceMap" /> causes exception due 
to immutable Map being used in JAXBElementProvider
--------------------------------------------------------------------------------------------------------------------------------

                 Key: CXF-3946
                 URL: https://issues.apache.org/jira/browse/CXF-3946
             Project: CXF
          Issue Type: Bug
          Components: JAX-RS, JAXB Databinding
    Affects Versions: 2.5
            Reporter: Miguel Martins Feitosa Jr.
            Priority: Trivial


 I was trying to set a specific namespace prefix for a qualified REST xml.

I configured beans.xml and included package-info.java as below:

@javax.xml.bind.annotation.XmlSchema(    namespace=GoldenKey.NS,
                                        elementFormDefault = 
javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
                                        attributeFormDefault = 
javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
                                        
xmlns={@javax.xml.bind.annotation.XmlNs(prefix = GoldenKey.NS_QUALIFIER , 
namespaceURI=GoldenKey.NS)}
                                     )

package com.upmc.tdc.xml;


beans.xml snippets:

     <jaxrs:server id="goldenKey_rest" address="/rest">
       <jaxrs:serviceBeans>
         <ref bean="goldenKey_bean" />
       </jaxrs:serviceBeans>
        <jaxrs:extensionMappings>
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
        </jaxrs:extensionMappings>
         <jaxrs:providers>
          <ref bean="dateProvider" />
          <ref bean="exceptionMapper" />
          <ref bean="jaxbProvider" />
        </jaxrs:providers>
     </jaxrs:server>
    
     <jaxws:endpoint serviceName="GoldenKey" endpointName="GoldenKeyPort" 
id="goldenKey_soap" implementor="#goldenKey_bean" address="/soap">
        <jaxws:binding>
            <soap:soapBinding version="1.2" />
        </jaxws:binding>
        <jaxws:features>
            <bean class="org.apache.cxf.feature.LoggingFeature">
                <property name="prettyLogging" value="true" />
            </bean>
        </jaxws:features>
    </jaxws:endpoint>

     <bean id="goldenKey_bean" class="com.upmc.tdc.server.GoldenKeyImpl"/>
     <bean id="dateProvider" 
class="com.upmc.tdc.server.parameterhandler.DateParameterHandler"/>
     <bean id="exceptionMapper" class="com.upmc.tdc.exception.ExceptionMapper"/>
    
     <bean id="jaxbProvider" 
class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
        <property name="marshallerProperties" ref="propertiesMap" />
         <property name="namespacePrefixes" ref="namespaceMap" />
        <property name="enableBuffering" value="true" />
    </bean>
   
     <util:map id="propertiesMap">
        <entry key="jaxb.formatted.output">
            <value type="java.lang.Boolean">true</value>
            <!--  prints indented XML for REST, useful for testing, can be 
disabled for production -->
        </entry>
    </util:map>
   
    <util:map id="namespaceMap">
        <entry key="http://server.tdc.upmc.com/";  value="GoldenKey"/>
    </util:map>

This setup throws the following exception:

java.lang.UnsupportedOperationException
    at java.util.AbstractMap.put(AbstractMap.java:203)
    at java.util.AbstractMap.putAll(AbstractMap.java:273)
    at 
org.apache.cxf.jaxrs.provider.JAXBElementProvider.marshalCollectionMember(JAXBElementProvider.java:327)
    at 
org.apache.cxf.jaxrs.provider.JAXBElementProvider.marshalCollection(JAXBElementProvider.java:293)
    at 
org.apache.cxf.jaxrs.provider.JAXBElementProvider.writeTo(JAXBElementProvider.java:232)
    at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.serializeMessage(JAXRSOutInterceptor.java:257)
    at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:144)
    at 
org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:83)
    at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
<clipped>

Lines 325-330 of JAXBElementProvider.java contain the following code:
        if (ns.length() > 0) {
            Map<String, String> map = Collections.singletonMap(ns, "ns1");
            map.putAll(nsPrefixes);
            setNamespaceMapper(ms, map);
        }
        marshal(obj, cls, genericType, enc, os, mt, ms);

The call Collections.singletonMap(...) is below:

 /**
     * Returns an immutable map, mapping only the specified key to the
     * specified value.  The returned map is serializable.
     *
     * @param key the sole key to be stored in the returned map.
     * @param value the value to which the returned map maps <tt>key</tt>.
     * @return an immutable map containing only the specified key-value
     *         mapping.
     * @since 1.3
     */
    public static <K,V> Map<K,V> singletonMap(K key, V value) {
        return new SingletonMap<>(key, value);
    }

So it seems that
            map.putAll(nsPrefixes);

should fail as it is failing when called because the map is immutable.

In case there are other prefixes to add it seems that the map should be of 
another type....

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators: 
https://issues.apache.org/jira/secure/ContactAdministrators!default.jspa
For more information on JIRA, see: http://www.atlassian.com/software/jira

        
  • [jira] [Created] (CXF-3946) &l... Miguel Martins Feitosa Jr. (Created) (JIRA)

Reply via email to