Migrating from JAX-RPC to JAX-WS

Here is some of the issues that we encountered during migration of the OpenPortal WSRP Project from JAX-RPC to JAX-WS. The following note does not go into details on why these changes are required and the concepts behind it, rather a quick note that helps you to deal with migrating your application from the older webservice stack to new stack.

Consider leaving a note if you have faced a different issue and solved it, so that it would benefit other.

Note : The following note is based on the assumption that you already have a wsdl and schema and you are implementing a webservice based on these.

If you are migrating from JAX-RPC to JAX-WS, you are sure to come across the JAXB changes, since JAX-WS now uses JAXB binding rather  than defining its own binding. So here is some details on JAXB migration first.

A. JAXB Migration:

Using the new XJC compiler generates generics based code as compared to the older JAXB compiler. Most of the changes are straight forward where we had to convert array objects to List<ObjectType>

Old XJC compiler :

    MarkupType[] getMarkupTypes(String portletName)
 
New XJC compiler:

    List<MarkupType> getMarkupTypes(String portletName)

Collections in JAXB:

    With the above changes in return type. While adding collection objects to we need to get the list and then add to it

In older JAXB :
        
    MarkupType[] markupTypes = new MarkupType[10]'
    //add values to above array
    markupTypes[0] = new MarkupType();
    .....
    ....
    PortletDescription pd = new PortletDescription(markupTypes, blah, blah);

In the new JAXB :

    PortletDescription pd = new PortletDescription();
    List<MarkupType> markupTypes = pd.getMarkupTypes();
    markTypes.add(new MarkupType());

As you can see there were 2 differences ,

1. The generated code is initialized using the default constructor , unlike the old JAXB , generated code constructors do not take all the parameters

2. The collection is added by obtaining the list from the object to which you are adding. Do not create a new java.util.List object always obtain from the parent object and add to it.

jaxb.properties:

The older JAXB compiler generated  the jaxb.properties for each binding, the new xjc compiler does not generate the jaxb.properties. So don't look for this if your are packaging

Marshalling and Unmarshalling :

The new JAXB runtime expects the marshalled objects to be of type JAXBElement, If you see exceptions related to @XmlRootAnnotation, that is because the object that you are serializing is not of type JAXBElement. Here is the snippet on old and new JAXB generated code usages

Old Code :

       ObjectFactory objectFactory = new ObjectFactory();
       FilePersistedWSRPProducers producers =  objectFactory.createFilePersistedWSRPProducers();
       FileOutputStream fos = new FileOutputStream(file);
       marshaller.marshal(producers,fos);   

New Code :

               FilePersistedWSRPProducers defaultProducers =  objectFactory.createFilePersistedWSRPProducers();
               JAXBElement<FilePersistedProducers> rootElement =
                        objectFactory.createFilePersistedWSRPProducers(defaultProducer);
                FileOutputStream fos = new FileOutputStream(file);
                marshaller.marshal(rootElement,fos);

B. JAX-WS Migration :

1.0 Compiler : A. The wscompile in JAX-RPC is replaced with wsimport in JAX-WS, use this compiler to generate the code. The JAX-WS implementation uses the JAXB binding unlike the older JAX-RPC stack, so you'll face most of the issues that are described above in the JAXB migration.

B. The generated code would be slightly different than the old stack. Mostly
  1. Signature changes in terms of
    1. Usage of holder objects
    2. Changes in enumeration
    3. Faults
    4. Arrays to List as indicated above in JAXB
  2. Annotating the webservice implementation with javax.jws.WebService
Enumeration Changes :

JAX-RPC : The old JAX-RPC code enumerations can be accessed as static variables from generated code
CookieProtocol requiresInitCookie = CookieProtocol.none;

JAX-WS : In JAX-WS the enumeration object creation is as follows.
CookieProtocol requiresInitCookie = CookieProtocol.fromValue("none");

Usage of Holder Objects :
JAX-WS uses Holder objects extensively. Here is a snippet on how to use it on the client side and server side

Client side:
Holder<MarkupContext> markupContextHolder= new Holder(MarkupContext());


ServerSide:
MarkupContext markupContext = markupContextHolder.value;

Annotations: The purpose of this annotation is to mark a endpoint implementation as implementing a web service or to mark that a service endpoint interface as defining a web service interface. All endpoint implementation classes must have a WebService annotation , for eg :

@javax.jws.WebService(endpointInterface="com.sun.portal.wsrp.common.stubs.WSRPV1MarkupPortType")

2. Deployment descriptor :

A.The JAX-WS stack expects the sun-jaxws.xml file rather than the jaxrpc-ri.xml file. Most of the contents in the new xml file is same as  that of the older file. There is no need or equivalent to wsdeploy. So if you have used wsdeploy , it would generate the  jaxrpc-ri-runtime.xml, use this file as it would have most of the information to populate the sun-jaxws.xml

B. web.xml: Use the JAX-WS servlet and the listener rather than the old JAX-RPC servlet, here is the snippet
Old web.xml

    <listener>
        <listener-class>com.sun.xml.rpc.server.http.JAXRPCContextListener</listener-class>
    </listener>

    <servlet>
        <description>JAX-RPC endpoint - WSRPPortletManagementService</description>
        <servlet-name>WSRPPortletManagementService</servlet-name>
        <servlet-class>com.sun.xml.rpc.server.http.JAXRPCServlet</servlet-class>
    </servlet>

New web.xml:

<listener>
        <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>

    <servlet>
        <description>JAX-WS endpoint - WSRPPortletManagementService</description>
        <servlet-name>WSRPV1PortletManagementPortType</servlet-name>
        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
    </servlet>


3.0 Client Port Lookup:
At the client side the old JAX-RPC stub creation and port look up is as follows

        Stub getNonDynamicStub = (Stub)(new WSRPService_Impl().getWSRPBaseService());
         getNonDynamicStub._setProperty(Stub.ENDPOINT_ADDRESS_PROPERTY, endpoint);
         WSRP_v1_Markup_PortType port =  (WSRP_v1_Markup_PortType) getNonDynamicStub;


New JAX-WS port lookup is as follows

      WSRPV1MarkupPortType port =  new WSRPService(new URL(wsdlURL),  new QName("urn:oasis:names:tc:wsrp:v1:wsdl", "WSRPService")).getWSRPBaseService();        

Note the change is classname of WSRP_v1_Markup_PortType to WSRPV1MarkupPortType from JAX-RPC to JAX-WS which is noted above is a example of another difference in code generated between the two stacks

C. XWS Migration:

If you had used XWS especially using the "-security" option in wscompile, here is how to migrate the configuration.  The simplest way to migrate this is to add the XWS configuration to the WEB-INF i.e place this file along with sun-jaxws.xml during deployment. The name of the deployment files should be
  1. server_security_config.xml for server side XWS configuration
  2. client_security_config.xml for client side XWS configuration
For client side XWS, alternatively you could write a SOAPHandler and add the security handler to the SOAP handler during invoking the webservice port from the client

            WSRPV1MarkupPortType port = new WSRPService(new URL(wsdlURL),  new QName("urn:oasis:names:tc:wsrp:v1:wsdl", "WSRPService")).getWSRPBaseService();              
                BindingProvider provider = (BindingProvider)port;
    String endpointURL = (String)(provider.getRequestContext().get(javax.xml.ws.BindingProvider.ENDPOINT_ADDRESS_PROPERTY));
                List<Handler> chain = new ArrayList<Handler>();
                chain.add(new ConsumerSecurityHandler(endpointURL));
                provider.getBinding().setHandlerChain(chain);                                

Where ConsumerSecurityHandler is SOAPHandler<SOAPMessageContext>, See sample/code here

D. Where to go for help :

I know that I have capture only few issues that we have encountered. If you are still stuck I'd recommend getting the JAXB and JAX-RPC code and start debugging by hooking the netbeans debugger and stepping through the code. This will help you with most of time , else there is Metro project post you questions to users@metro.dev.java.net
Comments:

Hello Rajesh
I have one query
We have implemented the webservice with jaxrpc api now we want to migrate to jaxws, is it possible to keep the existing webservice by changing only the client with jaxws api? or we will have to change the server also with jaxws

please give your suggession on this

thanks and regards

Posted by P Shetkar on November 26, 2007 at 09:06 AM IST #

Hi Shetkar,

Yes you can migrate just the client to the JAX-WS and our server can still be in JAX-RPC. AFAIK JAX-WS is over the wire backward compatible with JAX-RPC

In fact while doing the above migration we change the server first and had a separate install of client which was still on JAX-RPC.

HTH
regards
Rajesh T

Posted by Rajesh T on November 27, 2007 at 02:53 AM IST #

Hi Rajesh
First of all thanks for ur reply
See i am using the same server which is using jax-rpc and generated new classes for client using wsimport utility with jaxws

Now it is creating the soap object, but when i try to call any method it gives me the following err

javax.xml.ws.WebServiceException: HTTP transport error: java.net.ConnectException: Connection timed out: connect
at com.sun.xml.ws.util.SOAPConnectionUtil.send(SOAPConnectionUtil.java:107)
at com.sun.xml.ws.util.SOAPConnectionUtil.sendResponse(SOAPConnectionUtil.java:113)
at com.sun.xml.ws.protocol.soap.client.SOAPMessageDispatcher.doSend(SOAPMessageDispatcher.java:284)
at com.sun.xml.ws.protocol.soap.client.SOAPMessageDispatcher.send(SOAPMessageDispatcher.java:153)
at com.sun.xml.ws.encoding.soap.internal.DelegateBase.send(DelegateBase.java:85)
at com.sun.xml.ws.client.EndpointIFInvocationHandler.implementSEIMethod(EndpointIFInvocationHandler.java:176)
at com.sun.xml.ws.client.EndpointIFInvocationHandler.invoke(EndpointIFInvocationHandler.java:105)
at $Proxy20.getOrderByPon(Unknown Source)

my earlier client with jaxrpc works fine but this gives me above err, can u plz suggest some solution to this

Thanks and regards
P. Shetkar

Posted by guest on November 27, 2007 at 05:03 AM IST #

From the stack it looks like a connection issue, Check if you are able to access the server from your client box... proxy setting etc.

I'd recommend you use the users@metro.dev.java.net alias for such questions. All the JAX\* development team monitors this alias.

regards
Rajesh T

Posted by Rajesh T on November 27, 2007 at 07:26 AM IST #

I get a RPC/Encoded wsdls are not supported in JAX-WS 2.0.

Posted by Mike on February 21, 2008 at 08:55 PM IST #

Im trying to run 'Application Client' code from sun tutes for ws samples - (for j2ee1.4 on glassfish9-JEE5) he Context.lookup is returning a WSServiceDelegate object and cant be cast to the MyHelloService class. Its a problem with the JNDI lookup returning a jax-ws instead of the older rpc-Service i stronly suspect.

Any suggestions please. thanx ;-)

Posted by koko on April 12, 2008 at 05:48 AM IST #

Hi,
We got an issue which has to be fixed. it is taking long time, alomost a week

We have an application running on jboss-4.0.3SP1 which uses web services (axis web services). The web services are invoked by Oracle procedures.

Now ,we are trying to migrate our application to Jboss 4.2.3GA.
However the existing web services are failing, throwing the following exception.

JAXRPC SOAP request exception javax.xml.rpc.soap.SOAPFaultException: Endpoint http://localhost:8080/jmxclient/Jmxclientinvoker JMXClientInvokerSeiPort does not contain operation meta data for: http://127.0.0.1:8080/ sendTextmessage

It seems Jboss 4.2.3GA does not support webservices that are created using axis, we could not find any axis related jars in the Jboss 4.2.3GA server.

Jboss-4.0.3SP1 uses Axis based web services and Jboss-4.2.3GA uses JbossWS.

In that case looks like there is no backward compatibility .

What will be the problem? and How to move the existing web services to the new server Jboss4.2.3GA

Thanks,
Prabhu

Posted by Prabhu on August 08, 2008 at 02:40 PM IST #

Post a Comment:
Comments are closed for this entry.
About

trajesh

Search

Categories
Archives
« July 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today