Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Direct network traffic of EJBs

Avoid bottlenecking by encapsulating bean properties into a single object

Before we get into the heart of this article, there are some things to keep in mind. You're going to need a firm understanding of Enterprise JavaBeans or remote objects in general to follow the discussion here. In order to avoid confusion, the source-code snippets are color-coded : green for the bean, red for the client, and blue for objects that are shared by both.

Network traffic

When dealing with remote objects, such as Enterprise JavaBeans (EJB), some of the biggest performance problems can be traced to network traffic. A method call that has to be marshaled over a socket connection is going to be much slower than a method call issued in local memory. The following piece of client code, which assumes that bean is a handle to an EJB, makes six remote calls (remember, red here stands for client code):

   bean.setFirstName( "Thomas" );
    bean.setLastName( "Davis" );
    bean.setCity( "Boca Raton" );
    bean.setState( "Florida" );
    bean.setZipCode( "33487" );
    bean.setCountry( "United States" );



This code has the potential to be a performance nightmare. Six calls to bean methods means six requests over the network. In the EJB implementations with which I have worked, all of the client-to-EJB communication within a single virtual machine instance takes place through a single socket connection. This is a bottleneck. When one client is talking to a bean, other clients (within the same virtual machine, sharing the single socket) are waiting for their turn. Waiting is bad. You want to avoid remote calls whenever possible.

Property encapsulation

One solution to this problem, the solution I am going to promote in this article, is to encapsulate the bean properties into a single object, and then send that entire object back and forth between client and server (over the network). This lets you put all of the get/set methods into the transported object and have them executed within the client's virtual machine -- in local memory rather than over the network. The properties object must be serializable in order to be transported over the network, and it should be as compact as possible to ensure the fastest possible transfer rate. Here is an example that encapsulates the properties that the above code modified (note that it's blue because it is shared between the client and the bean):

public class BeanProperties implements java.io.Serializable {
    private String firstName, lastName, city, state, zipCode;

public void setFirstName( String firstName ){ this.firstName = firstName; }

// more 'set' methods for the other string values... }


Using this technique, you can reduce the previous client example to only two remote calls. The first call retrieves the properties object from the bean, while the second sends the properties object back to the bean:

BeanProperties props = bean.getProperties(); // remote call #1

props.setFirstName( "Thomas" ); props.setLastName( "Davis" ); props.setCity( "Boca Raton" ); props.setState( "Florida" ); props.setZipCode( "33487" ); props.setCountry( "United States" );

bean.setProperties( props ); // remote call #2


This code is going to run more quickly due to the reduced amount of network calls. And any other processes that are sharing the same network connection will also run more quickly because they won't be waiting as often for this client to relinquish the socket.

Synchronization issues

The properties encapsulation is a major improvement in performance, but it comes at a price -- we now have a synchronization issue. If two clients are working with the same bean, it is possible for the properties to get out of sync. I'll demonstrate this momentarily.

When a client requests the properties from the bean, the client actually receives a copy of the properties object. If a single client requests the properties object twice, it will receive two different instances of that object.

Observe the following code, explained below:

   BeanProperties propsA = bean.getProperties();
    BeanProperties propsB = bean.getProperties();
    propsA.setFirstName( "Edward" );
    propsB.setState( "Ohio" );
    bean.setProperties( propsA );
    bean.setProperties( propsB );
    BeanProperties propsC = bean.getProperties();
    System.out.println( propsC.getFirstName() ); // "Thomas" !!!



The client retrieves a copy of the bean's properties and assigns them to propsA, then immediately requests the properties again and assigns them to propsB. The client now has two copies of the bean's properties.

The client modifies the first name value in propsA, then changes the state value of propsB. Now each copy of the properties is unique -- one has a different first name and the other contains a different value for the state.

Next, the client sends the propsA copy back to the bean. This means that the remote bean now has a first name value of "Edward". But then the client sends up the propsB copy. Now the bean has the state set to "Ohio" ... but the value for the first name has been reset to its original value! Why? Because propsB was a copy of the properties, and the first name was never changed for it. When we sent the propsB version back to the bean, the propsA version was overwritten; thus, the change to the first name was lost.

This is exactly what can happen when two different clients start modifying the properties of the same bean. This is called a race condition. Each client is essentially racing the other to update the bean's properties.

SUBHEAD_BREAK: Synchronization solutions

If all of the clients were running in a single virtual machine, we could use the synchronization keyword in a strategic manner to ensure that only one client accessed the remote bean's properties at a time. However, the clients will most likely be running on completely different machines, and thus not within the same virtual machine.

One way to tackle this is to have the bean timestamp the properties object and check that timestamp each time the properties get passed back from the client. If the timestamps don't match up, in the case of the client passing back an old copy of the properties, then a race condition has occurred. Let's add some more logic to the BeanProperties class to facilitate a timestamp:

1 | 2 | 3 |  Next >
Resources