You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2014/06/13 10:26:33 UTC

svn commit: r1602336 - in /tomee/tomee/trunk/container/openejb-core/src: main/java/org/apache/openejb/core/stateful/ test/java/org/apache/openejb/cdi/

Author: rmannibucau
Date: Fri Jun 13 08:26:33 2014
New Revision: 1602336

URL: http://svn.apache.org/r1602336
Log:
TOMEE-1249 allow to change lock for stateful beans

Added:
    tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/DefaultLockFactory.java
    tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/LockFactory.java
Modified:
    tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java
    tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
    tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java
    tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StatefulDecoratorInjectionTest.java

Added: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/DefaultLockFactory.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/DefaultLockFactory.java?rev=1602336&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/DefaultLockFactory.java (added)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/DefaultLockFactory.java Fri Jun 13 08:26:33 2014
@@ -0,0 +1,61 @@
+/*
+ * 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.core.stateful;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class DefaultLockFactory implements LockFactory {
+    public static class DefaultLock implements StatefulLock {
+        private final ReentrantLock lock = new ReentrantLock();
+
+        @Override
+        public void lock() {
+            lock.lock();
+        }
+
+        @Override
+        public void unlock() {
+            lock.unlock();
+        }
+
+        @Override
+        public boolean isHeldByCurrentThread() {
+            return lock.isHeldByCurrentThread();
+        }
+
+        @Override
+        public boolean tryLock() {
+            return lock.tryLock();
+        }
+
+        @Override
+        public boolean tryLock(final long time, final TimeUnit unit) throws InterruptedException {
+            return lock.tryLock(time, unit);
+        }
+    }
+
+    @Override
+    public StatefulLock newLock(final String beanId) {
+        return new DefaultLock();
+    }
+
+    @Override
+    public void setContainer(final StatefulContainer statefulContainer) {
+        // no-op
+    }
+}

Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java?rev=1602336&r1=1602335&r2=1602336&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/Instance.java Fri Jun 13 08:26:33 2014
@@ -42,13 +42,14 @@ public class Instance implements Seriali
     public final BeanContext beanContext;
     public final Object primaryKey;
     public final Object bean;
+    public final Object containerId;
     public CreationalContext creationalContext;
     public final Map<String, Object> interceptors;
 
     private boolean inUse;
     private SuspendedTransaction beanTransaction;
     private final Stack<Transaction> transaction = new Stack<Transaction>();
-    private final ReentrantLock lock = new ReentrantLock();
+    private final LockFactory.StatefulLock lock;
 
     // todo if we keyed by an entity manager factory id we would not have to make this transient and rebuild the index below
     // This would require that we crete an id and that we track it
@@ -56,17 +57,24 @@ public class Instance implements Seriali
     private Map<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> entityManagers;
     private final JtaEntityManagerRegistry.EntityManagerTracker[] entityManagerArray;
 
-    public Instance(final BeanContext beanContext, final Object primaryKey, final Object bean, final CreationalContext creationalContext, final Map<String, Object> interceptors, final Map<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> entityManagers) {
+    public Instance(final BeanContext beanContext, final Object primaryKey, final Object containerId,
+                    final Object bean, final CreationalContext creationalContext,
+                    final Map<String, Object> interceptors,
+                    final Map<EntityManagerFactory, JtaEntityManagerRegistry.EntityManagerTracker> entityManagers,
+                    final LockFactory.StatefulLock lock) {
         this.beanContext = beanContext;
         this.primaryKey = primaryKey;
+        this.containerId = containerId;
         this.bean = bean;
         this.interceptors = interceptors;
         this.creationalContext = creationalContext;
         this.entityManagers = entityManagers;
         this.entityManagerArray = null;
+        this.lock = lock;
     }
 
-    public Instance(final Object deploymentId, final Object primaryKey, final Object bean, final CreationalContext creationalContext, final Map<String, Object> interceptors, final JtaEntityManagerRegistry.EntityManagerTracker[] entityManagerArray) {
+    public Instance(final Object deploymentId, final Object primaryKey, final Object containerId, final Object bean, final CreationalContext creationalContext, final Map<String, Object> interceptors, final JtaEntityManagerRegistry.EntityManagerTracker[] entityManagerArray,
+                    final LockFactory.StatefulLock lock) {
         this.beanContext = SystemInstance.get().getComponent(ContainerSystem.class).getBeanContext(deploymentId);
         if (beanContext == null) {
             throw new IllegalArgumentException("Unknown deployment " + deploymentId);
@@ -76,6 +84,8 @@ public class Instance implements Seriali
         this.creationalContext = creationalContext;
         this.interceptors = interceptors;
         this.entityManagerArray = entityManagerArray;
+        this.lock = lock;
+        this.containerId = containerId;
     }
 
     @Override
@@ -103,7 +113,7 @@ public class Instance implements Seriali
         return transaction.size() > 0 ? transaction.peek(): null;
     }
 
-    public Lock getLock() {
+    public LockFactory.StatefulLock getLock() {
         return lock;
     }
 
@@ -151,6 +161,7 @@ public class Instance implements Seriali
         private static final long serialVersionUID = 6002078080752564395L;
         public final Object deploymentId;
         public final Object primaryKey;
+        public final Object containerId;
         public final Object bean;
         public final CreationalContext creationalContext;
         public final Map<String, Object> interceptors;
@@ -179,6 +190,8 @@ public class Instance implements Seriali
             } else {
                 entityManagerArray = null;
             }
+
+            this.containerId = toSerializable(i.containerId);
         }
 
         private static Object toSerializable(final Object obj) {
@@ -193,7 +206,12 @@ public class Instance implements Seriali
             // 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(deploymentId, primaryKey, bean, creationalContext, interceptors, entityManagerArray);
+            final StatefulContainer statefulContainer = StatefulContainer.class.cast(SystemInstance.get().getComponent(ContainerSystem.class).getContainer(containerId));
+            return new Instance(
+                    deploymentId, primaryKey, containerId,
+                    bean, creationalContext,
+                    interceptors, entityManagerArray,
+                    statefulContainer.getLockFactory().newLock(deploymentId.toString()));
         }
     }
 }

Added: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/LockFactory.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/LockFactory.java?rev=1602336&view=auto
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/LockFactory.java (added)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/LockFactory.java Fri Jun 13 08:26:33 2014
@@ -0,0 +1,33 @@
+/*
+ * 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.core.stateful;
+
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+public interface LockFactory {
+    StatefulLock newLock(String beanId);
+    void setContainer(StatefulContainer statefulContainer);
+
+    public static interface StatefulLock {
+        void lock();
+        void unlock();
+        boolean isHeldByCurrentThread();
+        boolean tryLock();
+        boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
+    }
+}

Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java?rev=1602336&r1=1602335&r2=1602336&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainer.java Fri Jun 13 08:26:33 2014
@@ -106,16 +106,18 @@ public class StatefulContainer implement
     protected final Map<Object, BeanContext> deploymentsById = new HashMap<Object, BeanContext>();
 
     protected final Cache<Object, Instance> cache;
+    protected final LockFactory lockFactory;
     private final ConcurrentMap<Object, Instance> checkedOutInstances = new ConcurrentHashMap<Object, Instance>();
     private final SessionContext sessionContext;
     private final boolean preventExtendedEntityManagerSerialization;
 
     public StatefulContainer(final Object id, final SecurityService securityService, final Cache<Object, Instance> cache) {
-        this(id, securityService, cache, new Duration(-1, TimeUnit.MILLISECONDS), true);
+        this(id, securityService, cache, new Duration(-1, TimeUnit.MILLISECONDS), true, new DefaultLockFactory());
     }
 
     public StatefulContainer(final Object id, final SecurityService securityService, final Cache<Object, Instance> cache,
-                             final Duration accessTimeout, final boolean preventExtendedEntityManagerSerialization) {
+                             final Duration accessTimeout, final boolean preventExtendedEntityManagerSerialization,
+                             final LockFactory lockFactory) {
         this.containerID = id;
         this.securityService = securityService;
         this.cache = cache;
@@ -123,6 +125,8 @@ public class StatefulContainer implement
         this.accessTimeout = accessTimeout;
         sessionContext = new StatefulContext(this.securityService, new StatefulUserTransaction(new EjbUserTransaction(), entityManagerRegistry));
         this.preventExtendedEntityManagerSerialization = preventExtendedEntityManagerSerialization;
+        this.lockFactory = lockFactory;
+        this.lockFactory.setContainer(this);
     }
 
     private Map<Method, MethodType> getLifecycleMethodsOfInterface(final BeanContext beanContext) {
@@ -234,6 +238,14 @@ public class StatefulContainer implement
         return methods;
     }
 
+    public LockFactory getLockFactory() {
+        return lockFactory;
+    }
+
+    public Cache<Object, Instance> getCache() {
+        return cache;
+    }
+
     public static enum MethodType {
         CREATE,
         REMOVE,
@@ -410,7 +422,7 @@ public class StatefulContainer implement
                     final InstanceContext context = beanContext.newInstance();
 
                     // Wrap-up everthing into a object
-                    instance = new Instance(beanContext, primaryKey, context.getBean(), context.getCreationalContext(), context.getInterceptors(), entityManagers);
+                    instance = new Instance(beanContext, primaryKey, containerID, context.getBean(), context.getCreationalContext(), context.getInterceptors(), entityManagers, lockFactory.newLock(primaryKey.toString()));
 
                 } catch (final Throwable throwable) {
                     final ThreadContext callContext = ThreadContext.getThreadContext();
@@ -727,7 +739,7 @@ public class StatefulContainer implement
 
         final Duration accessTimeout = getAccessTimeout(instance.beanContext, callMethod);
 
-        final Lock currLock = instance.getLock();
+        final LockFactory.StatefulLock currLock = instance.getLock();
         final boolean lockAcquired;
         if (accessTimeout == null || accessTimeout.getTime() < 0) {
             // wait indefinitely for a lock

Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java?rev=1602336&r1=1602335&r2=1602336&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/core/stateful/StatefulContainerFactory.java Fri Jun 13 08:26:33 2014
@@ -19,6 +19,7 @@ package org.apache.openejb.core.stateful
 
 import org.apache.openejb.spi.SecurityService;
 import org.apache.openejb.util.Duration;
+import org.apache.openejb.util.SuperProperties;
 import org.apache.xbean.recipe.ObjectRecipe;
 import org.apache.xbean.recipe.Option;
 
@@ -30,7 +31,7 @@ public class StatefulContainerFactory {
     private Object id;
     private SecurityService securityService;
     private Cache<Object, Instance> cache;
-    private Properties properties = new Properties();
+    private Properties properties = new SuperProperties().caseInsensitive(false);
     private Duration accessTimeout = new Duration(0, TimeUnit.MILLISECONDS);
 
     public Object getId() {
@@ -107,7 +108,23 @@ public class StatefulContainerFactory {
             buildCache();
         }
         cache.init();
-        return new StatefulContainer(id, securityService, cache, accessTimeout, properties.containsKey("PreventExtendedEntityManagerSerialization"));
+        return new StatefulContainer(
+                id, securityService,
+                cache, accessTimeout,
+                "true".equalsIgnoreCase(properties.getProperty("PreventExtendedEntityManagerSerialization", "false").trim()),
+                createLockFactory());
+    }
+
+    private LockFactory createLockFactory() {
+        final Object lockFactory = properties.remove("LockFactory");
+        if (lockFactory != null) {
+            try {
+                return LockFactory.class.cast(StatefulContainerFactory.class.getClassLoader().loadClass(lockFactory.toString().trim()).newInstance());
+            } catch (final Exception e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+        return new DefaultLockFactory();
     }
 
     private void buildCache() throws Exception {

Modified: tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StatefulDecoratorInjectionTest.java
URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StatefulDecoratorInjectionTest.java?rev=1602336&r1=1602335&r2=1602336&view=diff
==============================================================================
--- tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StatefulDecoratorInjectionTest.java (original)
+++ tomee/tomee/trunk/container/openejb-core/src/test/java/org/apache/openejb/cdi/StatefulDecoratorInjectionTest.java Fri Jun 13 08:26:33 2014
@@ -61,8 +61,8 @@ public class StatefulDecoratorInjectionT
             orange.someBusinessMethod();
 
             fail("call should not be allowed");
-        } catch (EJBException e) {
-            assertTrue(AccessDeniedException.class.isInstance(e.getCause()));
+        } catch (AccessDeniedException e) {
+            // ok
         }
     }