[ 
https://issues.apache.org/jira/browse/CXF-3363?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12999636#comment-12999636
 ] 

Gladwin commented on CXF-3363:
------------------------------

*If CXF won't deal with deployment issues for popular JEE containers like 
Tomcat/WebSphere/Weblogic/JBoss/Glassfish, etc. then it will loose a big 
market.*

For CXF to deal with classloader issues in the various J2EE servers, another 
solution is as given below.


To resolve this we should be able to force CXF to use specific message factory 
we can set as java system property by which then CXF will always return 
specified message factory instance when no protocol parameter is passed. 
Further more it should not interfere with JEE application server unless server 
itself uses CXF libraries internally.

*java ... 
-D=org.apache.cxf.binding.soap.MessageFactoryCreator.messageFactoryClassName=com.sun.xml.messaging.saaj.soap.ver1_1SOAPMessageFactory1_1Impl*


*Solution*

*In CXF code, replace* all {{MessageFactory.newInstance}} calls in CXF with 
{{MessageFactoryCreator.create}} as mentioned below:

{code:title=Original calls to be replaced|borderStyle=solid}
MessageFactory.newInstance();

MessageFactory.newInstance(someProtocol);
{code}

{code:title=New calls to be replaced with|borderStyle=solid}
MessageFactoryCreator.create();

MessageFactoryCreator.create(someProtocol);
{code}


*Define* {{org.apache.cxf.binding.soap.MessageFactoryCreator}} class in CXF
{code:title=org.apache.cxf.binding.soap.MessageFactoryCreator (This code is not 
tested)|borderStyle=solid}

package org.apache.cxf.binding.soap;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;

public class MessageFactoryCreator {

        public static final String MESSAGE_FACTORY_KEY = 
"org.apache.cxf.binding.soap.MessageFactoryCreator.messageFactoryClassName";

        public MessageFactoryCreator() {
        }

        public static MessageFactory create() throws SOAPException {
                MessageFactory messageFactory;
                String messageFactoryClassName = System
                                
.getProperty(MessageFactoryCreator.MESSAGE_FACTORY_KEY);
                if (messageFactoryClassName != null) {
                        messageFactory = 
newInstanceCxfMessageFactory(messageFactoryClassName);
                } else {
                        messageFactory = MessageFactory.newInstance();
                }
                return messageFactory;
        }

        public static MessageFactory create(String protocol)
                        throws SOAPException {
                MessageFactory messageFactory = 
MessageFactory.newInstance(protocol);
                return messageFactory;
        }

        @SuppressWarnings("unchecked")
        private static MessageFactory newInstanceCxfMessageFactory(
                        String messageFactoryClassName) throws SOAPException {
                try {
                        Class<MessageFactory> klass = (Class<MessageFactory>) 
Class
                                        .forName(messageFactoryClassName);
                        MessageFactory messageFactory = klass.newInstance();
                        return messageFactory;
                } catch (ClassNotFoundException cnfe) {
                        throw new SOAPException("Provider " + 
messageFactoryClassName
                                        + " could not be instantiated: " + 
cnfe, cnfe);
                } catch (InstantiationException ie) {
                        throw new SOAPException("Provider " + 
messageFactoryClassName
                                        + " could not be instantiated: " + ie, 
ie);
                } catch (IllegalAccessException iae) {
                        throw new SOAPException("Provider " + 
messageFactoryClassName
                                        + " could not be instantiated: " + iae, 
iae);
                }
        }

}
{code}

*Note:* This solution is derived from the fact that in Weblogic 10.3.3 server, 
there are issues as it automatically set the system property 
{{javax.xml.soap.MessageFactory}}={{weblogic.webservice.core.soap.MessageFactoryImpl}}
 hence forcing all the {{MessageFactory.newInstance()}} calls to return this 
factory by default (see javadoc of 
[javax.xml.soap.MessageFactory.getInstance()|http://download.oracle.com/javase/6/docs/api/javax/xml/soap/MessageFactory.html#newInstance%28%29]
 for explaination).

> Use MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL) instead of 
> MessageFactory.newInstance()
> -------------------------------------------------------------------------------------------------------
>
>                 Key: CXF-3363
>                 URL: https://issues.apache.org/jira/browse/CXF-3363
>             Project: CXF
>          Issue Type: Improvement
>          Components: JAX-WS Runtime, Soap Binding
>    Affects Versions: 2.3.2
>            Reporter: Gladwin
>
> When it is known that SOAP version used is 1.1 [ {{instanceof Soap11}} ], CXF 
> should use {{MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL)}} 
> instead of {{MessageFactory.newInstance()}}
> Further more by default when version is neither of 1.1 or 1.2, then instead 
> of returning {{null}}, CXF should return 
> {{MessageFactory.newInstance(SOAPConstants.DEFAULT_SOAP_PROTOCOL)}} or 
> {{MessageFactory.newInstance(SOAPConstants.DYNAMIC_SOAP_PROTOCOL)}}
> *Given below is an example of cxf code where this refactoring can be done*
> {code:title=org.apache.cxf.jaxws.binding.soap.SOAPBindingImpl.java|borderStyle=solid}
> public MessageFactory getMessageFactory() 
> {
>         if (this.soapBinding instanceof SoapBindingInfo) {
>             SoapBindingInfo bindingInfo = (SoapBindingInfo) this.soapBinding;
>             try {
>                 if (bindingInfo.getSoapVersion() instanceof Soap11) {
>                     return MessageFactory.newInstance();
>                 } else if (bindingInfo.getSoapVersion() instanceof Soap12) {
>                     return 
> MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
>                 }
>             } catch (SOAPException e) {
>                 throw new 
> WebServiceException(BUNDLE.getString("SAAJ_FACTORY_ERR"), e);
>             }
>         }
>         return null;
> }
> {code} 
> *Advantages*
> * In future, {{MessageFactory.newInstance()}} may not return object instance 
> of the default implementation that does not supports "SOAP 1.1 Protocol"
> * Some JEE Appserver implementations of {{MessageFactory.newInstance()}}, 
> currently do not return factory that supports "SOAP 1.1 Protocol"
> ** Weblogic 10.3.x [ {{weblogic.webservice.core.soap.MessageFactoryImpl}} ] 
> does not support SAAJ "SOAP 1.1 Protocol" -> 
> "{{java.lang.UnsupportedOperationException: This class does not support SAAJ 
> 1.1}}"
> * This could help ease use of CXF libraries in JEE applications even if 
> Application Server has it's own SOAP/SAAJ implementation. By above method, 
> CXF will always get {{MessageFactory}} that supports required protocol.
> *Related Isues*
> * https://issues.apache.org/jira/browse/CXF-976
> * https://issues.apache.org/jira/browse/CXF-1750
> * https://issues.apache.org/jira/browse/CXF-3307

-- 
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

Reply via email to