Skip to main content

Web services programming tips and tricks: Roundtrip issues in Java coding conventions

Russell Butek (butek@us.ibm.com), Software Engineer, IBM, Software Group
Russell Butek is one of the developers of the IBM® WebSphere® Web services engine. He is also an IBM representative on the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's AXIS SOAP engine, driving AXIS 1.0 to comply with JAX-RPC 1.0. Previously, he was a developer of the IBM CORBA ORB and an IBM representative on a number of OMG task forces: the portable interceptor task force (of which he was chair), the core task force, and the interoperability task force.
Richard Scheuerle (scheu@us.ibm.com), Software Engineer, IBM, Software Group
Richard Scheuerle is one of the developers of the IBM® WebSphere® Web services engine. He was involved in the implementation of Apache's AXIS SOAP engine. Richard has 10 years of development experience with compiler/language design. Currently he is concentrating on the Web services engine performance and API design. Richard has also worked on the development of CORBA tooling and chip validation software.

Summary:  Java APIs for XML-Based Remote Procedure Call's (JAX-RPC's) Java-to-WSDL/WSDL-to-Java mapping rules do not try to preserve Java constructs during roundtripping. Many constructs are preserved, but not all. This tip describes, in particular, why following Java coding conventions is very important to maintaining the ability to roundtrip.

Date:  02 Apr 2004
Level:  Intermediate
Activity:  972 views
Comments:  

This is the second of three tips on roundtripping and data integrity. This tip addresses the importance of following Java coding conventions. For an introduction to the concept behind roundtripping please read the previous tip as listed in the Resources section.

The Java APIs for XML-Based Remote Procedure Call (JAX-RPC) protocol (see Resources) is Java-centric, not WSDL-centric. It contains a fairly elaborate set of rules for mapping WSDL names to Java-friendly names which follow the Java coding conventions. This is good because JAX-RPC users will be Java programmers. In fact, they may not even care that your Web service is a Web service. They probably do not know or care about WSDL and XML, and all the quirks that they bring to the table. All they may care about is that they can write Java code to call your service and expect the JAX-RPC APIs for your service to look familiar; in other words, to follow Java coding conventions.

However, the drawback to this approach is that your original Java service must follow Java coding conventions to begin with in order to avoid roundtripping issues. If you start with a Java application which does not follow Java coding conventions, your code will not roundtrip because the resulting code will follow the Java coding conventions.

A scenario in detail

Let's start with a simple example. The use case in which roundtripping issues arise is when you expose an existing application as a Web service. Assume that an existing application implements the interface and bean in Listings 1 and 2. You will notice that there are a lot of violations of the Java coding conventions. (Besides showcasing Java coding convention problems, this example also presents java.util.Date, which we showed, in the first roundtrip tip, to not be roundtripable.)


Listing 1. Population application interface
package com.ibm.developerWorks.roundtrip;

public interface population {
    public life GetALife();
}


Listing 2. Life bean
package com.ibm.developerWorks.roundtrip;

public class life {
    public java.util.Date birthday;
    public java.util.Date deathday;
}

To expose this application as a Web service, the first thing you do is run the population interface through your favorite JAX-RPC Java-to-WSDL tool. If you tell that tool to generate a RPC/literal binding, you should end up with a WSDL file similar to the one in Listing 3.


Listing 3. Population application's WSDL
<?xml version="1.0" encoding="UTF-8"?>
<definitions
    targetNamespace="http://roundtrip.developerWorks.ibm.com"
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:impl="http://roundtrip.developerWorks.ibm.com"
    xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/">
  <types>
    <schema
        targetNamespace="http://roundtrip.developerWorks.ibm.com"
        xmlns="http://www.w3.org/2001/XMLSchema"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <complexType name="life">
        <sequence>
          <element name="deathday" nillable="true" type="xsd:dateTime"/>
          <element name="birthday" nillable="true" type="xsd:dateTime"/>
        </sequence>
      </complexType>
    </schema>
  </types>
  <message name="GetALifeRequest"/>
  <message name="GetALifeResponse">
    <part name="GetALifeReturn" type="impl:life"/>
  </message>
  <portType name="population">
    <operation name="GetALife">
      <input message="impl:GetALifeRequest" name="GetALifeRequest"/>
      <output message="impl:GetALifeResponse" name="GetALifeResponse"/>
    </operation>
  </portType>
  <binding name="populationSoapBinding" type="impl:population">
    ...
  </binding>
  <service name="populationService">
    ...
  </service>
</definitions>

Once you have the WSDL file, you will have to generate artifacts. The application's Web services EAR file will require these artifacts. These generated artifacts are deployment descriptors and helper classes. You generate them using your favorite WSDL-to-Java tool, completing the round trip from Java language to WSDL and back to Java language. These generated artifacts will obey Java coding conventions.

If roundtripping were perfect, you could simply bundle your original application code into an EAR file with the generated artifacts and you would have yourself a merry little Web service. But roundtripping isn't perfect. The generated artifacts assume that the application code follows Java coding conventions. In other words, they assume the application is made up of Population and Life classes, but your original classes are population and life. See listings 4 and 5 to see what the artifacts generated from the WSDL in listing 3 assume the Population and Life classes look like. Please note the inconsistencies highlighted below between the original Java code and the expected Java code.


Listing 4. Population service endpoint interface generated from the WSDL
package com.ibm.developerWorks.roundtrip;

public interface Population extends java.rmi.Remote {
    public Life getALife() throws java.rmi.RemoteException;
}


Listing 5. Life bean generated from the WSDL
package com.ibm.developerWorks.roundtrip;

public class Life implements java.io.Serializable {
    public java.util.Calendar getBirthday() {...}
    public void setBirthday(java.util.Calendar birthday) {...}
    public java.util.Calendar getDeathday() {...}
    public void setDeathday(java.util.Calendar deathday) {...}
public boolean equals(java.lang.Object obj) {...} public int hashCode() {...} }

Other inconsistencies

Notice that in listings 4 and 5 there are a number of differences which we did not highlight: Population now extends Remote; getALife now throws RemoteException; Life now extends Serializeable; Life now has explicit equals and hashCode methods. While these differences might cause problems, they rarely prevent you from turning an existing application into a Web service.

Try building an EAR file with your original code and the generated artifacts. At best, you will get a build-time or install-time error. At worst, the EAR file will build and install successfully, but you will get some obscure runtime error that will take you days to debug. So, you can see why it is important to understand the inconsistencies between your original code and what the generated artifacts assume your code looks like.

Table 1 summarizes all of the inconsistencies which have arisen because the original Java code did not follow the Java coding conventions.


Table 1. Java constructs which do not round trip
ProblemJava-to-WSDL-to-JavaFrom the example
Date becomes Calendarjava.util.Date

xsd:datetime

java.util.Calendar
Life's "birthday" and "deathday" properties
Case changes in bean nameclass bean {
}

<complexType name="bean">
</complexType>

class Bean {
}
Class name life vs Life
Case change in interface name and method namesinterface y {
  void A();
}

<portType name="y">
  <operation name="A">
    ...
  </operation>
</portType>

interface Y {
  void a();
}
Interface name population vs Population
and method name GetALife vs getALife
Public instance variable vs accessorsclass Bean {
  public int a;
}

<complexType name="Bean">
  <sequence>
    <element name="a" type="int"/>
  </sequence>
</complexType>

class Bean {
  public void setA(int a);
  public int getA();
}
Life's "birthday" and "deathday" properties

How to avoid coding convention roundtrip issues

Since roundtripping isn't perfect, extra work is required in addition to using the original code in your Web service EAR file.

Just say "no"

The easiest way around these issues is simply to avoid them. Always follow the Java coding conventions.

Write wrappers

Perhaps you cannot change the original code. Another alternative is to write wrappers around the original application. The wrapper code would be the Web service, and it would delegate all invocations to the real implementation. Listing 6 shows a wrapper for this example. The EAR file which is packaged with this tip implements this wrapper. (Note that for this wrapper we generated Life and Population into a different package than the original life and population classes. We developed this example on Windows which isn't particularly friendly to file names that differ only in case.)


Listing 6. Web service wrapper around the original population application
package com.ibm.developerWorks.roundtrip;

import java.rmi.RemoteException;
import java.util.Calendar;
import com.ibm.developerWorks.roundtrip.generated.Life;
import com.ibm.developerWorks.roundtrip.generated.Population;

public class WrapperImpl implements Population {
    private population p = new populationImpl();

    public Life getALife() throws RemoteException {
        life l = p.GetALife();
        Life L = new Life();
        Calendar birthday = Calendar.getInstance();
        birthday.setTime(l.birthday);
        Calendar deathday = Calendar.getInstance();
        deathday.setTime(l.deathday);
        L.setBirthday(birthday);
        L.setDeathday(deathday);
        return L;
    }
}

Modify the mapping metadata file

Web services for J2EE (commonly referred to as JSR-109 -- see Resources) defines a mapping metadata file which lets you bypass some of the JAX-RPC mapping rules. Stay tuned for a future tip which will give some hints about modifying this mapping metadata file to get around roundtripping issues.


Summary

When roundtripping a Web service, it is important to follow Java coding conventions. Failure to do so will compromise roundtripping.

There are a number of ways to work around these roundtrip issues:

  • you could avoid them altogether by simply following the conventions
  • you could write Web services wrappers around the original implementation
  • you could modify the mapping metadata file (this tip does not go into details on the mapping metadata file).

Resources

About the authors

Russell Butek is one of the developers of the IBM® WebSphere® Web services engine. He is also an IBM representative on the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's AXIS SOAP engine, driving AXIS 1.0 to comply with JAX-RPC 1.0. Previously, he was a developer of the IBM CORBA ORB and an IBM representative on a number of OMG task forces: the portable interceptor task force (of which he was chair), the core task force, and the interoperability task force.

Richard Scheuerle is one of the developers of the IBM® WebSphere® Web services engine. He was involved in the implementation of Apache's AXIS SOAP engine. Richard has 10 years of development experience with compiler/language design. Currently he is concentrating on the Web services engine performance and API design. Richard has also worked on the development of CORBA tooling and chip validation software.

Comments



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and Web services
ArticleID=11893
ArticleTitle=Web services programming tips and tricks: Roundtrip issues in Java coding conventions
publish-date=04022004
author1-email=butek@us.ibm.com
author1-email-cc=
author2-email=scheu@us.ibm.com
author2-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers