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
}
}