You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by ma...@apache.org on 2008/04/02 15:32:27 UTC
svn commit: r643904 -
/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
Author: manugeorge
Date: Wed Apr 2 06:32:25 2008
New Revision: 643904
URL: http://svn.apache.org/viewvc?rev=643904&view=rev
Log:
reverting back to older revision = 643871
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java?rev=643904&r1=643903&r2=643904&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java (original)
+++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java Wed Apr 2 06:32:25 2008
@@ -1,376 +1,368 @@
-/**
- * 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.stateless;
-
-import java.lang.reflect.Method;
-import java.rmi.RemoteException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.ejb.SessionBean;
-import javax.ejb.SessionContext;
-import javax.naming.Context;
-import javax.naming.NamingException;
-import javax.transaction.TransactionManager;
-import javax.xml.ws.WebServiceContext;
-
-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;
-import org.apache.openejb.core.ThreadContext;
-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;
-import org.apache.xbean.recipe.StaticRecipe;
-
-public class StatelessInstanceManager {
- 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 PoolQueue poolQueue = null;
-
- protected final SafeToolkit toolkit = SafeToolkit.getToolkit("StatefulInstanceManager");
- private TransactionManager transactionManager;
- private SecurityService securityService;
-
- public StatelessInstanceManager(TransactionManager transactionManager, SecurityService securityService, int timeout, int poolSize, boolean strictPooling) {
- this.transactionManager = transactionManager;
- this.securityService = securityService;
- this.poolLimit = poolSize;
- this.strictPooling = strictPooling;
-
- if (strictPooling && poolSize < 1) {
- throw new IllegalArgumentException("Cannot use strict pooling with a pool size less than one. Strict pooling blocks threads till an instance in the pool is available. Please increase the pool size or set strict pooling to false");
- }
-
- if (this.strictPooling) {
- poolQueue = new PoolQueue(timeout);
- }
- }
-
- /**
- * Removes an instance from the pool and returns it for use
- * by the container in business methods.
- *
- * If the pool is at it's limit the StrictPooling flag will
- * cause this thread to wait.
- *
- * If StrictPooling is not enabled this method will create a
- * new stateless bean instance performing all required injection
- * and callbacks before returning it in a method ready state.
- *
- * @param callContext
- * @return
- * @throws OpenEJBException
- */
- public Object getInstance(ThreadContext callContext)
- throws OpenEJBException {
- CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
- Data data = (Data) deploymentInfo.getContainerData();
- Stack pool = data.getPool();
- Object bean = pool.pop();
- if(strictPooling){
- synchronized(pool){
- while (bean == null && pool.size() >= poolLimit) {
- poolQueue.waitForAvailableInstance();
- bean = pool.pop();
- }
- }
- }
- if (bean == null) {
-
- Class beanClass = deploymentInfo.getBeanClass();
- ObjectRecipe objectRecipe = new ObjectRecipe(beanClass);
- objectRecipe.allow(Option.FIELD_INJECTION);
- objectRecipe.allow(Option.PRIVATE_PROPERTIES);
- objectRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
-
- Operation originalOperation = callContext.getCurrentOperation();
- BaseContext.State[] originalAllowedStates = callContext.getCurrentAllowedStates();
-
- try {
- Context ctx = deploymentInfo.getJndiEnc();
- SessionContext sessionContext;
- // This needs to be synchronized as this code is multi-threaded.
- // In between the lookup and the bind a bind may take place in another Thread.
- // This is a fix for GERONIMO-3444
- synchronized(this){
- try {
- sessionContext = (SessionContext) ctx.lookup("java:comp/EJBContext");
- } catch (NamingException e1) {
- sessionContext = createSessionContext();
- // TODO: This should work
- ctx.bind("java:comp/EJBContext", sessionContext);
- }
- }
- if (javax.ejb.SessionBean.class.isAssignableFrom(beanClass) || hasSetSessionContext(beanClass)) {
- callContext.setCurrentOperation(Operation.INJECTION);
- callContext.setCurrentAllowedStates(StatelessContext.getStates());
- objectRecipe.setProperty("sessionContext", new StaticRecipe(sessionContext));
- }
-
- WebServiceContext wsContext;
- // This is a fix for GERONIMO-3444
- synchronized(this){
- try {
- wsContext = (WebServiceContext) ctx.lookup("java:comp/WebServiceContext");
- } catch (NamingException e) {
- wsContext = new EjbWsContext(sessionContext);
- ctx.bind("java:comp/WebServiceContext", wsContext);
- }
- }
-
- fillInjectionProperties(objectRecipe, beanClass, deploymentInfo, ctx);
-
- bean = objectRecipe.create(beanClass.getClassLoader());
- Map unsetProperties = objectRecipe.getUnsetProperties();
- if (unsetProperties.size() > 0) {
- for (Object property : unsetProperties.keySet()) {
- logger.warning("Injection: No such property '" + property + "' in class " + beanClass.getName());
- }
- }
-
- HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
- for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
- if (interceptorData.getInterceptorClass().equals(beanClass)) continue;
-
- Class clazz = interceptorData.getInterceptorClass();
- ObjectRecipe interceptorRecipe = new ObjectRecipe(clazz);
- interceptorRecipe.allow(Option.FIELD_INJECTION);
- interceptorRecipe.allow(Option.PRIVATE_PROPERTIES);
- interceptorRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
-
- fillInjectionProperties(interceptorRecipe, clazz, deploymentInfo, ctx);
-
- try {
- Object interceptorInstance = interceptorRecipe.create(clazz.getClassLoader());
- interceptorInstances.put(clazz.getName(), interceptorInstance);
- } catch (ConstructionException e) {
- throw new Exception("Failed to create interceptor: " + clazz.getName(), e);
- }
- }
-
- interceptorInstances.put(beanClass.getName(), bean);
-
-
- try {
- callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
- callContext.setCurrentAllowedStates(StatelessContext.getStates());
-
- List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
- InterceptorStack interceptorStack = new InterceptorStack(bean, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
- interceptorStack.invoke();
- } catch (Exception e) {
- throw e;
- }
-
- try {
- if (bean instanceof SessionBean){
- callContext.setCurrentOperation(Operation.CREATE);
- callContext.setCurrentAllowedStates(StatelessContext.getStates());
- Method create = deploymentInfo.getCreateMethod();
- InterceptorStack interceptorStack = new InterceptorStack(bean, create, Operation.CREATE, new ArrayList<InterceptorData>(), new HashMap());
- interceptorStack.invoke();
- }
- } catch (Exception e) {
- throw e;
- }
-
- bean = new Instance(bean, interceptorInstances);
- } 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;
- logger.error(t, e);
- throw new org.apache.openejb.ApplicationException(new RemoteException("Cannot obtain a free instance.", e));
- } finally {
- callContext.setCurrentOperation(originalOperation);
- callContext.setCurrentAllowedStates(originalAllowedStates);
- }
- }
- return bean;
- }
-
- private static void fillInjectionProperties(ObjectRecipe objectRecipe, Class clazz, CoreDeploymentInfo deploymentInfo, Context context) {
- for (Injection injection : deploymentInfo.getInjections()) {
- if (!injection.getTarget().isAssignableFrom(clazz)) continue;
- try {
- String jndiName = injection.getJndiName();
- Object object = context.lookup("java:comp/env/" + jndiName);
- if (object instanceof String) {
- String string = (String) object;
- // Pass it in raw so it could be potentially converted to
- // another data type by an xbean-reflect property editor
- objectRecipe.setProperty(injection.getTarget().getName() + "/" + injection.getName(), string);
- } else {
- objectRecipe.setProperty(injection.getTarget().getName() + "/" + injection.getName(), new StaticRecipe(object));
- }
- } catch (NamingException e) {
- logger.warning("Injection data not found in enc: jndiName='" + injection.getJndiName() + "', target=" + injection.getTarget() + "/" + injection.getName());
- }
- }
- }
-
- private boolean hasSetSessionContext(Class beanClass) {
- try {
- beanClass.getMethod("setSessionContext", SessionContext.class);
- return true;
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
- private SessionContext createSessionContext() {
- return new StatelessContext(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) {
- synchronized (pool) {
- if (pool.size() < poolLimit) {
- pool.push(bean);
- poolQueue.notifyWaitingThreads();
- } else {
- freeInstance(callContext, (Instance) bean);
- }
- }
- } else {
- if (pool.size() >= poolLimit) {
- freeInstance(callContext, (Instance)bean);
- } else {
- pool.push(bean);
- }
- }
- }
-
- private void freeInstance(ThreadContext callContext, Instance instance) {
- try {
- callContext.setCurrentOperation(Operation.PRE_DESTROY);
- callContext.setCurrentAllowedStates(StatelessContext.getStates());
- CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
-
- Method remove = instance.bean instanceof SessionBean? deploymentInfo.getCreateMethod(): null;
-
- List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
- InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors);
-
- interceptorStack.invoke();
- } catch (Throwable re) {
- logger.error("The bean instance " + instance + " threw a system exception:" + re, re);
- }
-
- }
-
- /**
- * This method has no work to do as all instances are removed from
- * the pool on getInstance(...) and not returned via poolInstance(...)
- * if they threw a system exception.
- *
- * @param callContext
- * @param bean
- */
- public void discardInstance(ThreadContext callContext, Object bean) {
-
- }
-
- public void deploy(CoreDeploymentInfo deploymentInfo) {
- Data data = new Data(poolLimit);
- deploymentInfo.setContainerData(data);
- }
-
- public void undeploy(CoreDeploymentInfo deploymentInfo) {
- Data data = (Data) deploymentInfo.getContainerData();
- if (data == null) return;
- Stack pool = data.getPool();
- //TODO ejbRemove on each bean in pool.
- //clean pool
- deploymentInfo.setContainerData(null);
- }
-
- static class PoolQueue {
- private final long waitPeriod;
-
- public PoolQueue(long time) {
- waitPeriod = time;
- }
-
- public synchronized void waitForAvailableInstance()
- throws org.apache.openejb.InvalidateReferenceException {
- try {
- wait(waitPeriod);
- } catch (InterruptedException ie) {
- throw new org.apache.openejb.InvalidateReferenceException(new RemoteException("No instance available to service request", ie));
- }
- }
-
- public synchronized void notifyWaitingThreads() {
- notify();
- }
- }
-
- private static final class Data {
- private final Stack pool;
-
- public Data(int poolLimit) {
- pool = new LinkedListStack(poolLimit);
- }
-
- public Stack getPool() {
- return pool;
- }
- }
-
-}
+/**
+ * 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.stateless;
+
+import java.lang.reflect.Method;
+import java.rmi.RemoteException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.SessionBean;
+import javax.ejb.SessionContext;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.transaction.TransactionManager;
+import javax.xml.ws.WebServiceContext;
+
+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;
+import org.apache.openejb.core.ThreadContext;
+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;
+import org.apache.xbean.recipe.StaticRecipe;
+
+public class StatelessInstanceManager {
+ 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 PoolQueue poolQueue = null;
+
+ protected final SafeToolkit toolkit = SafeToolkit.getToolkit("StatefulInstanceManager");
+ private TransactionManager transactionManager;
+ private SecurityService securityService;
+
+ public StatelessInstanceManager(TransactionManager transactionManager, SecurityService securityService, int timeout, int poolSize, boolean strictPooling) {
+ this.transactionManager = transactionManager;
+ this.securityService = securityService;
+ this.poolLimit = poolSize;
+ this.strictPooling = strictPooling;
+
+ if (strictPooling && poolSize < 1) {
+ throw new IllegalArgumentException("Cannot use strict pooling with a pool size less than one. Strict pooling blocks threads till an instance in the pool is available. Please increase the pool size or set strict pooling to false");
+ }
+
+ if (this.strictPooling) {
+ poolQueue = new PoolQueue(timeout);
+ }
+ }
+
+ /**
+ * Removes an instance from the pool and returns it for use
+ * by the container in business methods.
+ *
+ * If the pool is at it's limit the StrictPooling flag will
+ * cause this thread to wait.
+ *
+ * If StrictPooling is not enabled this method will create a
+ * new stateless bean instance performing all required injection
+ * and callbacks before returning it in a method ready state.
+ *
+ * @param callContext
+ * @return
+ * @throws OpenEJBException
+ */
+ public Object getInstance(ThreadContext callContext)
+ throws OpenEJBException {
+ CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
+ Data data = (Data) deploymentInfo.getContainerData();
+ Stack pool = data.getPool();
+ Object bean = pool.pop();
+
+ while (strictPooling && bean == null && pool.size() >= poolLimit) {
+ poolQueue.waitForAvailableInstance();
+ bean = pool.pop();
+ }
+
+ if (bean == null) {
+
+ Class beanClass = deploymentInfo.getBeanClass();
+ ObjectRecipe objectRecipe = new ObjectRecipe(beanClass);
+ objectRecipe.allow(Option.FIELD_INJECTION);
+ objectRecipe.allow(Option.PRIVATE_PROPERTIES);
+ objectRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
+
+ Operation originalOperation = callContext.getCurrentOperation();
+ BaseContext.State[] originalAllowedStates = callContext.getCurrentAllowedStates();
+
+ try {
+ Context ctx = deploymentInfo.getJndiEnc();
+ SessionContext sessionContext;
+ // This needs to be synchronized as this code is multi-threaded.
+ // In between the lookup and the bind a bind may take place in another Thread.
+ // This is a fix for GERONIMO-3444
+ synchronized(this){
+ try {
+ sessionContext = (SessionContext) ctx.lookup("java:comp/EJBContext");
+ } catch (NamingException e1) {
+ sessionContext = createSessionContext();
+ // TODO: This should work
+ ctx.bind("java:comp/EJBContext", sessionContext);
+ }
+ }
+ if (javax.ejb.SessionBean.class.isAssignableFrom(beanClass) || hasSetSessionContext(beanClass)) {
+ callContext.setCurrentOperation(Operation.INJECTION);
+ callContext.setCurrentAllowedStates(StatelessContext.getStates());
+ objectRecipe.setProperty("sessionContext", new StaticRecipe(sessionContext));
+ }
+
+ WebServiceContext wsContext;
+ // This is a fix for GERONIMO-3444
+ synchronized(this){
+ try {
+ wsContext = (WebServiceContext) ctx.lookup("java:comp/WebServiceContext");
+ } catch (NamingException e) {
+ wsContext = new EjbWsContext(sessionContext);
+ ctx.bind("java:comp/WebServiceContext", wsContext);
+ }
+ }
+
+ fillInjectionProperties(objectRecipe, beanClass, deploymentInfo, ctx);
+
+ bean = objectRecipe.create(beanClass.getClassLoader());
+ Map unsetProperties = objectRecipe.getUnsetProperties();
+ if (unsetProperties.size() > 0) {
+ for (Object property : unsetProperties.keySet()) {
+ logger.warning("Injection: No such property '" + property + "' in class " + beanClass.getName());
+ }
+ }
+
+ HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
+ for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
+ if (interceptorData.getInterceptorClass().equals(beanClass)) continue;
+
+ Class clazz = interceptorData.getInterceptorClass();
+ ObjectRecipe interceptorRecipe = new ObjectRecipe(clazz);
+ interceptorRecipe.allow(Option.FIELD_INJECTION);
+ interceptorRecipe.allow(Option.PRIVATE_PROPERTIES);
+ interceptorRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
+
+ fillInjectionProperties(interceptorRecipe, clazz, deploymentInfo, ctx);
+
+ try {
+ Object interceptorInstance = interceptorRecipe.create(clazz.getClassLoader());
+ interceptorInstances.put(clazz.getName(), interceptorInstance);
+ } catch (ConstructionException e) {
+ throw new Exception("Failed to create interceptor: " + clazz.getName(), e);
+ }
+ }
+
+ interceptorInstances.put(beanClass.getName(), bean);
+
+
+ try {
+ callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
+ callContext.setCurrentAllowedStates(StatelessContext.getStates());
+
+ List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+ InterceptorStack interceptorStack = new InterceptorStack(bean, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
+ interceptorStack.invoke();
+ } catch (Exception e) {
+ throw e;
+ }
+
+ try {
+ if (bean instanceof SessionBean){
+ callContext.setCurrentOperation(Operation.CREATE);
+ callContext.setCurrentAllowedStates(StatelessContext.getStates());
+ Method create = deploymentInfo.getCreateMethod();
+ InterceptorStack interceptorStack = new InterceptorStack(bean, create, Operation.CREATE, new ArrayList<InterceptorData>(), new HashMap());
+ interceptorStack.invoke();
+ }
+ } catch (Exception e) {
+ throw e;
+ }
+
+ bean = new Instance(bean, interceptorInstances);
+ } 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;
+ logger.error(t, e);
+ throw new org.apache.openejb.ApplicationException(new RemoteException("Cannot obtain a free instance.", e));
+ } finally {
+ callContext.setCurrentOperation(originalOperation);
+ callContext.setCurrentAllowedStates(originalAllowedStates);
+ }
+ }
+ return bean;
+ }
+
+ private static void fillInjectionProperties(ObjectRecipe objectRecipe, Class clazz, CoreDeploymentInfo deploymentInfo, Context context) {
+ for (Injection injection : deploymentInfo.getInjections()) {
+ if (!injection.getTarget().isAssignableFrom(clazz)) continue;
+ try {
+ String jndiName = injection.getJndiName();
+ Object object = context.lookup("java:comp/env/" + jndiName);
+ if (object instanceof String) {
+ String string = (String) object;
+ // Pass it in raw so it could be potentially converted to
+ // another data type by an xbean-reflect property editor
+ objectRecipe.setProperty(injection.getTarget().getName() + "/" + injection.getName(), string);
+ } else {
+ objectRecipe.setProperty(injection.getTarget().getName() + "/" + injection.getName(), new StaticRecipe(object));
+ }
+ } catch (NamingException e) {
+ logger.warning("Injection data not found in enc: jndiName='" + injection.getJndiName() + "', target=" + injection.getTarget() + "/" + injection.getName());
+ }
+ }
+ }
+
+ private boolean hasSetSessionContext(Class beanClass) {
+ try {
+ beanClass.getMethod("setSessionContext", SessionContext.class);
+ return true;
+ } catch (NoSuchMethodException e) {
+ return false;
+ }
+ }
+
+ private SessionContext createSessionContext() {
+ return new StatelessContext(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);
+ poolQueue.notifyWaitingThreads();
+ } else {
+ if (pool.size() >= poolLimit) {
+ freeInstance(callContext, (Instance)bean);
+ } else {
+ pool.push(bean);
+ }
+ }
+ }
+
+ private void freeInstance(ThreadContext callContext, Instance instance) {
+ try {
+ callContext.setCurrentOperation(Operation.PRE_DESTROY);
+ callContext.setCurrentAllowedStates(StatelessContext.getStates());
+ CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
+
+ Method remove = instance.bean instanceof SessionBean? deploymentInfo.getCreateMethod(): null;
+
+ List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
+ InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors);
+
+ interceptorStack.invoke();
+ } catch (Throwable re) {
+ logger.error("The bean instance " + instance + " threw a system exception:" + re, re);
+ }
+
+ }
+
+ /**
+ * This method has no work to do as all instances are removed from
+ * the pool on getInstance(...) and not returned via poolInstance(...)
+ * if they threw a system exception.
+ *
+ * @param callContext
+ * @param bean
+ */
+ public void discardInstance(ThreadContext callContext, Object bean) {
+
+ }
+
+ public void deploy(CoreDeploymentInfo deploymentInfo) {
+ Data data = new Data(poolLimit);
+ deploymentInfo.setContainerData(data);
+ }
+
+ public void undeploy(CoreDeploymentInfo deploymentInfo) {
+ Data data = (Data) deploymentInfo.getContainerData();
+ if (data == null) return;
+ Stack pool = data.getPool();
+ //TODO ejbRemove on each bean in pool.
+ //clean pool
+ deploymentInfo.setContainerData(null);
+ }
+
+ static class PoolQueue {
+ private final long waitPeriod;
+
+ public PoolQueue(long time) {
+ waitPeriod = time;
+ }
+
+ public synchronized void waitForAvailableInstance()
+ throws org.apache.openejb.InvalidateReferenceException {
+ try {
+ wait(waitPeriod);
+ } catch (InterruptedException ie) {
+ throw new org.apache.openejb.InvalidateReferenceException(new RemoteException("No instance available to service request", ie));
+ }
+ }
+
+ public synchronized void notifyWaitingThreads() {
+ notify();
+ }
+ }
+
+ private static final class Data {
+ private final Stack pool;
+
+ public Data(int poolLimit) {
+ pool = new LinkedListStack(poolLimit);
+ }
+
+ public Stack getPool() {
+ return pool;
+ }
+ }
+
+}
Re: svn commit: r643904 - /openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
Posted by Manu George <ma...@gmail.com>.
Well it seems the mistake I did was use wordpad from windows to edit
the file :(.
Regards
Manu
On Wed, Apr 2, 2008 at 7:02 PM, <ma...@apache.org> wrote:
> Author: manugeorge
> Date: Wed Apr 2 06:32:25 2008
> New Revision: 643904
>
> URL: http://svn.apache.org/viewvc?rev=643904&view=rev
> Log:
> reverting back to older revision = 643871
>
> Modified:
> openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
>
> Modified: openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java
> URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java?rev=643904&r1=643903&r2=643904&view=diff
> ==============================================================================
> --- openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java (original)
> +++ openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessInstanceManager.java Wed Apr 2 06:32:25 2008
> @@ -1,376 +1,368 @@
> -/**
> - * 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.stateless;
> -
> -import java.lang.reflect.Method;
> -import java.rmi.RemoteException;
> -import java.util.ArrayList;
> -import java.util.HashMap;
> -import java.util.List;
> -import java.util.Map;
> -
> -import javax.ejb.SessionBean;
> -import javax.ejb.SessionContext;
> -import javax.naming.Context;
> -import javax.naming.NamingException;
> -import javax.transaction.TransactionManager;
> -import javax.xml.ws.WebServiceContext;
> -
> -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;
> -import org.apache.openejb.core.ThreadContext;
> -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;
> -import org.apache.xbean.recipe.StaticRecipe;
> -
> -public class StatelessInstanceManager {
> - 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 PoolQueue poolQueue = null;
> -
> - protected final SafeToolkit toolkit = SafeToolkit.getToolkit("StatefulInstanceManager");
> - private TransactionManager transactionManager;
> - private SecurityService securityService;
> -
> - public StatelessInstanceManager(TransactionManager transactionManager, SecurityService securityService, int timeout, int poolSize, boolean strictPooling) {
> - this.transactionManager = transactionManager;
> - this.securityService = securityService;
> - this.poolLimit = poolSize;
> - this.strictPooling = strictPooling;
> -
> - if (strictPooling && poolSize < 1) {
> - throw new IllegalArgumentException("Cannot use strict pooling with a pool size less than one. Strict pooling blocks threads till an instance in the pool is available. Please increase the pool size or set strict pooling to false");
> - }
> -
> - if (this.strictPooling) {
> - poolQueue = new PoolQueue(timeout);
> - }
> - }
> -
> - /**
> - * Removes an instance from the pool and returns it for use
> - * by the container in business methods.
> - *
> - * If the pool is at it's limit the StrictPooling flag will
> - * cause this thread to wait.
> - *
> - * If StrictPooling is not enabled this method will create a
> - * new stateless bean instance performing all required injection
> - * and callbacks before returning it in a method ready state.
> - *
> - * @param callContext
> - * @return
> - * @throws OpenEJBException
> - */
> - public Object getInstance(ThreadContext callContext)
> - throws OpenEJBException {
> - CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
> - Data data = (Data) deploymentInfo.getContainerData();
> - Stack pool = data.getPool();
> - Object bean = pool.pop();
> - if(strictPooling){
> - synchronized(pool){
> - while (bean == null && pool.size() >= poolLimit) {
> - poolQueue.waitForAvailableInstance();
> - bean = pool.pop();
> - }
> - }
> - }
> - if (bean == null) {
> -
> - Class beanClass = deploymentInfo.getBeanClass();
> - ObjectRecipe objectRecipe = new ObjectRecipe(beanClass);
> - objectRecipe.allow(Option.FIELD_INJECTION);
> - objectRecipe.allow(Option.PRIVATE_PROPERTIES);
> - objectRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
> -
> - Operation originalOperation = callContext.getCurrentOperation();
> - BaseContext.State[] originalAllowedStates = callContext.getCurrentAllowedStates();
> -
> - try {
> - Context ctx = deploymentInfo.getJndiEnc();
> - SessionContext sessionContext;
> - // This needs to be synchronized as this code is multi-threaded.
> - // In between the lookup and the bind a bind may take place in another Thread.
> - // This is a fix for GERONIMO-3444
> - synchronized(this){
> - try {
> - sessionContext = (SessionContext) ctx.lookup("java:comp/EJBContext");
> - } catch (NamingException e1) {
> - sessionContext = createSessionContext();
> - // TODO: This should work
> - ctx.bind("java:comp/EJBContext", sessionContext);
> - }
> - }
> - if (javax.ejb.SessionBean.class.isAssignableFrom(beanClass) || hasSetSessionContext(beanClass)) {
> - callContext.setCurrentOperation(Operation.INJECTION);
> - callContext.setCurrentAllowedStates(StatelessContext.getStates());
> - objectRecipe.setProperty("sessionContext", new StaticRecipe(sessionContext));
> - }
> -
> - WebServiceContext wsContext;
> - // This is a fix for GERONIMO-3444
> - synchronized(this){
> - try {
> - wsContext = (WebServiceContext) ctx.lookup("java:comp/WebServiceContext");
> - } catch (NamingException e) {
> - wsContext = new EjbWsContext(sessionContext);
> - ctx.bind("java:comp/WebServiceContext", wsContext);
> - }
> - }
> -
> - fillInjectionProperties(objectRecipe, beanClass, deploymentInfo, ctx);
> -
> - bean = objectRecipe.create(beanClass.getClassLoader());
> - Map unsetProperties = objectRecipe.getUnsetProperties();
> - if (unsetProperties.size() > 0) {
> - for (Object property : unsetProperties.keySet()) {
> - logger.warning("Injection: No such property '" + property + "' in class " + beanClass.getName());
> - }
> - }
> -
> - HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
> - for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
> - if (interceptorData.getInterceptorClass().equals(beanClass)) continue;
> -
> - Class clazz = interceptorData.getInterceptorClass();
> - ObjectRecipe interceptorRecipe = new ObjectRecipe(clazz);
> - interceptorRecipe.allow(Option.FIELD_INJECTION);
> - interceptorRecipe.allow(Option.PRIVATE_PROPERTIES);
> - interceptorRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
> -
> - fillInjectionProperties(interceptorRecipe, clazz, deploymentInfo, ctx);
> -
> - try {
> - Object interceptorInstance = interceptorRecipe.create(clazz.getClassLoader());
> - interceptorInstances.put(clazz.getName(), interceptorInstance);
> - } catch (ConstructionException e) {
> - throw new Exception("Failed to create interceptor: " + clazz.getName(), e);
> - }
> - }
> -
> - interceptorInstances.put(beanClass.getName(), bean);
> -
> -
> - try {
> - callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
> - callContext.setCurrentAllowedStates(StatelessContext.getStates());
> -
> - List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
> - InterceptorStack interceptorStack = new InterceptorStack(bean, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
> - interceptorStack.invoke();
> - } catch (Exception e) {
> - throw e;
> - }
> -
> - try {
> - if (bean instanceof SessionBean){
> - callContext.setCurrentOperation(Operation.CREATE);
> - callContext.setCurrentAllowedStates(StatelessContext.getStates());
> - Method create = deploymentInfo.getCreateMethod();
> - InterceptorStack interceptorStack = new InterceptorStack(bean, create, Operation.CREATE, new ArrayList<InterceptorData>(), new HashMap());
> - interceptorStack.invoke();
> - }
> - } catch (Exception e) {
> - throw e;
> - }
> -
> - bean = new Instance(bean, interceptorInstances);
> - } 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;
> - logger.error(t, e);
> - throw new org.apache.openejb.ApplicationException(new RemoteException("Cannot obtain a free instance.", e));
> - } finally {
> - callContext.setCurrentOperation(originalOperation);
> - callContext.setCurrentAllowedStates(originalAllowedStates);
> - }
> - }
> - return bean;
> - }
> -
> - private static void fillInjectionProperties(ObjectRecipe objectRecipe, Class clazz, CoreDeploymentInfo deploymentInfo, Context context) {
> - for (Injection injection : deploymentInfo.getInjections()) {
> - if (!injection.getTarget().isAssignableFrom(clazz)) continue;
> - try {
> - String jndiName = injection.getJndiName();
> - Object object = context.lookup("java:comp/env/" + jndiName);
> - if (object instanceof String) {
> - String string = (String) object;
> - // Pass it in raw so it could be potentially converted to
> - // another data type by an xbean-reflect property editor
> - objectRecipe.setProperty(injection.getTarget().getName() + "/" + injection.getName(), string);
> - } else {
> - objectRecipe.setProperty(injection.getTarget().getName() + "/" + injection.getName(), new StaticRecipe(object));
> - }
> - } catch (NamingException e) {
> - logger.warning("Injection data not found in enc: jndiName='" + injection.getJndiName() + "', target=" + injection.getTarget() + "/" + injection.getName());
> - }
> - }
> - }
> -
> - private boolean hasSetSessionContext(Class beanClass) {
> - try {
> - beanClass.getMethod("setSessionContext", SessionContext.class);
> - return true;
> - } catch (NoSuchMethodException e) {
> - return false;
> - }
> - }
> -
> - private SessionContext createSessionContext() {
> - return new StatelessContext(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) {
> - synchronized (pool) {
> - if (pool.size() < poolLimit) {
> - pool.push(bean);
> - poolQueue.notifyWaitingThreads();
> - } else {
> - freeInstance(callContext, (Instance) bean);
> - }
> - }
> - } else {
> - if (pool.size() >= poolLimit) {
> - freeInstance(callContext, (Instance)bean);
> - } else {
> - pool.push(bean);
> - }
> - }
> - }
> -
> - private void freeInstance(ThreadContext callContext, Instance instance) {
> - try {
> - callContext.setCurrentOperation(Operation.PRE_DESTROY);
> - callContext.setCurrentAllowedStates(StatelessContext.getStates());
> - CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
> -
> - Method remove = instance.bean instanceof SessionBean? deploymentInfo.getCreateMethod(): null;
> -
> - List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
> - InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors);
> -
> - interceptorStack.invoke();
> - } catch (Throwable re) {
> - logger.error("The bean instance " + instance + " threw a system exception:" + re, re);
> - }
> -
> - }
> -
> - /**
> - * This method has no work to do as all instances are removed from
> - * the pool on getInstance(...) and not returned via poolInstance(...)
> - * if they threw a system exception.
> - *
> - * @param callContext
> - * @param bean
> - */
> - public void discardInstance(ThreadContext callContext, Object bean) {
> -
> - }
> -
> - public void deploy(CoreDeploymentInfo deploymentInfo) {
> - Data data = new Data(poolLimit);
> - deploymentInfo.setContainerData(data);
> - }
> -
> - public void undeploy(CoreDeploymentInfo deploymentInfo) {
> - Data data = (Data) deploymentInfo.getContainerData();
> - if (data == null) return;
> - Stack pool = data.getPool();
> - //TODO ejbRemove on each bean in pool.
> - //clean pool
> - deploymentInfo.setContainerData(null);
> - }
> -
> - static class PoolQueue {
> - private final long waitPeriod;
> -
> - public PoolQueue(long time) {
> - waitPeriod = time;
> - }
> -
> - public synchronized void waitForAvailableInstance()
> - throws org.apache.openejb.InvalidateReferenceException {
> - try {
> - wait(waitPeriod);
> - } catch (InterruptedException ie) {
> - throw new org.apache.openejb.InvalidateReferenceException(new RemoteException("No instance available to service request", ie));
> - }
> - }
> -
> - public synchronized void notifyWaitingThreads() {
> - notify();
> - }
> - }
> -
> - private static final class Data {
> - private final Stack pool;
> -
> - public Data(int poolLimit) {
> - pool = new LinkedListStack(poolLimit);
> - }
> -
> - public Stack getPool() {
> - return pool;
> - }
> - }
> -
> -}
> +/**
> + * 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.stateless;
> +
> +import java.lang.reflect.Method;
> +import java.rmi.RemoteException;
> +import java.util.ArrayList;
> +import java.util.HashMap;
> +import java.util.List;
> +import java.util.Map;
> +
> +import javax.ejb.SessionBean;
> +import javax.ejb.SessionContext;
> +import javax.naming.Context;
> +import javax.naming.NamingException;
> +import javax.transaction.TransactionManager;
> +import javax.xml.ws.WebServiceContext;
> +
> +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;
> +import org.apache.openejb.core.ThreadContext;
> +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;
> +import org.apache.xbean.recipe.StaticRecipe;
> +
> +public class StatelessInstanceManager {
> + 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 PoolQueue poolQueue = null;
> +
> + protected final SafeToolkit toolkit = SafeToolkit.getToolkit("StatefulInstanceManager");
> + private TransactionManager transactionManager;
> + private SecurityService securityService;
> +
> + public StatelessInstanceManager(TransactionManager transactionManager, SecurityService securityService, int timeout, int poolSize, boolean strictPooling) {
> + this.transactionManager = transactionManager;
> + this.securityService = securityService;
> + this.poolLimit = poolSize;
> + this.strictPooling = strictPooling;
> +
> + if (strictPooling && poolSize < 1) {
> + throw new IllegalArgumentException("Cannot use strict pooling with a pool size less than one. Strict pooling blocks threads till an instance in the pool is available. Please increase the pool size or set strict pooling to false");
> + }
> +
> + if (this.strictPooling) {
> + poolQueue = new PoolQueue(timeout);
> + }
> + }
> +
> + /**
> + * Removes an instance from the pool and returns it for use
> + * by the container in business methods.
> + *
> + * If the pool is at it's limit the StrictPooling flag will
> + * cause this thread to wait.
> + *
> + * If StrictPooling is not enabled this method will create a
> + * new stateless bean instance performing all required injection
> + * and callbacks before returning it in a method ready state.
> + *
> + * @param callContext
> + * @return
> + * @throws OpenEJBException
> + */
> + public Object getInstance(ThreadContext callContext)
> + throws OpenEJBException {
> + CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
> + Data data = (Data) deploymentInfo.getContainerData();
> + Stack pool = data.getPool();
> + Object bean = pool.pop();
> +
> + while (strictPooling && bean == null && pool.size() >= poolLimit) {
> + poolQueue.waitForAvailableInstance();
> + bean = pool.pop();
> + }
> +
> + if (bean == null) {
> +
> + Class beanClass = deploymentInfo.getBeanClass();
> + ObjectRecipe objectRecipe = new ObjectRecipe(beanClass);
> + objectRecipe.allow(Option.FIELD_INJECTION);
> + objectRecipe.allow(Option.PRIVATE_PROPERTIES);
> + objectRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
> +
> + Operation originalOperation = callContext.getCurrentOperation();
> + BaseContext.State[] originalAllowedStates = callContext.getCurrentAllowedStates();
> +
> + try {
> + Context ctx = deploymentInfo.getJndiEnc();
> + SessionContext sessionContext;
> + // This needs to be synchronized as this code is multi-threaded.
> + // In between the lookup and the bind a bind may take place in another Thread.
> + // This is a fix for GERONIMO-3444
> + synchronized(this){
> + try {
> + sessionContext = (SessionContext) ctx.lookup("java:comp/EJBContext");
> + } catch (NamingException e1) {
> + sessionContext = createSessionContext();
> + // TODO: This should work
> + ctx.bind("java:comp/EJBContext", sessionContext);
> + }
> + }
> + if (javax.ejb.SessionBean.class.isAssignableFrom(beanClass) || hasSetSessionContext(beanClass)) {
> + callContext.setCurrentOperation(Operation.INJECTION);
> + callContext.setCurrentAllowedStates(StatelessContext.getStates());
> + objectRecipe.setProperty("sessionContext", new StaticRecipe(sessionContext));
> + }
> +
> + WebServiceContext wsContext;
> + // This is a fix for GERONIMO-3444
> + synchronized(this){
> + try {
> + wsContext = (WebServiceContext) ctx.lookup("java:comp/WebServiceContext");
> + } catch (NamingException e) {
> + wsContext = new EjbWsContext(sessionContext);
> + ctx.bind("java:comp/WebServiceContext", wsContext);
> + }
> + }
> +
> + fillInjectionProperties(objectRecipe, beanClass, deploymentInfo, ctx);
> +
> + bean = objectRecipe.create(beanClass.getClassLoader());
> + Map unsetProperties = objectRecipe.getUnsetProperties();
> + if (unsetProperties.size() > 0) {
> + for (Object property : unsetProperties.keySet()) {
> + logger.warning("Injection: No such property '" + property + "' in class " + beanClass.getName());
> + }
> + }
> +
> + HashMap<String, Object> interceptorInstances = new HashMap<String, Object>();
> + for (InterceptorData interceptorData : deploymentInfo.getAllInterceptors()) {
> + if (interceptorData.getInterceptorClass().equals(beanClass)) continue;
> +
> + Class clazz = interceptorData.getInterceptorClass();
> + ObjectRecipe interceptorRecipe = new ObjectRecipe(clazz);
> + interceptorRecipe.allow(Option.FIELD_INJECTION);
> + interceptorRecipe.allow(Option.PRIVATE_PROPERTIES);
> + interceptorRecipe.allow(Option.IGNORE_MISSING_PROPERTIES);
> +
> + fillInjectionProperties(interceptorRecipe, clazz, deploymentInfo, ctx);
> +
> + try {
> + Object interceptorInstance = interceptorRecipe.create(clazz.getClassLoader());
> + interceptorInstances.put(clazz.getName(), interceptorInstance);
> + } catch (ConstructionException e) {
> + throw new Exception("Failed to create interceptor: " + clazz.getName(), e);
> + }
> + }
> +
> + interceptorInstances.put(beanClass.getName(), bean);
> +
> +
> + try {
> + callContext.setCurrentOperation(Operation.POST_CONSTRUCT);
> + callContext.setCurrentAllowedStates(StatelessContext.getStates());
> +
> + List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
> + InterceptorStack interceptorStack = new InterceptorStack(bean, null, Operation.POST_CONSTRUCT, callbackInterceptors, interceptorInstances);
> + interceptorStack.invoke();
> + } catch (Exception e) {
> + throw e;
> + }
> +
> + try {
> + if (bean instanceof SessionBean){
> + callContext.setCurrentOperation(Operation.CREATE);
> + callContext.setCurrentAllowedStates(StatelessContext.getStates());
> + Method create = deploymentInfo.getCreateMethod();
> + InterceptorStack interceptorStack = new InterceptorStack(bean, create, Operation.CREATE, new ArrayList<InterceptorData>(), new HashMap());
> + interceptorStack.invoke();
> + }
> + } catch (Exception e) {
> + throw e;
> + }
> +
> + bean = new Instance(bean, interceptorInstances);
> + } 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;
> + logger.error(t, e);
> + throw new org.apache.openejb.ApplicationException(new RemoteException("Cannot obtain a free instance.", e));
> + } finally {
> + callContext.setCurrentOperation(originalOperation);
> + callContext.setCurrentAllowedStates(originalAllowedStates);
> + }
> + }
> + return bean;
> + }
> +
> + private static void fillInjectionProperties(ObjectRecipe objectRecipe, Class clazz, CoreDeploymentInfo deploymentInfo, Context context) {
> + for (Injection injection : deploymentInfo.getInjections()) {
> + if (!injection.getTarget().isAssignableFrom(clazz)) continue;
> + try {
> + String jndiName = injection.getJndiName();
> + Object object = context.lookup("java:comp/env/" + jndiName);
> + if (object instanceof String) {
> + String string = (String) object;
> + // Pass it in raw so it could be potentially converted to
> + // another data type by an xbean-reflect property editor
> + objectRecipe.setProperty(injection.getTarget().getName() + "/" + injection.getName(), string);
> + } else {
> + objectRecipe.setProperty(injection.getTarget().getName() + "/" + injection.getName(), new StaticRecipe(object));
> + }
> + } catch (NamingException e) {
> + logger.warning("Injection data not found in enc: jndiName='" + injection.getJndiName() + "', target=" + injection.getTarget() + "/" + injection.getName());
> + }
> + }
> + }
> +
> + private boolean hasSetSessionContext(Class beanClass) {
> + try {
> + beanClass.getMethod("setSessionContext", SessionContext.class);
> + return true;
> + } catch (NoSuchMethodException e) {
> + return false;
> + }
> + }
> +
> + private SessionContext createSessionContext() {
> + return new StatelessContext(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);
> + poolQueue.notifyWaitingThreads();
> + } else {
> + if (pool.size() >= poolLimit) {
> + freeInstance(callContext, (Instance)bean);
> + } else {
> + pool.push(bean);
> + }
> + }
> + }
> +
> + private void freeInstance(ThreadContext callContext, Instance instance) {
> + try {
> + callContext.setCurrentOperation(Operation.PRE_DESTROY);
> + callContext.setCurrentAllowedStates(StatelessContext.getStates());
> + CoreDeploymentInfo deploymentInfo = callContext.getDeploymentInfo();
> +
> + Method remove = instance.bean instanceof SessionBean? deploymentInfo.getCreateMethod(): null;
> +
> + List<InterceptorData> callbackInterceptors = deploymentInfo.getCallbackInterceptors();
> + InterceptorStack interceptorStack = new InterceptorStack(instance.bean, remove, Operation.PRE_DESTROY, callbackInterceptors, instance.interceptors);
> +
> + interceptorStack.invoke();
> + } catch (Throwable re) {
> + logger.error("The bean instance " + instance + " threw a system exception:" + re, re);
> + }
> +
> + }
> +
> + /**
> + * This method has no work to do as all instances are removed from
> + * the pool on getInstance(...) and not returned via poolInstance(...)
> + * if they threw a system exception.
> + *
> + * @param callContext
> + * @param bean
> + */
> + public void discardInstance(ThreadContext callContext, Object bean) {
> +
> + }
> +
> + public void deploy(CoreDeploymentInfo deploymentInfo) {
> + Data data = new Data(poolLimit);
> + deploymentInfo.setContainerData(data);
> + }
> +
> + public void undeploy(CoreDeploymentInfo deploymentInfo) {
> + Data data = (Data) deploymentInfo.getContainerData();
> + if (data == null) return;
> + Stack pool = data.getPool();
> + //TODO ejbRemove on each bean in pool.
> + //clean pool
> + deploymentInfo.setContainerData(null);
> + }
> +
> + static class PoolQueue {
> + private final long waitPeriod;
> +
> + public PoolQueue(long time) {
> + waitPeriod = time;
> + }
> +
> + public synchronized void waitForAvailableInstance()
> + throws org.apache.openejb.InvalidateReferenceException {
> + try {
> + wait(waitPeriod);
> + } catch (InterruptedException ie) {
> + throw new org.apache.openejb.InvalidateReferenceException(new RemoteException("No instance available to service request", ie));
> + }
> + }
> +
> + public synchronized void notifyWaitingThreads() {
> + notify();
> + }
> + }
> +
> + private static final class Data {
> + private final Stack pool;
> +
> + public Data(int poolLimit) {
> + pool = new LinkedListStack(poolLimit);
> + }
> +
> + public Stack getPool() {
> + return pool;
> + }
> + }
> +
> +}
>
>
>