Tuesday, October 16, 2007

JAXRPC Error - java.lang.ClassCastException

at com.sun.xml.rpc.client.StubBase._postSendingHook(StubBase.java:231)
at com.sun.xml.rpc.client.StreamingSender._send(StreamingSender.java:324)
at com.bamnetworks.services.boc.csp.client.impl.jaxrpc.generated.CspWsInterface_Stub.getPlanSummary(CspWsInterface_Stub.java:86)
at com.bamnetworks.services.boc.csp.client.CspClient.getMnCollegescholarshipInterface(CspClient.java:63)

JAXRPC client resides inside Axis2 container.
The following jars are included in the Axis2 service lib: saaj-api.jar and saaj-impl.jar.

However, the Axis2 container also contains the following jar: axis2_saaj-1.1.jar

possible causes:
The above two jars are conflicting with each other. What is happening is that the axis2 saaj implementation of the message factory is being used instead of the sun saaj implementation of the message factory.

Therefore, the axis2 saaj implementation is creating messages that the JAX-RPC client is not expecting. It is expecting Message objects of a different type.

Axis2 saaj Message class: org.apache.axis2.saaj.SOAPMessageImpl
Sun saaj Message class: com.sun.xml.messaging.saaj.soap.MessagingImpl

It is this discrepancy in the classes that is causing the above ClassCastException. Within the StubBase it is expecting the type to be of the Sun implementation, but instead is getting the Axis 2 implementation.


solution 1) Setting a system property and moving jars to the Axis 2 container lib

Move the saaj-impl.jar and FastInfoSet.jar to the Axis2 container lib from the Axis2 service's lib.

Then, within the code, set a system property that indicates which message factory should be used to construct SOAP messages for web services before the JAX-RPC client operation is called, as in the following code:

System.setProperty("javax.xml.soap.MessageFactory", "com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Imp");

solution 2) Keep the JAXRPC jars in the service lib directory and modify the JAXRPC stub to use the correct MessageFactory.

This is particularly a hacky way of embedding a JAXRPC client within a Axis2 service, but this seems to be the only way to do without including the JAXRPC client jars in the Axis2 container lib.

In this solution, you need to modify the JAXRPC stub to

a) Create a custom MessageContext that extends from com.sun.xml.rpc.soap.message.SOAPMessageContext

In this custom class, override the methods called createMessage(useFastInfoset, acceptFastInfoset) and
createMessage(useFastInfoset, acceptFastInfoset) to use the com.sun.xml.messaging.saaj.soap.ver1_1.SOAPMessageFactory1_1Impl() as the MessageFactory.

b) Create a custom ClientTransport that extends from HttpClientTransport.

In this custom class, override the readResponse() method.

1 comment:

Gowtham said...

Thx dude ,
resolved the issue
Ganesh Gowtham