You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by co...@apache.org on 2010/08/19 14:50:40 UTC
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
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)