[prev in list] [next in list] [prev in thread] [next in thread]
List: openejb-cvs
Subject: svn commit: r672684 - in /openejb/trunk/openejb3: api/ejb31-api-experimental/
From: dblevins () apache ! org
Date: 2008-06-30 0:00:26
Message-ID: 20080630000027.2C0E22388A02 () eris ! apache ! org
[Download RAW message or body]
Author: dblevins
Date: Sun Jun 29 17:00:25 2008
New Revision: 672684
URL: http://svn.apache.org/viewvc?rev=672684&view=rev
Log:
Good chunk of the container side of the following:
OPENEJB-837: Singleton Bean-Managed Concurrency
OPENEJB-838: Singleton Container-Managed Concurrency
OPENEJB-839: ReadOnly and ReadWrite method locking
No deployment support yet, though
Added:
openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagement.java
openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagementType.java
openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrentAccessTimeoutException.java
openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Lock.java
openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/LockType.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Duration.java
openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/DurationTest.java
Modified:
openejb/trunk/openejb3/api/ejb31-api-experimental/pom.xml
openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/Instance.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java
openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml
openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
Modified: openejb/trunk/openejb3/api/ejb31-api-experimental/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/api/ejb31-api-experimental/pom.xml?rev=672684&r1=672683&r2=672684&view=diff
==============================================================================
--- openejb/trunk/openejb3/api/ejb31-api-experimental/pom.xml (original)
+++ openejb/trunk/openejb3/api/ejb31-api-experimental/pom.xml Sun Jun 29 17:00:25 \
2008 @@ -27,4 +27,12 @@
<packaging>jar</packaging>
<name>OpenEJB :: APIs :: EJB 3.1 Experimental</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>javaee-api</artifactId>
+ <version>5.0-1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
</project>
Added: openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagement.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagement.java?rev=672684&view=auto
==============================================================================
--- openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagement.java \
(added)
+++ openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagement.java \
Sun Jun 29 17:00:25 2008 @@ -0,0 +1,12 @@
+package javax.ejb;
+
+import static javax.ejb.ConcurrencyManagementType.CONTAINER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+
+@java.lang.annotation.Target(value = {METHOD, TYPE})
+@java.lang.annotation.Retention(value = RUNTIME)
+public @interface ConcurrencyManagement {
+ javax.ejb.ConcurrencyManagementType value() default CONTAINER;
+}
Added: openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagementType.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagementType.java?rev=672684&view=auto
==============================================================================
--- openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagementType.java \
(added)
+++ openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrencyManagementType.java \
Sun Jun 29 17:00:25 2008 @@ -0,0 +1,30 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.ejb;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public enum ConcurrencyManagementType {
+ CONTAINER, BEAN;
+}
Added: openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrentAccessTimeoutException.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrentAccessTimeoutException.java?rev=672684&view=auto
==============================================================================
--- openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrentAccessTimeoutException.java \
(added)
+++ openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/ConcurrentAccessTimeoutException.java \
Sun Jun 29 17:00:25 2008 @@ -0,0 +1,40 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.
+ */
+
+//
+// This source code implements specifications defined by the Java
+// Community Process. In order to remain compliant with the specification
+// DO NOT add / change / or delete method signatures!
+//
+package javax.ejb;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class ConcurrentAccessTimeoutException extends \
javax.ejb.ConcurrentAccessException { +
+ public ConcurrentAccessTimeoutException() {
+ }
+
+ public ConcurrentAccessTimeoutException(String string) {
+ super(string);
+ }
+
+ public ConcurrentAccessTimeoutException(String string, Exception exception) {
+ super(string, exception);
+ }
+}
Added: openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Lock.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Lock.java?rev=672684&view=auto
==============================================================================
--- openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Lock.java \
(added)
+++ openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/Lock.java \
Sun Jun 29 17:00:25 2008 @@ -0,0 +1,12 @@
+package javax.ejb;
+
+import static javax.ejb.LockType.WRITE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.METHOD;
+
+@java.lang.annotation.Target(value = {METHOD, TYPE})
+@java.lang.annotation.Retention(value = RUNTIME)
+public @interface Lock {
+ javax.ejb.LockType value() default WRITE;
+}
Added: openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/LockType.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/LockType.java?rev=672684&view=auto
==============================================================================
--- openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/LockType.java \
(added)
+++ openejb/trunk/openejb3/api/ejb31-api-experimental/src/main/java/javax/ejb/LockType.java \
Sun Jun 29 17:00:25 2008 @@ -0,0 +1,8 @@
+package javax.ejb;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public enum LockType {
+ WRITE, READ;
+}
Modified: openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/opene \
jb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml?rev=672684&r1=672683&r2=672684&view=diff
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml \
(original)
+++ openejb/trunk/openejb3/assembly/openejb-tomcat/openejb-tomcat-webapp/src/main/resources/META-INF/org.apache.openejb.tomcat/service-jar.xml \
Sun Jun 29 17:00:25 2008 @@ -132,6 +132,8 @@
constructor="id, transactionManager, securityService"
class-name="org.apache.openejb.core.singleton.SingletonContainer">
+ AccessTimeout = 30 seconds
+
</ServiceProvider>
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/Instance.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/ma \
in/java/org/apache/openejb/core/singleton/Instance.java?rev=672684&r1=672683&r2=672684&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/Instance.java \
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/Instance.java \
Sun Jun 29 17:00:25 2008 @@ -16,9 +16,8 @@
*/
package org.apache.openejb.core.singleton;
-import java.util.List;
-import java.util.Collections;
import java.util.Map;
+import java.util.concurrent.locks.ReadWriteLock;
/**
* @version $Rev$ $Date$
@@ -26,9 +25,11 @@
public class Instance {
public final Object bean;
public final Map<String,Object> interceptors;
+ public final ReadWriteLock lock;
- public Instance(Object bean, Map<String, Object> interceptors) {
+ public Instance(Object bean, Map<String, Object> interceptors, ReadWriteLock \
lock) { this.bean = bean;
this.interceptors = interceptors;
+ this.lock = lock;
}
}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/ma \
in/java/org/apache/openejb/core/singleton/SingletonContainer.java?rev=672684&r1=672683&r2=672684&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java \
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonContainer.java \
Sun Jun 29 17:00:25 2008 @@ -21,12 +21,15 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.TimeUnit;
import javax.ejb.EJBAccessException;
import javax.ejb.EJBHome;
import javax.ejb.EJBLocalHome;
import javax.ejb.EJBLocalObject;
import javax.ejb.EJBObject;
+import javax.ejb.ConcurrentAccessTimeoutException;
import javax.interceptor.AroundInvoke;
import javax.transaction.TransactionManager;
@@ -35,6 +38,7 @@
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.ProxyInfo;
import org.apache.openejb.InterfaceType;
+import org.apache.openejb.util.Duration;
import org.apache.openejb.core.CoreDeploymentInfo;
import org.apache.openejb.core.Operation;
import org.apache.openejb.core.ThreadContext;
@@ -60,6 +64,9 @@
private Object containerID = null;
private TransactionManager transactionManager;
private SecurityService securityService;
+ private long wait = 30;
+ private TimeUnit unit = TimeUnit.SECONDS;
+
public SingletonContainer(Object id, TransactionManager transactionManager, \
SecurityService securityService) throws OpenEJBException { this.containerID = id;
@@ -74,6 +81,11 @@
}
}
+ public void setAccessTimeout(Duration duration){
+ this.unit = duration.getUnit();
+ this.wait = duration.getTime();
+ }
+
public synchronized DeploymentInfo [] deployments() {
return deploymentRegistry.values().toArray(new \
DeploymentInfo[deploymentRegistry.size()]); }
@@ -153,7 +165,7 @@
return null;// EJBObject.remove( ) and other EJBObject methods are \
not process by the container }
- Object bean = instanceManager.getInstance(callContext);
+ Instance instance = instanceManager.getInstance(callContext);
callContext.setCurrentOperation(Operation.BUSINESS);
callContext.setCurrentAllowedStates(SingletonContext.getStates());
@@ -162,8 +174,7 @@
callContext.set(Method.class, runMethod);
callContext.setInvokedInterface(callInterface);
- Object retValue = _invoke(callInterface, callMethod, runMethod, args, \
bean, callContext);
- instanceManager.poolInstance(callContext, bean);
+ Object retValue = _invoke(callInterface, callMethod, runMethod, args, \
instance, callContext);
return retValue;
@@ -196,53 +207,80 @@
TransactionContext txContext = new TransactionContext(callContext, \
getTransactionManager()); txContext.callContext = callContext;
- txPolicy.beforeInvoke(instance, txContext);
- Object returnValue = null;
+ boolean read = false; // TODO: get meta data from DeploymentInfo
+ final Lock lock = aquireLock(read, instance);
+
+ Object returnValue;
try {
- InterfaceType type = deploymentInfo.getInterfaceType(callInterface);
- if (type == InterfaceType.SERVICE_ENDPOINT){
- callContext.setCurrentOperation(Operation.BUSINESS_WS);
- returnValue = invokeWebService(args, deploymentInfo, runMethod, \
instance, returnValue);
- } else {
- List<InterceptorData> interceptors = \
deploymentInfo.getMethodInterceptors(runMethod);
- InterceptorStack interceptorStack = new \
InterceptorStack(instance.bean, runMethod, Operation.BUSINESS, interceptors, \
instance.interceptors);
- returnValue = interceptorStack.invoke(args);
- }
- } catch (Throwable re) {// handle reflection exception
- ExceptionType type = deploymentInfo.getExceptionType(re);
- if (type == ExceptionType.SYSTEM) {
- /* System Exception ****************************/
-
- /**
- * The bean instance is not put into the pool via \
instanceManager.poolInstance
- * and therefore the instance will be garbage collected and \
destroyed.
- * For this reason the discardInstance method of the \
StatelessInstanceManager
- * does nothing.
- */
-
- txPolicy.handleSystemException(re, instance, txContext);
- } else {
- /* Application Exception ***********************/
+ txPolicy.beforeInvoke(instance, txContext);
- txPolicy.handleApplicationException(re, type == \
ExceptionType.APPLICATION_ROLLBACK, txContext); + returnValue = null;
+ try {
+ InterfaceType type = deploymentInfo.getInterfaceType(callInterface);
+ if (type == InterfaceType.SERVICE_ENDPOINT){
+ callContext.setCurrentOperation(Operation.BUSINESS_WS);
+ returnValue = invokeWebService(args, deploymentInfo, runMethod, \
instance); + } else {
+ List<InterceptorData> interceptors = \
deploymentInfo.getMethodInterceptors(runMethod); + \
InterceptorStack interceptorStack = new InterceptorStack(instance.bean, runMethod, \
Operation.BUSINESS, interceptors, instance.interceptors); + \
returnValue = interceptorStack.invoke(args); + }
+ } catch (Throwable re) {// handle reflection exception
+ ExceptionType type = deploymentInfo.getExceptionType(re);
+ if (type == ExceptionType.SYSTEM) {
+ /* System Exception ****************************/
+
+ /**
+ * The bean instance is not put into the pool via \
instanceManager.poolInstance + * and therefore the instance will \
be garbage collected and destroyed. + * For this reason the \
discardInstance method of the StatelessInstanceManager + * does \
nothing. + */
+
+ txPolicy.handleSystemException(re, instance, txContext);
+ } else {
+ /* Application Exception ***********************/
+
+ txPolicy.handleApplicationException(re, type == \
ExceptionType.APPLICATION_ROLLBACK, txContext); + }
+ } finally {
+ txPolicy.afterInvoke(instance, txContext);
}
} finally {
- instanceManager.poolInstance(callContext, instance);
-
- txPolicy.afterInvoke(instance, txContext);
+ lock.unlock();
}
return returnValue;
}
- private Object invokeWebService(Object[] args, CoreDeploymentInfo \
deploymentInfo, Method runMethod, Instance instance, Object returnValue) throws \
Exception { + private Lock aquireLock(boolean read, Instance instance) {
+ final Lock lock;
+ if (read) {
+ lock = instance.lock.readLock();
+ } else {
+ lock = instance.lock.writeLock();
+ }
+
+ try {
+ if (!lock.tryLock(wait, unit)){
+ throw new ConcurrentAccessTimeoutException();
+ }
+ } catch (InterruptedException e) {
+ throw (ConcurrentAccessTimeoutException) new \
ConcurrentAccessTimeoutException().initCause(e); + }
+ return lock;
+ }
+
+ private Object invokeWebService(Object[] args, CoreDeploymentInfo \
deploymentInfo, Method runMethod, Instance instance) throws Exception { if \
(args.length != 2){
throw new IllegalArgumentException("WebService calls must follow format \
{messageContext, interceptor}."); }
Object messageContext = args[0];
+ if (messageContext == null) throw new \
IllegalArgumentException("MessageContext is null."); +
// This object will be used as an interceptor in the stack and will be \
responsible
// for unmarshalling the soap message parts into an argument list that will \
be // used for the actual method invocation.
@@ -251,6 +289,7 @@
// of our stack.
Object interceptor = args[1];
+ if (interceptor == null) throw new IllegalArgumentException("Interceptor \
instance is null.");
// Add the webservice interceptor to the list of interceptor instances
Map<String, Object> interceptors = new HashMap<String, \
Object>(instance.interceptors); @@ -271,12 +310,12 @@
Object[] params = new Object[runMethod.getParameterTypes().length];
if (messageContext instanceof javax.xml.rpc.handler.MessageContext) {
ThreadContext.getThreadContext().set(javax.xml.rpc.handler.MessageContext.class, \
(javax.xml.rpc.handler.MessageContext) messageContext);
- returnValue = \
interceptorStack.invoke((javax.xml.rpc.handler.MessageContext) messageContext, \
params); + return \
interceptorStack.invoke((javax.xml.rpc.handler.MessageContext) messageContext, \
params);
} else if (messageContext instanceof javax.xml.ws.handler.MessageContext) {
ThreadContext.getThreadContext().set(javax.xml.ws.handler.MessageContext.class, \
(javax.xml.ws.handler.MessageContext) messageContext);
- returnValue = \
interceptorStack.invoke((javax.xml.ws.handler.MessageContext) messageContext, \
params); + return \
interceptorStack.invoke((javax.xml.ws.handler.MessageContext) messageContext, \
params); }
- return returnValue;
+ throw new IllegalArgumentException("Uknown MessageContext type: " + \
messageContext.getClass().getName()); }
private TransactionManager getTransactionManager() {
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/ma \
in/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java?rev=672684&r1=672683&r2=672684&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java \
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/singleton/SingletonInstanceManager.java \
Sun Jun 29 17:00:25 2008 @@ -22,7 +22,11 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.Semaphore;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.TimeUnit;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
@@ -33,7 +37,6 @@
import org.apache.openejb.Injection;
import org.apache.openejb.OpenEJBException;
-import org.apache.openejb.SystemException;
import org.apache.openejb.core.BaseContext;
import org.apache.openejb.core.CoreDeploymentInfo;
import org.apache.openejb.core.Operation;
@@ -41,11 +44,9 @@
import org.apache.openejb.core.interceptor.InterceptorData;
import org.apache.openejb.core.interceptor.InterceptorStack;
import org.apache.openejb.spi.SecurityService;
-import org.apache.openejb.util.LinkedListStack;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
import org.apache.openejb.util.SafeToolkit;
-import org.apache.openejb.util.Stack;
import org.apache.xbean.recipe.ConstructionException;
import org.apache.xbean.recipe.ObjectRecipe;
import org.apache.xbean.recipe.Option;
@@ -54,12 +55,6 @@
public class SingletonInstanceManager {
private static final Logger logger = Logger.getInstance(LogCategory.OPENEJB, \
"org.apache.openejb.util.resources");
- protected int poolLimit = 0;
- protected int beanCount = 0;
- protected boolean strictPooling = false;
-
- protected HashMap<Object,Semaphore> semaphores;
-
protected final SafeToolkit toolkit = \
SafeToolkit.getToolkit("SingletonInstanceManager"); private TransactionManager \
transactionManager; private SecurityService securityService;
@@ -67,12 +62,6 @@
public SingletonInstanceManager(TransactionManager transactionManager, \
SecurityService securityService) { this.transactionManager = transactionManager;
this.securityService = securityService;
- this.poolLimit = 1;
- this.strictPooling = true;
-
- if (this.strictPooling) {
- this.semaphores = new HashMap();
- }
}
/**
@@ -90,21 +79,12 @@
* @return
* @throws OpenEJBException
*/
- public Object getInstance(ThreadContext callContext)
+ public Instance getInstance(ThreadContext callContext)
throws OpenEJBException {
CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
Data data = (Data) deploymentInfo.getContainerData();
- Stack pool = data.getPool();
- if(strictPooling){
- try {
- semaphores.get(deploymentInfo.getDeploymentID()).acquire();
- } catch (InterruptedException e2) {
- throw new OpenEJBException("Unexpected Interruption of current \
thread: ",e2);
- }
- }
- Object bean = pool.pop();
- if (bean == null) {
+ if (data.instance == null) {
Class beanClass = deploymentInfo.getBeanClass();
ObjectRecipe objectRecipe = new ObjectRecipe(beanClass);
@@ -150,7 +130,7 @@
fillInjectionProperties(objectRecipe, beanClass, deploymentInfo, \
ctx);
- bean = objectRecipe.create(beanClass.getClassLoader());
+ Object bean = objectRecipe.create(beanClass.getClassLoader());
Map unsetProperties = objectRecipe.getUnsetProperties();
if (unsetProperties.size() > 0) {
for (Object property : unsetProperties.keySet()) {
@@ -205,12 +185,21 @@
throw e;
}
- bean = new Instance(bean, interceptorInstances);
+ ReadWriteLock lock;
+ if (false){ // TODO: Get metadata from DeploymentInfo
+ // Bean-Managed Concurrency
+ lock = new BeanManagedLock();
+ } else {
+ // Container-Managed Concurrency
+ lock = new ReentrantReadWriteLock();
+ }
+
+ data.instance = new Instance(bean, interceptorInstances, lock);
} catch (Throwable e) {
if (e instanceof java.lang.reflect.InvocationTargetException) {
e = ((java.lang.reflect.InvocationTargetException) \
e).getTargetException(); }
- String t = "The bean instance " + bean + " threw a system \
exception:" + e; + String t = "The bean instance threw a system \
exception:" + e; logger.error(t, e);
throw new org.apache.openejb.ApplicationException(new \
RemoteException("Cannot obtain a free instance.", e)); } finally {
@@ -218,7 +207,8 @@
callContext.setCurrentAllowedStates(originalAllowedStates);
}
}
- return bean;
+
+ return data.instance;
}
private static void fillInjectionProperties(ObjectRecipe objectRecipe, Class \
clazz, CoreDeploymentInfo deploymentInfo, Context context) { @@ -271,41 +261,7 @@
return new SingletonContext(transactionManager, securityService);
}
- /**
- * All instances are removed from the pool in getInstance(...). They are only
- * returned by the StatelessContainer via this method under two circumstances.
- *
- * 1. The business method returns normally
- * 2. The business method throws an application exception
- *
- * Instances are not returned to the pool if the business method threw a system
- * exception.
- *
- * @param callContext
- * @param bean
- * @throws OpenEJBException
- */
- public void poolInstance(ThreadContext callContext, Object bean) throws \
OpenEJBException {
- if (bean == null) {
- throw new SystemException("Invalid arguments");
- }
-
- CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
- Data data = (Data) deploymentInfo.getContainerData();
- Stack pool = data.getPool();
-
- if (strictPooling) {
- pool.push(bean);
- semaphores.get(deploymentInfo.getDeploymentID()).release();
- } else {
- if (pool.size() >= poolLimit) {
- freeInstance(callContext, (Instance)bean);
- } else {
- pool.push(bean);
- }
- }
- }
-
+ // TODO: Call on system shutdown
private void freeInstance(ThreadContext callContext, Instance instance) {
try {
callContext.setCurrentOperation(Operation.PRE_DESTROY);
@@ -337,36 +293,51 @@
}
public void deploy(CoreDeploymentInfo deploymentInfo) {
- Data data = new Data(poolLimit);
+ Data data = new Data();
deploymentInfo.setContainerData(data);
- if (this.strictPooling) {
- this.semaphores.put(deploymentInfo.getDeploymentID(), new \
Semaphore(poolLimit));
- }
-
}
public void undeploy(CoreDeploymentInfo deploymentInfo) {
Data data = (Data) deploymentInfo.getContainerData();
- if (this.strictPooling) {
- semaphores.remove(deploymentInfo.getDeploymentID());
- }
if (data == null) return;
- Stack pool = data.getPool();
- //TODO ejbRemove on each bean in pool.
- //clean pool
deploymentInfo.setContainerData(null);
}
private static final class Data {
- private final Stack pool;
+ private Instance instance;
+ }
+
+
+ private static class BeanManagedLock implements ReadWriteLock {
+ private final Lock lock = new Lock(){
+ public void lock() {
+ }
- public Data(int poolLimit) {
- pool = new LinkedListStack(poolLimit);
+ public void lockInterruptibly() {
+ }
+
+ public Condition newCondition() {
+ throw new java.lang.UnsupportedOperationException("newCondition()");
+ }
+
+ public boolean tryLock() {
+ return true;
+ }
+
+ public boolean tryLock(long time, TimeUnit unit) {
+ return true;
+ }
+
+ public void unlock() {
+ }
+ };
+
+ public Lock readLock() {
+ return lock;
}
- public Stack getPool() {
- return pool;
+ public Lock writeLock() {
+ return lock;
}
}
-
}
Added: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Duration.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Duration.java?rev=672684&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Duration.java \
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/Duration.java \
Sun Jun 29 17:00:25 2008 @@ -0,0 +1,241 @@
+/**
+ * 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.util;
+
+import java.beans.PropertyEditorManager;
+import java.util.concurrent.TimeUnit;
+
+public class Duration {
+
+ private long time;
+ private TimeUnit unit;
+
+ public Duration() {
+ }
+
+ public Duration(long time, TimeUnit unit) {
+ this.time = time;
+ this.unit = unit;
+ }
+
+ public Duration(String string) {
+ parse(string, this);
+ }
+
+ public long getTime() {
+ return time;
+ }
+
+ public void setTime(long time) {
+ this.time = time;
+ }
+
+ public TimeUnit getUnit() {
+ return unit;
+ }
+
+ public void setUnit(TimeUnit unit) {
+ this.unit = unit;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final Duration duration = (Duration) o;
+
+ if (time != duration.time) return false;
+ if (unit != duration.unit) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = (int) (time ^ (time >>> 32));
+ result = 29 * result + (unit != null ? unit.hashCode() : 0);
+ return result;
+ }
+
+ public String toString() {
+ if (unit == null){
+ return time + "";
+ } else {
+ return time + " " + unit;
+ }
+ }
+
+ public static Duration parse(String text) {
+ Duration d = new Duration();
+ parse(text, d);
+ return d;
+ }
+
+ private static void parse(String text, Duration d) {
+ text = text.trim();
+
+ StringBuilder t = new StringBuilder();
+ StringBuilder u = new StringBuilder();
+
+ int i = 0;
+
+ // get the number
+ for (; i < text.length(); i++) {
+ char c = text.charAt(i);
+ System.out.println("a "+c);
+ if (Character.isDigit(c) || i == 0 && c == '-') {
+ t.append(c);
+ } else {
+ break;
+ }
+ }
+
+ if (t.length() == 0){
+ invalidFormat(text);
+ }
+
+ // skip whitespace
+ for (; i < text.length(); i++) {
+ char c = text.charAt(i);
+ System.out.println("b "+c);
+ if (Character.isWhitespace(c)) {
+ } else {
+ break;
+ }
+ }
+
+ // get time unit text part
+ for (; i < text.length(); i++) {
+ char c = text.charAt(i);
+ System.out.println("c "+c);
+ if (Character.isLetter(c)) {
+ u.append(c);
+ } else {
+ invalidFormat(text);
+ }
+ }
+
+ d.time = Integer.parseInt(t.toString());
+
+ Unit unit = parseUnit(u.toString());
+
+ if (unit != null) switch (unit) {
+ case days: {
+ d.time *= 60 * 60 * 24;
+ d.unit = TimeUnit.SECONDS;
+ }
+ ;
+ break;
+ case hours: {
+ d.time *= 60 * 60;
+ d.unit = TimeUnit.SECONDS;
+ }
+ ;
+ break;
+ case minutes: {
+ d.time *= 60;
+ d.unit = TimeUnit.SECONDS;
+ }
+ ;
+ break;
+ case seconds: {
+ d.unit = TimeUnit.SECONDS;
+ }
+ ;
+ break;
+ case milliseconds: {
+ d.unit = TimeUnit.MILLISECONDS;
+ }
+ ;
+ break;
+ case microseconds: {
+ d.unit = TimeUnit.MICROSECONDS;
+ }
+ ;
+ break;
+ case nanoseconds: {
+ d.unit = TimeUnit.NANOSECONDS;
+ }
+ ;
+ break;
+ }
+ }
+
+ private static void invalidFormat(String text) {
+ throw new IllegalArgumentException("Illegal duration format: '"+text+"'. \
Valid examples are '10s' or '10 seconds'."); + }
+
+ private static Unit parseUnit(String u) {
+ if (u.length() == 0) return null;
+
+ if (u.equalsIgnoreCase("NANOSECONDS")) return Unit.nanoseconds;
+ if (u.equalsIgnoreCase("NANOSECOND")) return Unit.nanoseconds;
+ if (u.equalsIgnoreCase("NANOS")) return Unit.nanoseconds;
+ if (u.equalsIgnoreCase("NANO")) return Unit.nanoseconds;
+ if (u.equalsIgnoreCase("NS")) return Unit.nanoseconds;
+
+ if (u.equalsIgnoreCase("MICROSECONDS")) return Unit.microseconds;
+ if (u.equalsIgnoreCase("MICROSECOND")) return Unit.microseconds;
+ if (u.equalsIgnoreCase("MICROS")) return Unit.microseconds;
+ if (u.equalsIgnoreCase("MICRO")) return Unit.microseconds;
+
+ if (u.equalsIgnoreCase("MILLISECONDS")) return Unit.milliseconds;
+ if (u.equalsIgnoreCase("MILLISECOND")) return Unit.milliseconds;
+ if (u.equalsIgnoreCase("MILLIS")) return Unit.milliseconds;
+ if (u.equalsIgnoreCase("MILLI")) return Unit.milliseconds;
+ if (u.equalsIgnoreCase("MS")) return Unit.milliseconds;
+
+ if (u.equalsIgnoreCase("SECONDS")) return Unit.seconds;
+ if (u.equalsIgnoreCase("SECOND")) return Unit.seconds;
+ if (u.equalsIgnoreCase("SEC")) return Unit.seconds;
+ if (u.equalsIgnoreCase("S")) return Unit.seconds;
+
+ if (u.equalsIgnoreCase("MINUTES")) return Unit.minutes;
+ if (u.equalsIgnoreCase("MINUTE")) return Unit.minutes;
+ if (u.equalsIgnoreCase("MIN")) return Unit.minutes;
+ if (u.equalsIgnoreCase("M")) return Unit.minutes;
+
+ if (u.equalsIgnoreCase("HOURS")) return Unit.hours;
+ if (u.equalsIgnoreCase("HOUR")) return Unit.hours;
+ if (u.equalsIgnoreCase("HRS")) return Unit.hours;
+ if (u.equalsIgnoreCase("HR")) return Unit.hours;
+ if (u.equalsIgnoreCase("H")) return Unit.hours;
+
+ if (u.equalsIgnoreCase("DAYS")) return Unit.days;
+ if (u.equalsIgnoreCase("DAY")) return Unit.days;
+ if (u.equalsIgnoreCase("D")) return Unit.days;
+
+ throw new IllegalArgumentException("Unknown time unit '" + u + "'. \
Supported units " + Join.join(", ", Unit.values())); + }
+
+
+ static {
+ PropertyEditorManager.registerEditor(Duration.class, Editor.class);
+ }
+
+ public static class Editor extends java.beans.PropertyEditorSupport {
+ public void setAsText(String text) {
+ Duration d = parse(text);
+ setValue(d);
+ }
+ }
+
+ public static enum Unit {
+ // All lowercase so they look good displayed in help
+ nanoseconds, microseconds, milliseconds, seconds, minutes, hours, days;
+ }
+}
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/ma \
in/resources/META-INF/org.apache.openejb.embedded/service-jar.xml?rev=672684&r1=672683&r2=672684&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml \
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb.embedded/service-jar.xml \
Sun Jun 29 17:00:25 2008 @@ -124,6 +124,8 @@
constructor="id, transactionManager, securityService"
class-name="org.apache.openejb.core.singleton.SingletonContainer">
+ AccessTimeout = 30 seconds
+
</ServiceProvider>
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/ma \
in/resources/META-INF/org.apache.openejb/service-jar.xml?rev=672684&r1=672683&r2=672684&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml \
(original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/resources/META-INF/org.apache.openejb/service-jar.xml \
Sun Jun 29 17:00:25 2008 @@ -127,6 +127,8 @@
constructor="id, transactionManager, securityService"
class-name="org.apache.openejb.core.singleton.SingletonContainer">
+ AccessTimeout = 30 seconds
+
</ServiceProvider>
Added: openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/DurationTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/DurationTest.java?rev=672684&view=auto
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/DurationTest.java \
(added)
+++ openejb/trunk/openejb3/container/openejb-core/src/test/java/org/apache/openejb/util/DurationTest.java \
Sun Jun 29 17:00:25 2008 @@ -0,0 +1,49 @@
+/**
+ * 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.util;
+
+import junit.framework.TestCase;
+
+import static java.util.concurrent.TimeUnit.MICROSECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class DurationTest extends TestCase {
+
+ public void test() throws Exception {
+
+ assertEquals(new Duration(1000, MILLISECONDS), new Duration("1000ms"));
+ assertEquals(new Duration(1000, MILLISECONDS), new Duration("1000 ms"));
+ assertEquals(new Duration(1000, MILLISECONDS), new Duration("1000 ms"));
+
+ assertEquals(new Duration(60, SECONDS), new Duration("1m"));
+ assertEquals(new Duration(3600, SECONDS), new Duration("1h"));
+ assertEquals(new Duration(86400, SECONDS), new Duration("1d"));
+
+ assertEquals(new Duration(1000, MICROSECONDS), new Duration("1000 \
microseconds")); + assertEquals(new Duration(1000, NANOSECONDS), new \
Duration("1000 nanoseconds")); +
+ assertEquals(new Duration(1, null), new Duration("1"));
+ assertEquals(new Duration(234, null), new Duration("234"));
+ assertEquals(new Duration(123, null), new Duration("123"));
+ assertEquals(new Duration(-1, null), new Duration("-1"));
+ }
+}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic