users@glassfish.java.net

Re: Script Entity Beans using Groovy

From: <glassfish_at_javadesktop.org>
Date: Wed, 04 Jun 2008 07:53:01 PDT

Hi,

thanks for your replies, and sorry for my late response.

I have managed to create and use Entity beans using groovy.
The initial problem was that the Session EJB did not load up because it could not find the class definitions of the scripted classes. The reason for this was that the scripted entity bean classes was referensed in an orm.xml file in the jar being referensed from the persistence.xml file of the EJB jar file.

What I did instead was to create a separete jar file containing the orm.xml and persistence.xml. This jar file was contained within the Session EJB jar file.

I was then able to load the groovy classes using the groovy API and then to create an EntityManagerFactory and EntityManager using the GroovyClassLoader.

Also, by writing a custom oracle.toplink.essentials.tools.sessionconfiguration.SessionCustomizer I was able to use the database pool from the application server.

This is all working, but I cannot use container managed things like automatic transaction management. As the EntityManager configuration is the same as a java SE one. Also, the scripted entity beans needs a special ObjectInputStream to be serialized back to an object. I wrote a new ObjectInputStream deriving from the java.io.ObjectInputStream providing the GroovyClassLoader.

Are there anything else apart from tranasction management that is lost by this approach?

Also, I did some performance tests. I created some Entity Beans with the same fields and properties as the scripted ones. I expected the "normal" java beans to perform better. But the scripted ones are almost twice as fast.

I wrote a crude test app that loads up a number of threads that will query for 2 types of Entity Beans. Each with a max records of 1000. And each entity bean only loads up 3 fields from the db table.

When the thread count was 10, the scripted beans would be about twice as fast. When the thread count was 100, the "normal" java entity beans would raise an exception:

"IOP00410227: (COMM_FAILURE) Unexpected exception when writing with a temporary selector: bytes written = 0, total bytes requested to write = 4,096, time spent waiting = 4,400 ms, max time to wait = {4}."
org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 227 completed: No
        at com.sun.corba.ee.impl.logging.ORBUtilSystemException.exceptionWhenWritingWithTemporarySelector(ORBUtilSystemException.java:3416)
        at com.sun.corba.ee.impl.logging.ORBUtilSystemException.exceptionWhenWritingWithTemporarySelector(ORBUtilSystemException.java:3442)
        at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.write(SocketOrChannelConnectionImpl.java:741)
        at com.sun.corba.ee.impl.encoding.CDROutputObject.writeTo(CDROutputObject.java:196)
        at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.sendWithoutLock(SocketOrChannelConnectionImpl.java:1126)
        at com.sun.corba.ee.impl.encoding.BufferManagerWriteStream.sendFragment(BufferManagerWriteStream.java:149)
        at com.sun.corba.ee.impl.encoding.BufferManagerWriteStream.overflow(BufferManagerWriteStream.java:92)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_2.grow(CDROutputStream_1_2.java:240)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_2.alignAndReserve(CDROutputStream_1_2.java:211)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.internalWriteOctetArray(CDROutputStream_1_0.java:573)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_octet_array(CDROutputStream_1_0.java:592)
        at com.sun.corba.ee.impl.encoding.CDROutputStream.write_octet_array(CDROutputStream.java:302)
        at com.sun.corba.ee.impl.corba.TypeCodeImpl.write_value(TypeCodeImpl.java:1814)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_TypeCode(CDROutputStream_1_0.java:632)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_any(CDROutputStream_1_0.java:612)
        at com.sun.corba.ee.impl.encoding.CDROutputStream.write_any(CDROutputStream.java:390)
        at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.writeAny(Util.java:418)
        at com.sun.corba.ee.impl.io.ValueHandlerImpl.write_Array(ValueHandlerImpl.java:556)
        at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValueInternal(ValueHandlerImpl.java:257)
        at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValueWithVersion(ValueHandlerImpl.java:241)
        at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValue(ValueHandlerImpl.java:179)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.writeArray(CDROutputStream_1_0.java:745)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:923)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:949)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:690)
        at com.sun.corba.ee.impl.encoding.CDROutputStream.write_value(CDROutputStream.java:451)
        at com.sun.corba.ee.impl.io.IIOPOutputStream.writeObjectField(IIOPOutputStream.java:756)
        at com.sun.corba.ee.impl.io.IIOPOutputStream.outputClassFields(IIOPOutputStream.java:818)
        at com.sun.corba.ee.impl.io.IIOPOutputStream.defaultWriteObjectDelegate(IIOPOutputStream.java:232)
        at com.sun.corba.ee.impl.io.OutputStreamHook.defaultWriteObject(OutputStreamHook.java:164)
        at java.util.Vector.writeObject(Vector.java:1012)
        at sun.reflect.GeneratedMethodAccessor33.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at com.sun.corba.ee.impl.io.IIOPOutputStream.invokeObjectWriter(IIOPOutputStream.java:633)
        at com.sun.corba.ee.impl.io.IIOPOutputStream.outputObject(IIOPOutputStream.java:599)
        at com.sun.corba.ee.impl.io.IIOPOutputStream.simpleWriteObject(IIOPOutputStream.java:187)
        at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValueInternal(ValueHandlerImpl.java:259)
        at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValueWithVersion(ValueHandlerImpl.java:241)
        at com.sun.corba.ee.impl.io.ValueHandlerImpl.writeValue(ValueHandlerImpl.java:179)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.writeRMIIIOPValueType(CDROutputStream_1_0.java:839)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:935)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:949)
        at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_value(CDROutputStream_1_0.java:690)
        at com.sun.corba.ee.impl.encoding.CDROutputStream.write_value(CDROutputStream.java:451)
        at com.sun.corba.ee.impl.presentation.rmi.DynamicMethodMarshallerImpl$14.write(DynamicMethodMarshallerImpl.java:376)
        at com.sun.corba.ee.impl.presentation.rmi.DynamicMethodMarshallerImpl.writeResult(DynamicMethodMarshallerImpl.java:472)
        at com.sun.corba.ee.impl.presentation.rmi.ReflectiveTie._invoke(ReflectiveTie.java:158)
        at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:687)
        at com.sun.corba.ee.impl.protocol.CorbaServerRequestDispatcherImpl.dispatch(CorbaServerRequestDispatcherImpl.java:227)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequestRequest(CorbaMessageMediatorImpl.java:1846)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:1706)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1088)
        at com.sun.corba.ee.impl.protocol.giopmsgheaders.RequestMessage_1_2.callback(RequestMessage_1_2.java:223)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:806)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:563)
        at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2567)
        at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:555)


This is the simple Application Client I wrote:

package applicationclientscripttest;

import com.retaininternational.entity.mng.RtnClientEntityManager;
import com.retaininternational.entity.RtnNamedEntity;
import java.util.Calendar;
import java.util.List;

/**
 *
 * @author Hans Fladsrud
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    private static java.util.Date start;
    private static int maxIndex = 100;

    public static void main(String[] args) {
        // TODO code application logic here
        try {
            new Main();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    public Main() {
        start = Calendar.getInstance().getTime();
        run();
    }

    public void run() {
        Printer p = new Printer();
        for (int i = 0; i < maxIndex; i++) {
            RunTest test = new RunTest();
            test.main = p;
            test.index = i;
            test.start();
        }
        java.util.Date end = Calendar.getInstance().getTime();
        System.out.println("Time diff: " + (end.getTime() - start.getTime()));
        System.out.println("Started All Threads");
    }

    class Printer {

        public synchronized void threadDone(int index) {

            if (index == (maxIndex - 1)) {
                java.util.Date end = Calendar.getInstance().getTime();
                System.out.println("Time diff: " + (end.getTime() - start.getTime()));
            }
        }
    }

    class RunTest extends Thread {

        private Printer main;
        private int index;

        @Override
        public void run() {
            RtnClientEntityManager entManager = RtnClientEntityManager.getInstance();
            List<RtnNamedEntity> jobs = entManager.getNamedEntities("JOB", "", false);
            List<RtnNamedEntity> ress = entManager.getNamedEntities("RES", "", false);
            main.threadDone(index);
        }
    }
}

The RtnClientEntityManager instance will lookup a session bean using an InitialContext object, the same session bean is used when using the scripted bean or the "normal" java bean. Only the method called is different.

I am very surprised of the outcome of this test.
Do you think this is a valid test at all?
And when using an EntityManager like this is it bypassing alot of the container managed stuff? Apart from the transactions?

Also surprised that when using 100 threads, the app server would not be able to handle it.
[Message sent by forum member 'hansflhotmailcom' (hansflhotmailcom)]

http://forums.java.net/jive/thread.jspa?messageID=278254