Beware of Remote Interfaces

In the process of porting a not-yet-open-source EJB3 project to run in Sun’s Glassfish container, a working colleague of mine had to convert all local interfaces to remote ones, since Glassfish does not publish local interfaces via JNDI (unlike JBoss), making them unavailable to our own JNDI-based interface lookups (that were introduced because JBoss’ Tomcat on the other hand did not support injection via @EJB in web applications and we had some trouble with start-up dependencies in MBeans).

Besides making everything slower and exposing some not-so-serializable objects, it was amazing how much serialization was going on in JBoss (latest CVS 4.0.4) even though everything ran in the same VM. Mistakenly we were under the impression that in this case JBoss would automagically detect local calls to remote interfaces and enable call-by-reference (in the EJB sense) if a local interface was available. We were going back to local interfaces anyway – but now it’s a top priority.

On the other hand, two lessons learned:

  1. Automated unit and integration tests are essential, they revealed most problems almost instantly, and
  2. It is a bad idea to use fat static objects as parameters, especially when they are not serializable. It works fine and seems to be elegant and efficient with local interfaces, but totally screws you if remote interfaces are involved. In this case, the problem was a static collection of configuration parameters that contained XStream instances to serialize objects to XML. While this may or may not be a great idea (since XStream objects are pretty big and are thread-safe anyway), it worked in the local case – and failed with remote interfaces, since XStream objects themselves are not serializable. Storing them in an internal static array in the constructor does not work either, since the parameterized constructor is not called on deserialization. Now it’s just a single XStream object, initialized in a static constructor – it’s a bit less elegant since all class aliases have to be defined in a central class, but it’s definitely more resource- (and remoting-) friendly. So instead of
    public ObjectParameter(XStream xStream, ...) {
        this.xStream = xStream;
        ...
    }

    we now use a single static XStream instance, initialized in the class’ static constructor:

    private static XStream xStream;	
    
    static {
        xStream = new XStream();
        xStream.alias("queryOperatorNode", QueryOperatorNode.class);
        ...
    }
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: