[weld-commits] Weld SVN: r6211 - in core/trunk: impl/src/main/java/org/jboss/weld/bean/proxy/util and 3 other directories.

weld-commits at lists.jboss.org weld-commits at lists.jboss.org
Mon May 3 09:40:20 EDT 2010


Author: dallen6
Date: 2010-05-03 09:40:20 -0400 (Mon, 03 May 2010)
New Revision: 6211

Added:
   core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/SwitchableCLProxyServices.java
Modified:
   core/trunk/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java
   core/trunk/impl/src/main/java/org/jboss/weld/bean/proxy/util/SerializableProxy.java
   core/trunk/impl/src/main/java/org/jboss/weld/logging/messages/BeanMessage.java
   core/trunk/impl/src/main/resources/org/jboss/weld/messages/bean_en.properties
   core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/AbstractClusterTest.java
   core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/SwitchableMockEELifecycle.java
Log:
Added separate class loaders for cluster test to use with proxies and fixed discovered problems with proxy deserialization

Modified: core/trunk/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java	2010-05-03 08:22:14 UTC (rev 6210)
+++ core/trunk/impl/src/main/java/org/jboss/weld/bean/proxy/ProxyFactory.java	2010-05-03 13:40:20 UTC (rev 6211)
@@ -22,6 +22,8 @@
 import static org.jboss.weld.logging.messages.BeanMessage.PROXY_INSTANTIATION_BEAN_ACCESS_FAILED;
 import static org.jboss.weld.logging.messages.BeanMessage.PROXY_INSTANTIATION_FAILED;
 
+import java.io.IOException;
+import java.io.ObjectInputStream;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
 import java.lang.reflect.Modifier;
@@ -324,13 +326,21 @@
          CtClass objectClass = classPool.get(Object.class.getName());
          String writeReplaceBody = "{ " + 
          " if (firstSerializationPhaseComplete) {" +
-         "    firstSerializationPhaseComplete = true; " +
+         "    firstSerializationPhaseComplete = false; " +
          "    return $0; " +
          " } else {" +
          " firstSerializationPhaseComplete = true; " +
          " return ((org.jboss.weld.serialization.spi.ProxyServices)org.jboss.weld.Container.instance().services().get(org.jboss.weld.serialization.spi.ProxyServices.class)).wrapForSerialization($0);" +
          " } }";
          proxyClassType.addMethod(CtNewMethod.make(objectClass, "writeReplace", null, new CtClass[] { exception }, writeReplaceBody, proxyClassType));
+         
+         // Also add a static method that can be used to deserialize a proxy object.
+         // This causes the OO input stream to use the class loader from this class.
+         CtClass objectInputStreamClass = classPool.get(ObjectInputStream.class.getName());
+         CtClass cnfe = classPool.get(ClassNotFoundException.class.getName());
+         CtClass ioe = classPool.get(IOException.class.getName());
+         String deserializeProxyBody = "{ return $1.readObject(); }";
+         proxyClassType.addMethod(CtNewMethod.make(Modifier.STATIC | Modifier.PUBLIC, objectClass, "deserializeProxy", new CtClass[]{objectInputStreamClass}, new CtClass[]{cnfe, ioe}, deserializeProxyBody, proxyClassType));
       }
       catch (Exception e)
       {

Modified: core/trunk/impl/src/main/java/org/jboss/weld/bean/proxy/util/SerializableProxy.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/bean/proxy/util/SerializableProxy.java	2010-05-03 08:22:14 UTC (rev 6210)
+++ core/trunk/impl/src/main/java/org/jboss/weld/bean/proxy/util/SerializableProxy.java	2010-05-03 13:40:20 UTC (rev 6211)
@@ -17,6 +17,9 @@
 
 package org.jboss.weld.bean.proxy.util;
 
+import static org.jboss.weld.logging.messages.BeanMessage.PROXY_DESERIALIZATION_FAILURE;
+import static org.jboss.weld.logging.messages.BeanMessage.PROXY_REQUIRED;
+
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -26,15 +29,15 @@
 import org.jboss.weld.Container;
 import org.jboss.weld.bean.proxy.ProxyFactory;
 import org.jboss.weld.exceptions.ForbiddenStateException;
-import org.jboss.weld.logging.messages.BeanMessage;
+import org.jboss.weld.exceptions.WeldException;
 import org.jboss.weld.serialization.spi.ProxyServices;
 
 /**
- * A wrapper mostly for client proxies which provides header information
- * useful to generate the client proxy class in a VM before the proxy
- * object is deserialized.  Only client proxies really need this
- * extra step for serialization and deserialization since the other
- * proxy classes are generated during bean archive deployment.
+ * A wrapper mostly for client proxies which provides header information useful
+ * to generate the client proxy class in a VM before the proxy object is
+ * deserialized. Only client proxies really need this extra step for
+ * serialization and deserialization since the other proxy classes are generated
+ * during bean archive deployment.
  * 
  * @author David Allen
  */
@@ -44,17 +47,17 @@
    private static final long serialVersionUID = -7682006876407447753L;
 
    // Information required to generate client proxy classes
-   private final String proxyClassName;
-   private final String proxySuperClassName;
+   private final String      proxyClassName;
+   private final String      proxySuperClassName;
 
    // The wrapped proxy object not serialized by default actions
-   private transient Object proxyObject;
+   private transient Object  proxyObject;
 
    public SerializableProxy(Object proxyObject)
    {
       if (!ProxyFactory.isProxy(proxyObject))
       {
-         throw new ForbiddenStateException(BeanMessage.PROXY_REQUIRED);
+         throw new ForbiddenStateException(PROXY_REQUIRED);
       }
       this.proxyClassName = proxyObject.getClass().getName();
       this.proxySuperClassName = proxyObject.getClass().getSuperclass().getName();
@@ -62,9 +65,9 @@
    }
 
    /**
-    * Writes this object to the stream and also appends the serialization of
-    * the proxy object afterwards.  This allows this wrapper to later recover
-    * the proxy class before trying to deserialize the proxy object.
+    * Writes this object to the stream and also appends the serialization of the
+    * proxy object afterwards. This allows this wrapper to later recover the
+    * proxy class before trying to deserialize the proxy object.
     * 
     * @param out the output stream of objects
     * @throws IOException
@@ -91,11 +94,24 @@
       // Must use another OO stream per writeObject() above
       ObjectInputStream in2 = new ObjectInputStream(in);
       Class<?> proxyBeanType = Container.instance().services().get(ProxyServices.class).loadProxySuperClass(proxySuperClassName);
+      Class<?> proxyClass = null;
       if (proxyClassName.endsWith(ProxyFactory.PROXY_SUFFIX))
       {
-         generateClientProxyClass(proxyBeanType);
+         proxyClass = generateClientProxyClass(proxyBeanType);
       }
-      proxyObject = in2.readObject();
+      else
+      {
+         // All other proxy classes always exist where a Weld container was deployed
+         proxyClass = Container.instance().services().get(ProxyServices.class).getClassLoader(proxyBeanType).loadClass(proxyClassName);
+      }
+      try
+      {
+         proxyObject = proxyClass.getDeclaredMethod("deserializeProxy", ObjectInputStream.class).invoke(null, in2);
+      }
+      catch (Exception e)
+      {
+         throw new WeldException(PROXY_DESERIALIZATION_FAILURE, e);
+      }
    }
 
    /**
@@ -108,9 +124,9 @@
    {
       return proxyObject;
    }
-   
-   private <T> void generateClientProxyClass(Class<T> beanType)
+
+   private <T> Class<?> generateClientProxyClass(Class<T> beanType)
    {
-      new ProxyFactory<T>(beanType).getProxyClass();
+      return new ProxyFactory<T>(beanType).getProxyClass();
    }
 }

Modified: core/trunk/impl/src/main/java/org/jboss/weld/logging/messages/BeanMessage.java
===================================================================
--- core/trunk/impl/src/main/java/org/jboss/weld/logging/messages/BeanMessage.java	2010-05-03 08:22:14 UTC (rev 6210)
+++ core/trunk/impl/src/main/java/org/jboss/weld/logging/messages/BeanMessage.java	2010-05-03 13:40:20 UTC (rev 6211)
@@ -30,6 +30,7 @@
  * Log messages for Beans.
  * 
  * Message IDs: 000000 - 000099
+ *              001500 - 001599
  * 
  */
 public enum BeanMessage
@@ -133,6 +134,7 @@
    @MessageId("000096") PRODUCER_FIELD_ON_SESSION_BEAN_MUST_BE_STATIC,
    @MessageId("000097") PRODUCER_METHOD_WITH_TYPE_VARIABLE_RETURN_TYPE_MUST_BE_DEPENDENT,
    @MessageId("000098") PRODUCER_METHOD_WITH_WILDCARD_RETURN_TYPE_MUST_BE_DEPENDENT,
-   @MessageId("000099") CANNOT_LOAD_CLASS;
+   @MessageId("000099") CANNOT_LOAD_CLASS,
+   @MessageId("001500") PROXY_DESERIALIZATION_FAILURE;
    
 }

Modified: core/trunk/impl/src/main/resources/org/jboss/weld/messages/bean_en.properties
===================================================================
--- core/trunk/impl/src/main/resources/org/jboss/weld/messages/bean_en.properties	2010-05-03 08:22:14 UTC (rev 6210)
+++ core/trunk/impl/src/main/resources/org/jboss/weld/messages/bean_en.properties	2010-05-03 13:40:20 UTC (rev 6211)
@@ -98,3 +98,4 @@
 PRODUCER_METHOD_WITH_TYPE_VARIABLE_RETURN_TYPE_MUST_BE_DEPENDENT=A producer method with a parameterized return type with a type variable must be declared @Dependent scoped. Method {0}
 PRODUCER_METHOD_WITH_WILDCARD_RETURN_TYPE_MUST_BE_DEPENDENT=A producer method with a parameterized return type with a wildcard must be declared @Dependent scoped. Method {0}  
 CANNOT_LOAD_CLASS=Cannot load class {0} during deserialization of proxy
+PROXY_DESERIALIZATION_FAILURE=Failed to deserialize proxy object

Modified: core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/AbstractClusterTest.java
===================================================================
--- core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/AbstractClusterTest.java	2010-05-03 08:22:14 UTC (rev 6210)
+++ core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/AbstractClusterTest.java	2010-05-03 13:40:20 UTC (rev 6211)
@@ -24,11 +24,8 @@
 import java.lang.reflect.Field;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
-import javax.enterprise.inject.spi.PassivationCapable;
-
 import org.jboss.weld.Container;
 import org.jboss.weld.bootstrap.api.Singleton;
 import org.jboss.weld.context.ContextLifecycle;
@@ -36,9 +33,8 @@
 import org.jboss.weld.context.api.ContextualInstance;
 import org.jboss.weld.context.beanstore.HashMapBeanStore;
 import org.jboss.weld.manager.BeanManagerImpl;
-import org.jboss.weld.mock.MockEELifecycle;
 import org.jboss.weld.mock.TestContainer;
-import org.jboss.weld.serialization.spi.helpers.SerializableContextual;
+import org.jboss.weld.serialization.spi.ProxyServices;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 
@@ -47,6 +43,7 @@
 
    private Singleton<Container> singleton;
 
+   @SuppressWarnings("unchecked")
    @BeforeClass
    public void beforeClass() throws Exception
    {
@@ -72,7 +69,7 @@
       // Bootstrap container
       SwitchableSingletonProvider.use(id);
 
-      TestContainer container = new TestContainer(new MockEELifecycle(), classes, null);
+      TestContainer container = new TestContainer(new SwitchableMockEELifecycle(), classes, null);
       container.startContainer();
       container.ensureRequestActive();
 
@@ -131,4 +128,8 @@
       return in.readObject();
    }
 
+   protected void useNewClassLoader(ClassLoader parentClassLoader)
+   {
+      ((SwitchableCLProxyServices)Container.instance().services().get(ProxyServices.class)).useNewClassLoader(parentClassLoader);
+   }
 }
\ No newline at end of file

Added: core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/SwitchableCLProxyServices.java
===================================================================
--- core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/SwitchableCLProxyServices.java	                        (rev 0)
+++ core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/SwitchableCLProxyServices.java	2010-05-03 13:40:20 UTC (rev 6211)
@@ -0,0 +1,63 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat, Inc. and/or its affiliates, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * Licensed 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.jboss.weld.mock.cluster;
+
+import org.jboss.weld.bean.proxy.util.SimpleProxyServices;
+import org.jboss.weld.exceptions.WeldException;
+
+/**
+ * Uses a special CL to hold the proxies and allows a test to switch to a new
+ * CL. This is useful for testing cluster environments where the VMs are
+ * different and thus the CL would also be different between serialization and
+ * deserialization.
+ * 
+ * @author David Allen
+ */
+public class SwitchableCLProxyServices extends SimpleProxyServices
+{
+   private ClassLoader currentClassLoader;
+
+   @Override
+   public ClassLoader getClassLoader(Class<?> type)
+   {
+      if (currentClassLoader == null)
+      {
+         ClassLoader baseClassLoader = super.getClassLoader(type);
+         useNewClassLoader(baseClassLoader);
+      }
+      return currentClassLoader;
+   }
+
+   @Override
+   public Class<?> loadProxySuperClass(String className)
+   {
+      try
+      {
+         return currentClassLoader.loadClass(className);
+      }
+      catch (ClassNotFoundException e)
+      {
+         throw new WeldException(e);
+      }
+   }
+
+   public void useNewClassLoader(ClassLoader parentClassLoader)
+   {
+      currentClassLoader = new ClusterClassLoader(parentClassLoader);
+   }
+}

Modified: core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/SwitchableMockEELifecycle.java
===================================================================
--- core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/SwitchableMockEELifecycle.java	2010-05-03 08:22:14 UTC (rev 6210)
+++ core/trunk/tests/src/main/java/org/jboss/weld/mock/cluster/SwitchableMockEELifecycle.java	2010-05-03 13:40:20 UTC (rev 6211)
@@ -16,49 +16,17 @@
  */
 package org.jboss.weld.mock.cluster;
 
-import java.util.HashMap;
-import java.util.Map;
-
-import org.jboss.weld.context.api.BeanStore;
 import org.jboss.weld.mock.MockEELifecycle;
+import org.jboss.weld.serialization.spi.ProxyServices;
 
 public class SwitchableMockEELifecycle extends MockEELifecycle
 {
+   private SwitchableCLProxyServices proxyServices;
    
-   private final Map<Integer, BeanStore> requestBeanStores;
-   private final Map<Integer, BeanStore> sessionBeanStores;
-   private final Map<Integer, BeanStore> applicationBeanStores;
-   
-   private int id = 1;
-   
    public SwitchableMockEELifecycle()
    {
-      this.requestBeanStores = new HashMap<Integer, BeanStore>();
-      this.sessionBeanStores = new HashMap<Integer, BeanStore>();
-      this.applicationBeanStores = new HashMap<Integer, BeanStore>();
+      proxyServices = new SwitchableCLProxyServices();
+      getDeployment().getServices().add(ProxyServices.class, proxyServices);
    }
    
-   @Override
-   protected BeanStore getRequestBeanStore()
-   {
-      return requestBeanStores.get(id);
-   }
-   
-   @Override
-   protected BeanStore getSessionBeanStore()
-   {
-      return sessionBeanStores.get(id);
-   }
-   
-   @Override
-   protected BeanStore getApplicationBeanStore()
-   {
-      return applicationBeanStores.get(id);
-   }
-   
-   public void use(int id)
-   {
-      this.id = id;
-   }
-
 }



More information about the weld-commits mailing list