JAX-WS, CXF and SAAJ on Oracle Weblogic 10.3
Recently I had to get JAX-WS based webservices running on Weblogic 10.3. However instead of using the default Weblogic 10.3 stack (Metro), the Apache CXF stack had to be used. Why? We required SOAP over JMS capabilities and that is possible with CXF without much effort.
According to the CXF user documentation, a change to the weblogic-application.xml and packaging the CXF jars in the EAR should be enough for deploying on Weblogic.
javax.jws.*
And if building with maven, the pom.xml would have the following dependencies defined :
org.springframework
spring
2.5.6
org.apache.cxf
cxf-rt-core
${cxf.version}
org.springframework
spring-core
com.sun.xml.bind
jaxb-impl
org.codehaus.woodstox
wstx-asl
org.apache.geronimo.specs
geronimo-javamail_1.4_spec
org.apache.geronimo.specs
geronimo-annotation_1.0_spec
org.apache.geronimo.specs
geronimo-activation_1.1_spec
org.apache.cxf
cxf-rt-frontend-jaxws
${cxf.version}
javax.xml.soap
saaj-api
com.sun.xml.messaging.saaj
saaj-impl
com.sun.xml.bind
jaxb-impl
org.codehaus.woodstox
wstx-asl
org.apache.geronimo.specs
geronimo-javamail_1.4_spec
org.apache.geronimo.specs
geronimo-activation_1.1_spec
org.apache.cxf
cxf-rt-transports-http
${cxf.version}
org.springframework
spring-web
org.apache.cxf
cxf-rt-transports-jms
${cxf.version}
org.springframework
spring-jms
org.apache.geronimo.specs
geronimo-jms_1.1_spec
org.apache.cxf
cxf-rt-management
${cxf.version}
org.springframework
spring-core
org.apache.cxf
cxf-common-utilities
${cxf.version}
org.springframework
spring-core
org.springframework
spring-beans
org.springframework
spring-context
org.apache.geronimo.specs
geronimo-stax-api_1.0_spec
org.apache.geronimo.specs
geronimo-annotation_1.0_spec
However that setup was sufficient for the simplest of webservices. Our services used many more JAX-WS annotations to control parameter names, namespaces, operation names, soapbindings, WS-Addressing, etc. We also used the JAX-WS handler framework for custom processing of soap headers.
These type of webservices led to a scenario where JAX-WS Soap handlers defined in CXF had to process an incoming soap message whose first element in the soap body had a namespace prefix.
World
When deploying these services on Weblogic, we ended up having to deal with SAAJ (SOAP with Attachments API for Java) problems caused by the combination of JAX-WS Soap handlers, CXF and a namespace prefixed element in the soap body.
The first error encountered was :
java.lang.UnsupportedOperationException: This class does not support SAAJ 1.1
at weblogic.webservice.core.soap.SOAPPartImpl.createElementNS(SOAPPartImpl.java:820)
at org.apache.cxf.staxutils.W3CDOMStreamWriter.writeStartElement(W3CDOMStreamWriter.java:132)
at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.writeSoapEnvelopeStart(SoapOutInterceptor.java:118)
It turns out that Weblogic’s default SAAJ implementation, in package weblogic.webservice.core.soap, is flawed.
But there is a second “good” implementation that resides in the weblogic.xml.saaj package and supports SAAJ 1.3.
To enable the SAAJ 1.3 implementation, the system property
-Djavax.xml.soap.MessageFactory=weblogic.xml.saaj.MessageFactoryImpl
had to be added to the Weblogic startup script.
The next problem encountered demonstrated that the “good” implementation was not that good at all.
java.lang.AssertionError: UNIMPLEMENTED
at weblogic.xml.domimpl.NodeImpl.setPrefix(NodeImpl.java:173)
at org.apache.cxf.staxutils.StaxUtils.startElement(StaxUtils.java:724)
at org.apache.cxf.staxutils.StaxUtils.readDocElements(StaxUtils.java:791)
at org.apache.cxf.binding.soap.saaj.SAAJInInterceptor.handleMessage(SAAJInInterceptor.java:168)
at org.apache.cxf.jaxws.handler.soap.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:78)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.getOpQName(SOAPHandlerInterceptor.java:294)
at org.apache.cxf.jaxws.handler.AbstractJAXWSHandlerInterceptor.
setupBindingOperationInfo(AbstractJAXWSHandlerInterceptor.java:111)
at org.apache.cxf.jaxws.handler.soap.SOAPHandlerInterceptor.
createProtocolMessageContext(SOAPHandlerInterceptor.java:235)
As a work around we had to fall back to the default SAAJ implementation present in the JSE6 runtime instead of using any of the Weblogic implementations. The JSE6 implementation can be enabled by setting the following system property in the Weblogic startup script:
-Djavax.xml.soap.MessageFactory=com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
This works on both the SUN and the JRockit JVM. JAX-WS webservices running on the CXF stack and the default Weblogic stack can now be deployed in the same Weblogic domain without getting in each others way.
So far the work around appears to be working fine. Will keep you posted if any other problems may arise.
Look at our consultancy services, training offers and careers below or contact us at info@xebia.com
Comments
[…] JAX-WS, CXF and SAAJ on Oracle Weblogic 10.3 | Xebia Blog – JAX-WS webservices running on the CXF stack and the default Weblogic stack can now be deployed in the same Weblogic domain without getting in each others way. […]
Thanks Ravan. I was facing some problem with class loaders with the application devloped with spring and CXF and am able to solve it by adding.
“-Djavax.xml.soap.MessageFactory=com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl ” to weblogic start up script.
There were so many solutions like adding some jars to startup class path etc. But this one is simple and it solved the problem.
Good work. Thanks again.
What about if you have services that use soap 1.1 and soap 1.2?
thanks,
Domenic
Could you attach a zip file with a complete example (to view the .xml configuration files and the other files).
Thanks,
Frank
This issue has been fixed in CXF version 2.4 and 2.3.4
https://issues.apache.org/jira/browse/CXF-3363
Hi, I posted presoiuvly regarding:java.lang.NoClassDefFoundError: org/apache/cxf/ws/policy/PolicyException..when running integration tests.This issue was resolved by me changing the dependency cxf-rt-frontend-jaxrs from version 2.6.0-SNAPSHOT to version 2.5.1.Thanks
[…] Whenever I tried to run my application in my integrated weblogic 10.3. After some research on net I found out the fix for this here […]
Thanks Ravan. I was getting the same error in tomcat for application developed with cxf. It was resolved when the below was added in catalina.bat
-Djavax.xml.soap.MessageFactory=com.sun.xml.internal.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl
Thanks again for the solution.
Thank you so much… I think this will help me
Hi,
I am facing the same issue here
I am testing the web service with soapUI 4.0.0
getting the error when i am requesting something::
“This class does not support SAAJ 1.1”
My App server is weblogic 10
plz help me its urgent
[…] * WebLogic 10.x and CXF CXF on WebLogic 10.x will meet “This class does not support SAAJ 1.1″ issue. To solve, refer to this topic: “JAX-WS, CXF and SAAJ on Oracle Weblogic 10.3″ (“http://blog.xebia.com/2009/07/14/jax-ws-cxf-and-saaj-on-oracle-weblogic-103/“). […]
Thanks. This issue resolved a problem our team was experiencing using Oracle WebLogic Server 10.3/10.34 and the JAX-WS/CXF SOAP stacks. Implementing the MessageFactory for SOAP 1.1v works, as well we were using the CXF 2.2.2v implementation noticing that CXF 2.3.4 and 2.4 fixed the issues as well.
Thanks much.
Antonio
Thank you for posting this. It resolved our issue using CXF 2.2.10 with WebLogic 10.3.4.
[…] é porque é a implementação do SAAJ padrão do WebLogic é falha, conforme descrito nesse outro post. Como work-around segundo o artigo, seria só passar o seguinte parâmetro na inicialização do […]
I’ve been around the web finding lot of options and this is the perfect one……. Thanks a lot Ravan Naidoo..
Hi, I was facing the same SAAJ1.1 issue with weblogic 10.3.5 and resolved it by modifying start weblogic script as suggested. After that SAAJ issue got resolved but I face another error “java.lang.string cannot be cast to javax.xml.soap.SOAPElement” for the following code:
/** Use SAAJ to convert Document to SOAPElement
* Create SoapMessage **/
msgFactory = MessageFactory.newInstance();
message = msgFactory.createMessage();
soapBody = message.getSOAPBody();
/** This returns the SOAPBodyElement
* that contains ONLY the Payload **/
payLoad = (SOAPElement)soapBody.addDocument(doc);
where payload is an object of SOAPElement class and soapBody is an element of SOAPBody class.
I doubt that can it be because of pointing to a different implementation of SAAJ or a different issue?
Please help me to resolve this as this is urgent.
Please let me know If I have to include any jar files/folders
Great article! However, I tried the weblogic script above but to no avail. Actually this post solved my issue.
http://cxf.547215.n5.nabble.com/Running-CXF-WSS4J-on-Weblogic-td5626091.html
I just changed -Djavax.xml.soap.MessageFactory to -Dorg.apache.cxf.binding.soap.messageFactoryClassName
There are some caveats though, as mentioned by the author
1) all cxf stack in the same app server will be affected.
2) it is implemented only for SOAP 1.1
But until any other better solution (I search quite a lot) is found, I just had to stick with this solution.
I figured out another way without changing the weblogic startup script (which in production environment is not desirable)
1) Include saaj-impl.jar in your classpath. If you are using maven, put the dependency on pom.xml
2) in your weblogic.xml, put this in container descriptor to override weblogic implementation
com.sun.xml.messaging.saaj.*
3) By right, CXF should get the correct SAAJ implementation