FileDescriptor.sync()

First and foremost – a week ago, I never even knew this method existed in Java. Basically – it let you force the file writing to the disk. Turns out Arjuna (JBoss transactions) is using it in its ShadowStore class, to ensure transaction data is stored to disk. It makes sense – as they want to recover transactions in case of a server crash.
Now, if you read my last post, on the inflation of EJBs, you know that 200 EJBs working together is a mess. And I’ve reached a point where 15% of CPU time of a single transaction is spent on this FileDescriptor.sync() method. Since I couldn’t refactor the whole code – I had to think of another solution. Here goes.

I’ve written a new class, that extends ShadowStore.

public class TonaStore extends ShadowingStore {
    public TonaStore(ObjectStoreEnvironmentBean objectStoreEnvironmentBean) throws ObjectStoreException
    {
        super(objectStoreEnvironmentBean);
    	syncWrites = false;
    }
}

I deployed it to a JAR file, and placed it in the server/all/lib directory.

Now, I opened the /server/all/deploy/transactions-jboss-beans.xml file, and changed ActionStore section to the following:

    <bean name="ActionStoreObjectStoreEnvironmentBean" class="com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean">

        <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.jta:name=ActionStoreObjectStoreEnvironmentBean", exposedInterface=com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBeanMBean.class, registerDirectly=true)</annotation>
        
        <constructor factoryClass="com.arjuna.common.internal.util.propertyservice.BeanPopulator" factoryMethod="getNamedInstance">
            <parameter>com.arjuna.ats.arjuna.common.ObjectStoreEnvironmentBean</parameter>
            <parameter>default</parameter>
        </constructor>
        <property name="objectStoreDir">${jboss.server.data.dir}/tx-object-store</property>
	<property name="objectStoreType">com.tona.ts.common.TonaStore</property>
    </bean>

I got almost a 100% increase in hits/second. Sweet.

EJB inflation

Ever since the JavaEE standard introduced the Local interfaces (and especially in EJB3), I see people abusing EJBs. The logic is simple – if EJB calls are local, let’s use EJBs, and enjoy dependency injection.
Recently I assisted a customer who had over 200 EJBs in a project that had about 500 classes! I call it EJB inflation, and it’s bad. Really bad.
The reason – the EJB container does more than just proxy remote calls. It handles security, transactions, pooling and more. Using those, for every class, is paying a huge price in performance. Let’s just say that when I run a profiler on the customer code I saw that over 20% of the server time is wasted on the application server EJB related code (JTA, specifically).
I will post workarounds for this in future posts, but in the mean time – beware abusing EJBs. Don’t fall to the “if you have a hammer, everything looks like a nail” trap.

WebSphere ESB and EJBs

My next post will probably be a book review – I was asked to review a new book on WAS 7.0 administration. Cool. Hopefully I’ll be able to read it in the next couple of days (did I ever mention I was a quick reader?)

In the meantime, I want to publish my findings on the use of EJBs in WebSphere ESB.
A customer of mine is using WebSphere ESB. For services, it developed EJBs (stateless, of course, but still – version 2.0).
The mediation module has imports for the EJBs.
This turns out to be a very bad architectural decision (I arrived to the project after this decision was taken 🙂 ) , and right now they are rewriting everything, to drop EJBs and use SCA Java components.
Why?
  1. SCA Java components are actual EJBs, so why have an EJB call an EJB? Not a smart move, performance wise.
  2. Mediation Module (6.1) EJB support is lousy. It fails generating good mapping between the Java bean parameters and Data objects. So my customer resorted into sending Strings to the EJBs, and then parsing them, at the EJB level, to POJOs, using XMLBeans. This is insane – and shouldn’t be done.
So what is the current (working!) recommendation?
Use SCA Java components, in the same module, or other modules, depending on your component visibility and deployment needs.
Inside the Java component, use a mapper to map the DataObject object into real Java POJO. and then pass it to your business logic, which is implemented in regular Java Classes.
The mapper is really easy to write:
1. Use JAXB or XMLBeans to generate mapping between the DataObject XSD and a Java class.
2. Write a method that has the following signature:
public static Object mapper(DataObject do, Class clz)
3. Use reflection on the clz – create a new instance of it, and for every field decide:
3.1 If its a primitive – transform it.
3.2 If its a Java Class – call yourself in recurssion
3.3 If its an array – run over all elements
It works fine, great performance, and the development barrier was lowered by more than a few inches.
Hope it serves someone well.