openwebbeans-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cove...@apache.org
Subject svn commit: r987154 - in /openwebbeans/trunk: webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/util/EjbDefinitionUtility.java webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
Date Thu, 19 Aug 2010 12:50:40 GMT
Author: covener
Date: Thu Aug 19 12:50:40 2010
New Revision: 987154

URL: http://svn.apache.org/viewvc?rev=987154&view=rev
Log:
[OWB-442] since our EJB proxies only implement 1 of n interfaces, we need to create a unique
proxy class
per injected local interface for each EJB Class / Enterprise bean, otherwise a 2nd interface
injection
is incompatible with the proxy.

java.lang.IllegalArgumentException: Can not set org.apache.webbeans.sample.ejb.OtherIface
field org.apache.webbeans.sample.bean.EchoManaged.echo3 to org.apache.webbeans.sample.ejb.Echo_$$_javassist_3



Modified:
    openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/util/EjbDefinitionUtility.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java

Modified: openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/util/EjbDefinitionUtility.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/util/EjbDefinitionUtility.java?rev=987154&r1=987153&r2=987154&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/util/EjbDefinitionUtility.java
(original)
+++ openwebbeans/trunk/webbeans-ejb/src/main/java/org/apache/webbeans/ejb/common/util/EjbDefinitionUtility.java
Thu Aug 19 12:50:40 2010
@@ -53,12 +53,12 @@ public final class EjbDefinitionUtility
         try
         {
             T proxyInstance = null;            
-            Class<?> clazz = JavassistProxyFactory.getInstance().getEjbBeanProxyClass(bean);
+            Class<?> clazz = JavassistProxyFactory.getInstance().getEjbBeanProxyClass(bean,
iface);
             if(clazz == null)
             {
                 ProxyFactory factory = new ProxyFactory();
                 factory.setInterfaces(new Class[]{iface});
-                clazz = JavassistProxyFactory.getInstance().defineEjbBeanProxyClass(bean,
factory);
+                clazz = JavassistProxyFactory.getInstance().defineEjbBeanProxyClass(bean,
iface, factory);
             }
             
             proxyInstance = (T) ClassUtil.newInstance(clazz);

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java?rev=987154&r1=987153&r2=987154&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
(original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/proxy/JavassistProxyFactory.java
Thu Aug 19 12:50:40 2010
@@ -63,7 +63,8 @@ public final class JavassistProxyFactory
     private ConcurrentMap<OwbBean<?>, Class<?>> normalScopedBeanProxyClasses
= new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
     private ConcurrentMap<OwbBean<?>, Class<?>> dependentScopedBeanProxyClasses
= new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
     private ConcurrentMap<OwbBean<?>, Class<?>> interceptorProxyClasses
= new ConcurrentHashMap<OwbBean<?>, Class<?>>();    
-    private ConcurrentMap<OwbBean<?>, Class<?>> ejbProxyClasses = new ConcurrentHashMap<OwbBean<?>,
Class<?>>();    
+    // second level map is indexed on local interface
+    private ConcurrentMap<OwbBean<?>, ConcurrentMap<Class<?>, Class<?>>>
ejbProxyClasses = new ConcurrentHashMap<OwbBean<?>, ConcurrentMap<Class<?>,
Class<?>>>();    
     
     public   Map<OwbBean<?>, Class<?>> getInterceptorProxyClasses()
     {
@@ -76,7 +77,6 @@ public final class JavassistProxyFactory
         return aef;
     }
     
-    
     public void clear()
     {
         normalScopedBeanProxyClasses.clear();
@@ -84,27 +84,60 @@ public final class JavassistProxyFactory
         interceptorProxyClasses.clear();
         ejbProxyClasses.clear();
     }
-    
-    public  Class<?> getEjbBeanProxyClass(OwbBean<?> bean)
+    /**
+     * Provides the proxy for the given bean and interface, if defined
+     * 
+     * @param bean the contextual representing the EJB
+     * @param iface the injected business local interface
+     * @return the proxy Class if one has been defined, else null
+     */
+    public Class<?> getEjbBeanProxyClass(OwbBean<?> bean, Class<?> iface)
     {
-        return ejbProxyClasses.get(bean);
+        Class<?> proxyClass = null;
+        ConcurrentMap<Class<?>, Class<?>> typeToProxyClassMap = ejbProxyClasses.get(bean);
+        if (typeToProxyClassMap != null)
+        {
+            proxyClass = typeToProxyClassMap.get(iface);
+        }
+        return proxyClass;
     }
-    
 
-    public  Class<?> defineEjbBeanProxyClass(OwbBean<?> bean, ProxyFactory factory)
+    /**
+     * Defines the proxy for the given bean and iface using callers factory. Due
+     * to races with the concurrentmap, this might sometimes create additional
+     * javassist-defined classes that are not used by the caller and not stored
+     * in the map. Synchronizing the entire method, and getEjbBeanProxyClass, on
+     * ejbProxyClasses is an alternative.
+     * 
+     * @param bean the contextual representing the EJB
+     * @param iface the injected business local interface
+     * @param factory
+     * @return
+     */
+    public Class<?> defineEjbBeanProxyClass(OwbBean<?> bean, Class<?> iface,
ProxyFactory factory)
     {
-        Class<?> clazz = ejbProxyClasses.get(bean);
-        if(clazz != null)
+        Class<?> proxyClass = null;
+
+        ConcurrentMap<Class<?>, Class<?>> typeToProxyClassMap = ejbProxyClasses.get(bean);
+        if (typeToProxyClassMap == null)
         {
-            return clazz;
+            typeToProxyClassMap = new ConcurrentHashMap<Class<?>, Class<?>>();
+            ConcurrentMap<Class<?>, Class<?>> existingMap = ejbProxyClasses.putIfAbsent(bean,
typeToProxyClassMap);
+            
+            // use the map that beat us, because our new one definitely had no classes in
it.
+            typeToProxyClassMap = (existingMap != null) ? existingMap : typeToProxyClassMap;

         }
-        else
+
+        proxyClass = typeToProxyClassMap.get(iface);
+
+        if (proxyClass == null)
         {
-            clazz = SecurityUtil.doPrivilegedCreateClass(factory);
-            ejbProxyClasses.putIfAbsent(bean, clazz);
+            proxyClass = SecurityUtil.doPrivilegedCreateClass(factory);
+            typeToProxyClassMap.putIfAbsent(iface, proxyClass);
+            // don't care if we were beaten in updating the iface->proxyclass map
         }
-        
-        return clazz;
+
+        return proxyClass;
     }
     
     public  Class<?> createAbstractDecoratorProxyClass(OwbBean<?> bean)



Mime
View raw message