You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2008/03/01 02:16:49 UTC

svn commit: r632525 - in /openejb/trunk/openejb3/container/openejb-core/src: main/java/org/apache/openejb/core/stateful/ main/java/org/apache/openejb/util/ test/java/org/apache/openejb/core/stateful/ test/java/org/apache/openejb/util/

Author: dblevins
Date: Fri Feb 29 17:16:47 2008
New Revision: 632525

URL: http://svn.apache.org/viewvc?rev=632525&view=rev
Log:
OPENEJB-215: Passivation/Activation of non-Serializable Stateful SessionBeans

Added:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoExternalization.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoExternalizationTest.java
Modified:
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java
    openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoSerialization.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java
    openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoSerializationTest.java

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java?rev=632525&r1=632524&r2=632525&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulInstanceManager.java Fri Feb 29 17:16:47 2008
@@ -35,6 +35,7 @@
 import org.apache.openejb.util.Index;
 import org.apache.openejb.util.LogCategory;
 import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.PojoSerialization;
 import org.apache.xbean.recipe.ObjectRecipe;
 import org.apache.xbean.recipe.Option;
 import org.apache.xbean.recipe.StaticRecipe;
@@ -58,6 +59,7 @@
 import java.util.HashMap;
 import java.util.List;
 import java.io.Serializable;
+import java.io.ObjectStreamException;
 
 public class StatefulInstanceManager {
     public static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, "org.apache.openejb.util.resources");
@@ -200,7 +202,7 @@
             List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
             InterceptorStack interceptorStack = new InterceptorStack(bean, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
             interceptorStack.invoke();
-            
+
             bean = newInstance(primaryKey, bean, interceptorInstances);
 
         } catch (Throwable callbackException) {
@@ -231,7 +233,7 @@
     protected BeanEntry newBeanEntry(Object primaryKey, Object bean) {
         return new BeanEntry(bean, primaryKey, timeOut);
     }
-    
+
     private static void fillInjectionProperties(ObjectRecipe objectRecipe, Class clazz, CoreDeploymentInfo deploymentInfo, Context context) {
         for (Injection injection : deploymentInfo.getInjections()) {
             if (!injection.getTarget().isAssignableFrom(clazz)) continue;
@@ -425,7 +427,7 @@
             if (entry.beanTransaction == null) {
                 // add it to end of Queue; the most reciently used bean
                 lruQueue.add(entry);
-                
+
                 onPoolInstanceWithoutTransaction(callContext, entry);
             }
         }
@@ -448,7 +450,7 @@
         }
 
         onFreeBeanEntry(threadContext, entry);
-        
+
         return entry.bean;
     }
 
@@ -672,6 +674,40 @@
         public Instance(Object bean, Map<String, Object> interceptors) {
             this.bean = bean;
             this.interceptors = interceptors;
+        }
+
+        protected Object writeReplace() throws ObjectStreamException {
+            return new Serialization(this);
+        }
+
+        private static class Serialization implements Serializable {
+            public final Object bean;
+            public final Map<String,Object> interceptors;
+
+            public Serialization(Instance i) {
+                if (i.bean instanceof Serializable){
+                    bean = i.bean;
+                } else {
+                    bean = new PojoSerialization(i.bean);
+                }
+
+                interceptors = new HashMap(i.interceptors.size());
+                for (Map.Entry<String, Object> e : i.interceptors.entrySet()) {
+                    if (e.getValue() == i.bean){
+                        // need to use the same wrapped reference or well get two copies.
+                        interceptors.put(e.getKey(), bean);
+                    } else if (!(e.getValue() instanceof Serializable)){
+                        interceptors.put(e.getKey(), new PojoSerialization(e.getValue()));
+                    }
+                }
+            }
+
+            protected Object readResolve() throws ObjectStreamException {
+                // Anything wrapped with PojoSerialization will have been automatically
+                // unwrapped via it's own readResolve so passing in the raw bean
+                // and interceptors variables is totally fine.
+                return new Instance(bean, interceptors);
+            }
         }
     }
 }

Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoExternalization.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoExternalization.java?rev=632525&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoExternalization.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoExternalization.java Fri Feb 29 17:16:47 2008
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import java.io.Externalizable;
+import java.io.ObjectStreamException;
+import java.io.ObjectInput;
+import java.io.IOException;
+import java.io.ObjectOutput;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.lang.reflect.Field;
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Works with objects that have a public no-arg constructor
+ */
+public class PojoExternalization extends PojoSerialization implements Externalizable {
+
+    /** Constructor for externalization */
+    public PojoExternalization() {
+        super();
+    }
+
+    public PojoExternalization(Object object) {
+        super(object);
+    }
+
+    protected Object readResolve() throws ObjectStreamException {
+        return super.readResolve();
+    }
+
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        read(in);
+    }
+
+    public void writeExternal(ObjectOutput out) throws IOException {
+        write(out);
+    }
+}

Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoSerialization.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoSerialization.java?rev=632525&r1=632524&r2=632525&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoSerialization.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/PojoSerialization.java Fri Feb 29 17:16:47 2008
@@ -16,28 +16,19 @@
  */
 package org.apache.openejb.util;
 
-import sun.reflect.ReflectionFactory;
-
-import java.io.Externalizable;
-import java.io.ObjectStreamException;
-import java.io.ObjectInput;
 import java.io.IOException;
+import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-import java.lang.reflect.Field;
-import java.lang.reflect.Constructor;
-import java.lang.ref.WeakReference;
-import java.util.List;
 import java.util.ArrayList;
-import java.util.Map;
-import java.util.Collections;
-import java.util.WeakHashMap;
-
-/**
- * @version $Rev$ $Date$
- */
-public class PojoSerialization implements Externalizable {
+import java.util.List;
+
+public class PojoSerialization implements Serializable {
     private static final byte CLASS = (byte) 50;
     private static final byte FIELD = (byte) 51;
     private static final byte DONE = (byte) 52;
@@ -60,6 +51,9 @@
         });
     }
 
+    /**
+     * Constructor for externalization
+     */
     public PojoSerialization() {
     }
 
@@ -67,17 +61,30 @@
         this.object = object;
     }
 
+    private void writeObject(java.io.ObjectOutputStream out) throws IOException {
+        write(out);
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+        read(in);
+    }
+
     protected Object readResolve() throws ObjectStreamException {
         return object;
     }
 
-    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+    protected void read(ObjectInput in) throws IOException, ClassNotFoundException {
         byte b = in.readByte();
         if (b != CLASS) throw new IOException("Expected 'CLASS' byte " + CLASS + ", got: " + b);
 
         Class clazz = (Class) in.readObject();
 
-        Object object = newInstance(clazz);
+        Object object;
+        try {
+            object = unsafe.allocateInstance(clazz);
+        } catch (Exception e) {
+            throw (IOException) new IOException("Cannot construct " + clazz.getName()).initCause(e);
+        }
 
         while (b != DONE) {
             b = in.readByte();
@@ -104,7 +111,7 @@
         this.object = object;
     }
 
-    public void writeExternal(ObjectOutput out) throws IOException {
+    protected void write(ObjectOutput out) throws IOException {
         List<Class> classes = new ArrayList<Class>();
         Class c = object.getClass();
         while (c != null && !c.equals(Object.class)) {
@@ -118,6 +125,8 @@
 
             Field[] fields = clazz.getDeclaredFields();
             for (Field field : fields) {
+                if (Modifier.isStatic(field.getModifiers())) continue;
+                if (Modifier.isTransient(field.getModifiers())) continue;
                 field.setAccessible(true);
                 out.writeByte(FIELD);
                 out.writeUTF(field.getName());
@@ -131,31 +140,14 @@
         out.writeByte(DONE);
     }
 
-
-    private transient ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
-    private transient Map constructorCache = Collections.synchronizedMap(new WeakHashMap());
-
-    public Object newInstance(Class type) {
+    private void setValue(Field field, Object object, Object value) {
+        long offset;
         try {
-            Constructor customConstructor = getMungedConstructor(type);
-            return customConstructor.newInstance();
+            offset = unsafe.objectFieldOffset(field);
         } catch (Exception e) {
-            throw new IllegalStateException("Cannot construct " + type.getName(), e);
-        }
-    }
-
-    private Constructor getMungedConstructor(Class type) throws NoSuchMethodException {
-        WeakReference ref = (WeakReference) constructorCache.get(type);
-        if (ref == null || ref.get() == null) {
-            Constructor javaLangObjectConstructor = Object.class.getDeclaredConstructor();
-            ref = new WeakReference(reflectionFactory.newConstructorForSerialization(type, javaLangObjectConstructor));
-            constructorCache.put(type, ref);
+            throw new IllegalStateException("Failed getting offset for: field=" + field.getName() + "  class=" + field.getDeclaringClass().getName(), e);
         }
-        return (Constructor) ref.get();
-    }
 
-    private void setValue(Field field, Object object, Object value) {
-        long offset = unsafe.objectFieldOffset(field);
         Class type = field.getType();
         if (type.isPrimitive()) {
             if (type.equals(Integer.TYPE)) {
@@ -175,9 +167,7 @@
             } else if (type.equals(Boolean.TYPE)) {
                 unsafe.putBoolean(object, offset, ((Boolean) value).booleanValue());
             } else {
-                throw new IllegalStateException("Could not set field " +
-                        object.getClass() + "." + field.getName() +
-                        ": Unknown type " + type);
+                throw new IllegalStateException("Unknown primitive type: " + type.getName());
             }
         } else {
             unsafe.putObject(object, offset, value);

Modified: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java?rev=632525&r1=632524&r2=632525&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/core/stateful/StatefulContainerTest.java Fri Feb 29 17:16:47 2008
@@ -42,6 +42,7 @@
 import java.util.Arrays;
 import java.util.List;
 import java.util.Stack;
+import java.util.ArrayList;
 
 /**
  * @version $Revision$ $Date$
@@ -153,10 +154,10 @@
     }
 
     public static enum Lifecycle {
-        CONSTRUCTOR, INJECTION, POST_CONSTRUCT, PRE_PASSIVATE1, POST_ACTIVATE1, BUSINESS_METHOD, PRE_PASSIVATE2, POST_ACTIVATE2,REMOVE, PRE_DESTROY, 
+        CONSTRUCTOR, INJECTION, POST_CONSTRUCT, PRE_PASSIVATE1, POST_ACTIVATE1, BUSINESS_METHOD, PRE_PASSIVATE2, POST_ACTIVATE2,REMOVE, PRE_DESTROY,
     }
 
-    public static class WidgetBean implements Widget, RemoteWidget, Serializable {
+    public static class WidgetBean implements Widget, RemoteWidget {
         private static final long serialVersionUID = -8499745487520955081L;
 
         private int activates = 0;

Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoExternalizationTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoExternalizationTest.java?rev=632525&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoExternalizationTest.java (added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoExternalizationTest.java Fri Feb 29 17:16:47 2008
@@ -0,0 +1,304 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.openejb.util;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ObjectInputStream;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PojoExternalizationTest extends TestCase {
+
+    public void _testSpeed() throws Exception {
+        long start = System.currentTimeMillis();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+
+        Green green = new Green(1);
+        green.init();
+
+        int count = 20000;
+
+        for (int i = count; i > 0; i--) {
+            out.writeObject(new PojoSerialization(green));
+        }
+        out.close();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bais);
+
+        for (int i = count; i > 0; i--) {
+            Green actual = (Green) in.readObject();
+            assertEquals(green, actual);
+        }
+        long finish = System.currentTimeMillis();
+        fail("" + (finish - start));
+    }
+
+    public void test() throws Exception {
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+
+        Green green = new Green(1);
+        green.init();
+
+        out.writeObject(new PojoSerialization(green));
+        out.close();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bais);
+        Green actual = (Green) in.readObject();
+
+        assertEquals(green, actual);
+    }
+
+    public static class Color {
+        private final double mydouble;
+        private final double[] adouble = new double[]{10, 10};
+        private float myfloat = 10;
+        private final float[] afloat = new float[]{10, 10};
+        private long mylong = 10;
+        private final long[] along = new long[]{10, 10};
+        private int myint = 10;
+        private final int[] aint = new int[]{10, 10};
+        private short myshort = 10;
+        private final short[] ashort = new short[]{10, 10};
+        private byte mybyte = 10;
+        private final byte[] abyte = new byte[]{10, 10};
+        private char mychar = 10;
+        private final char[] achar = new char[]{10, 10};
+        private boolean myboolean = false;
+        private final boolean[] aboolean = new boolean[]{false, false};
+        private String myString = "";
+        private final String[] aString = new String[]{"one", "two"};
+        private final List myList = new ArrayList();
+        private final List[] aList = new List[]{new ArrayList(), new ArrayList()};
+
+
+        public Color() {
+            mydouble = 10;
+        }
+
+        public Color(int i) {
+            mydouble = 20;
+        }
+
+        protected void init() {
+            adouble[0] = 20;
+            adouble[1] = 22;
+            myfloat = 20;
+            afloat[0] = 20;
+            afloat[1] = 22;
+            mylong = 20;
+            along[0] = 20;
+            along[1] = 22;
+            myint = 20;
+            aint[0] = 20;
+            aint[1] = 22;
+            myshort = 20;
+            ashort[0] = 20;
+            ashort[1] = 22;
+            mybyte = 20;
+            abyte[0] = 20;
+            abyte[1] = 22;
+            mychar = 20;
+            achar[0] = 20;
+            achar[1] = 22;
+            myboolean = true;
+            aboolean[0] = true;
+            aboolean[1] = false;
+            myString = "hello";
+            aString[0] = "three";
+            aString[1] = "four";
+            aList[0].add("Color.list[0].entryOne");
+            aList[0].add("Color.list[0].entryTwo");
+            aList[1].add("Color.list[1].entryOne");
+            aList[1].add("Color.list[1].entryTwo");
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final PojoExternalizationTest.Color color = (PojoExternalizationTest.Color) o;
+
+            if (myboolean != color.myboolean) return false;
+            if (mybyte != color.mybyte) return false;
+            if (mychar != color.mychar) return false;
+            if (Double.compare(color.mydouble, mydouble) != 0) return false;
+            if (Float.compare(color.myfloat, myfloat) != 0) return false;
+            if (myint != color.myint) return false;
+            if (mylong != color.mylong) return false;
+            if (myshort != color.myshort) return false;
+            if (!Arrays.equals(aList, color.aList)) return false;
+            if (!Arrays.equals(aString, color.aString)) return false;
+            if (!Arrays.equals(aboolean, color.aboolean)) return false;
+            if (!Arrays.equals(abyte, color.abyte)) return false;
+            if (!Arrays.equals(achar, color.achar)) return false;
+            if (!Arrays.equals(adouble, color.adouble)) return false;
+            if (!Arrays.equals(afloat, color.afloat)) return false;
+            if (!Arrays.equals(aint, color.aint)) return false;
+            if (!Arrays.equals(along, color.along)) return false;
+            if (!Arrays.equals(ashort, color.ashort)) return false;
+            if (!myList.equals(color.myList)) return false;
+            if (!myString.equals(color.myString)) return false;
+
+            return true;
+        }
+
+        public int hashCode() {
+            int result;
+            long temp;
+            temp = mydouble != +0.0d ? Double.doubleToLongBits(mydouble) : 0L;
+            result = (int) (temp ^ (temp >>> 32));
+            result = 29 * result + myfloat != +0.0f ? Float.floatToIntBits(myfloat) : 0;
+            result = 29 * result + (int) (mylong ^ (mylong >>> 32));
+            result = 29 * result + myint;
+            result = 29 * result + (int) myshort;
+            result = 29 * result + (int) mybyte;
+            result = 29 * result + (int) mychar;
+            result = 29 * result + (myboolean ? 1 : 0);
+            result = 29 * result + myString.hashCode();
+            result = 29 * result + myList.hashCode();
+            return result;
+        }
+    }
+
+    public static class Green extends PojoExternalizationTest.Color {
+        private double mydouble = 10;
+        private final double[] adouble = new double[]{10, 10};
+        private float myfloat = 10;
+        private final float[] afloat = new float[]{10, 10};
+        private long mylong = 10;
+        private final long[] along = new long[]{10, 10};
+        private int myint = 10;
+        private final int[] aint = new int[]{10, 10};
+        private short myshort = 10;
+        private final short[] ashort = new short[]{10, 10};
+        private byte mybyte = 10;
+        private final byte[] abyte = new byte[]{10, 10};
+        private char mychar = 10;
+        private final char[] achar = new char[]{10, 10};
+        private boolean myboolean = false;
+        private final boolean[] aboolean = new boolean[]{false, false};
+        private String myString = "";
+        private final String[] aString = new String[]{"one", "two"};
+        private final List myList = new ArrayList();
+        private final List[] aList = new List[]{new ArrayList(), new ArrayList()};
+
+        public Green() {
+        }
+
+        public Green(int i) {
+            super(i);
+        }
+
+        protected void init() {
+            super.init();
+            mydouble = 30;
+            adouble[0] = 30;
+            adouble[1] = 33;
+            myfloat = 30;
+            afloat[0] = 30;
+            afloat[1] = 33;
+            mylong = 30;
+            along[0] = 30;
+            along[1] = 33;
+            myint = 30;
+            aint[0] = 30;
+            aint[1] = 33;
+            myshort = 30;
+            ashort[0] = 30;
+            ashort[1] = 33;
+            mybyte = 30;
+            abyte[0] = 30;
+            abyte[1] = 33;
+            mychar = 30;
+            achar[0] = 30;
+            achar[1] = 33;
+            myboolean = true;
+            aboolean[0] = true;
+            aboolean[1] = false;
+            myString = "hello";
+            aString[0] = "three";
+            aString[1] = "four";
+            aList[0].add("Green.list[0].entryOne");
+            aList[0].add("Green.list[0].entryTwo");
+            aList[1].add("Green.list[1].entryOne");
+            aList[1].add("Green.list[1].entryTwo");
+        }
+
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            if (!super.equals(o)) return false;
+
+            final Green green = (Green) o;
+
+            if (myboolean != green.myboolean) return false;
+            if (mybyte != green.mybyte) return false;
+            if (mychar != green.mychar) return false;
+            if (Double.compare(green.mydouble, mydouble) != 0) return false;
+            if (Float.compare(green.myfloat, myfloat) != 0) return false;
+            if (myint != green.myint) return false;
+            if (mylong != green.mylong) return false;
+            if (myshort != green.myshort) return false;
+            if (!Arrays.equals(aList, green.aList)) return false;
+            if (!Arrays.equals(aString, green.aString)) return false;
+            if (!Arrays.equals(aboolean, green.aboolean)) return false;
+            if (!Arrays.equals(abyte, green.abyte)) return false;
+            if (!Arrays.equals(achar, green.achar)) return false;
+            if (!Arrays.equals(adouble, green.adouble)) return false;
+            if (!Arrays.equals(afloat, green.afloat)) return false;
+            if (!Arrays.equals(aint, green.aint)) return false;
+            if (!Arrays.equals(along, green.along)) return false;
+            if (!Arrays.equals(ashort, green.ashort)) return false;
+            if (!myList.equals(green.myList)) return false;
+            if (!myString.equals(green.myString)) return false;
+
+            return true;
+        }
+
+        public int hashCode() {
+            int result = super.hashCode();
+            long temp;
+            temp = mydouble != +0.0d ? Double.doubleToLongBits(mydouble) : 0L;
+            result = 29 * result + (int) (temp ^ (temp >>> 32));
+            result = 29 * result + myfloat != +0.0f ? Float.floatToIntBits(myfloat) : 0;
+            result = 29 * result + (int) (mylong ^ (mylong >>> 32));
+            result = 29 * result + myint;
+            result = 29 * result + (int) myshort;
+            result = 29 * result + (int) mybyte;
+            result = 29 * result + (int) mychar;
+            result = 29 * result + (myboolean ? 1 : 0);
+            result = 29 * result + myString.hashCode();
+            result = 29 * result + myList.hashCode();
+            return result;
+        }
+    }
+
+
+}

Modified: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoSerializationTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoSerializationTest.java?rev=632525&r1=632524&r2=632525&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoSerializationTest.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/PojoSerializationTest.java Fri Feb 29 17:16:47 2008
@@ -31,20 +31,38 @@
  */
 public class PojoSerializationTest extends TestCase {
 
-//    public void testSpeed() throws Exception {
-//        long start = System.currentTimeMillis();
-//        for(int i=10000; i >0; i--){
-//            test();
-//        }
-//        long finish = System.currentTimeMillis();
-//        fail(""+(finish-start));
-//    }
+    public void _testSpeed() throws Exception {
+        long start = System.currentTimeMillis();
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream out = new ObjectOutputStream(baos);
+
+        Green green = new Green(1);
+        green.init();
+
+        int count = 20000;
+
+        for (int i = count; i > 0; i--) {
+            out.writeObject(new PojoSerialization(green));
+        }
+        out.close();
+
+        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+        ObjectInputStream in = new ObjectInputStream(bais);
+
+        for (int i = count; i > 0; i--) {
+            Green actual = (Green) in.readObject();
+            assertEquals(green, actual);
+        }
+        long finish = System.currentTimeMillis();
+        fail("" + (finish - start));
+    }
+
     public void test() throws Exception {
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         ObjectOutputStream out = new ObjectOutputStream(baos);
 
-        Green green = new Green();
+        Green green = new Green(1);
         green.init();
 
         out.writeObject(new PojoSerialization(green));
@@ -58,7 +76,10 @@
     }
 
     public static class Color {
-        private double mydouble = 10;
+        private static final String skipStatic = "Don't serialize this";
+        private transient final String skipTransient = "Don't serialize this";
+
+        private final double mydouble;
         private final double[] adouble = new double[]{10, 10};
         private float myfloat = 10;
         private final float[] afloat = new float[]{10, 10};
@@ -79,8 +100,16 @@
         private final List myList = new ArrayList();
         private final List[] aList = new List[]{new ArrayList(), new ArrayList()};
 
-        protected void init() {
+
+        public Color() {
+            mydouble = 10;
+        }
+
+        public Color(int i) {
             mydouble = 20;
+        }
+
+        protected void init() {
             adouble[0] = 20;
             adouble[1] = 22;
             myfloat = 20;
@@ -182,6 +211,13 @@
         private final String[] aString = new String[]{"one", "two"};
         private final List myList = new ArrayList();
         private final List[] aList = new List[]{new ArrayList(), new ArrayList()};
+
+        public Green() {
+        }
+
+        public Green(int i) {
+            super(i);
+        }
 
         protected void init() {
             super.init();