Author: rmannibucau Date: Sat May 17 13:12:11 2014 New Revision: 1595470 URL: http://svn.apache.org/r1595470 Log: TOMEE-1212 reading thread and queue size from context and creating a local executorservice if needed + flushing tasks before quitting
Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandle.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeProxyHandle.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandle.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectProxyHandle.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBHomeHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBObjectHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBHomeHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBObjectHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBHomeHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBObjectHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBHomeHandler.java tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBObjectHandler.java Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandle.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandle.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandle.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandle.java Sat May 17 13:12:11 2014 @@ -21,6 +21,9 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.rmi.RemoteException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; public class EJBHomeHandle implements java.io.Externalizable, javax.ejb.HomeHandle { @@ -54,7 +57,15 @@ public class EJBHomeHandle implements ja @Override public void writeExternal(final ObjectOutput out) throws IOException { // write out the version of the serialized data for future use - out.writeByte(1); + out.writeByte(2); + + final boolean hasExec = handler.executor != null && handler.executor != JNDIContext.globalExecutor(); + out.writeBoolean(hasExec); + if (hasExec) { + out.writeInt(handler.executor.getMaximumPoolSize()); + final BlockingQueue<Runnable> queue = handler.executor.getQueue(); + out.writeInt(queue.size() + queue.remainingCapacity()); + } handler.client.setMetaData(metaData); handler.client.writeExternal(out); @@ -75,6 +86,20 @@ public class EJBHomeHandle implements ja public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final byte version = in.readByte(); // future use + ThreadPoolExecutor executorService; + if (version > 1) { + if (in.readBoolean()) { + final int queue = in.readInt(); + final BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>((queue < 2 ? 2 : queue)); + final int threads = in.readInt(); + executorService = JNDIContext.newExecutor(threads, blockingQueue); + } else { + executorService = null; + } + } else { + executorService = JNDIContext.globalExecutor(); + } + final ClientMetaData client = new ClientMetaData(); final EJBMetaDataImpl ejb = new EJBMetaDataImpl(); final ServerMetaData server = new ServerMetaData(); @@ -97,7 +122,7 @@ public class EJBHomeHandle implements ja server.setMetaData(metaData); server.readExternal(in); - handler = EJBHomeHandler.createEJBHomeHandler(ejb, server, client, null); + handler = EJBHomeHandler.createEJBHomeHandler(executorService, ejb, server, client, null); ejbHomeProxy = handler.createEJBHomeProxy(); } Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeHandler.java Sat May 17 13:12:11 2014 @@ -27,6 +27,7 @@ import java.io.ObjectInput; import java.io.ObjectOutput; import java.lang.reflect.Method; import java.rmi.RemoteException; +import java.util.concurrent.ThreadPoolExecutor; @SuppressWarnings("NullArgumentToVariableArgMethod") public abstract class EJBHomeHandler extends EJBInvocationHandler implements Externalizable { @@ -39,15 +40,18 @@ public abstract class EJBHomeHandler ext @SuppressWarnings("RedundantArrayCreation") protected static final Method REMOVE_W_HAND = getMethod(EJBHome.class, "remove", new Class[]{Handle.class}); protected static final Method GETHANDLER = getMethod(EJBHomeProxy.class, "getEJBHomeHandler", null); + protected ThreadPoolExecutor executor; public EJBHomeHandler() { } - public EJBHomeHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + public EJBHomeHandler(final ThreadPoolExecutor executor, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { super(ejb, server, client, auth); + this.executor = executor; } - public static EJBHomeHandler createEJBHomeHandler(final EJBMetaDataImpl ejb, + public static EJBHomeHandler createEJBHomeHandler(final ThreadPoolExecutor executor, + final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { @@ -55,19 +59,19 @@ public abstract class EJBHomeHandler ext case EJBMetaDataImpl.BMP_ENTITY: case EJBMetaDataImpl.CMP_ENTITY: - return new EntityEJBHomeHandler(ejb, server, client, auth); + return new EntityEJBHomeHandler(executor, ejb, server, client, auth); case EJBMetaDataImpl.STATEFUL: - return new StatefulEJBHomeHandler(ejb, server, client, auth); + return new StatefulEJBHomeHandler(executor, ejb, server, client, auth); case EJBMetaDataImpl.STATELESS: - return new StatelessEJBHomeHandler(ejb, server, client, auth); + return new StatelessEJBHomeHandler(executor, ejb, server, client, auth); case EJBMetaDataImpl.SINGLETON: - return new SingletonEJBHomeHandler(ejb, server, client, auth); + return new SingletonEJBHomeHandler(executor, ejb, server, client, auth); } throw new IllegalStateException("Uknown bean type code '" + ejb.type + "' : " + ejb.toString()); @@ -223,7 +227,7 @@ public abstract class EJBHomeHandler ext case ResponseCodes.EJB_OK: final Object primKey = res.getResult(); - final EJBObjectHandler handler = EJBObjectHandler.createEJBObjectHandler(ejb, server, client, primKey, authenticationInfo); + final EJBObjectHandler handler = EJBObjectHandler.createEJBObjectHandler(executor, ejb, server, client, primKey, authenticationInfo); handler.setEJBHomeProxy((EJBHomeProxy) proxy); return handler.createEJBObjectProxy(); Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeProxyHandle.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeProxyHandle.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeProxyHandle.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBHomeProxyHandle.java Sat May 17 13:12:11 2014 @@ -21,6 +21,11 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; public class EJBHomeProxyHandle implements Externalizable { @@ -44,7 +49,15 @@ public class EJBHomeProxyHandle implemen @Override public void writeExternal(final ObjectOutput out) throws IOException { // write out the version of the serialized data for future use - out.writeByte(1); + out.writeByte(2); + + final boolean hasExec = handler.executor != null && handler.executor != JNDIContext.globalExecutor(); + out.writeBoolean(hasExec); + if (hasExec) { + out.writeInt(handler.executor.getMaximumPoolSize()); + final BlockingQueue<Runnable> queue = handler.executor.getQueue(); + out.writeInt(queue.size() + queue.remainingCapacity()); + } handler.client.setMetaData(metaData); handler.client.writeExternal(out); @@ -66,6 +79,20 @@ public class EJBHomeProxyHandle implemen public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final byte version = in.readByte(); // future use + ThreadPoolExecutor executorService; + if (version > 1) { + if (in.readBoolean()) { + final int queue = in.readInt(); + final BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>((queue < 2 ? 2 : queue)); + final int threads = in.readInt(); + executorService = JNDIContext.newExecutor(threads, blockingQueue); + } else { + executorService = null; + } + } else { + executorService = JNDIContext.globalExecutor(); + } + final ClientMetaData client = new ClientMetaData(); final EJBMetaDataImpl ejb = new EJBMetaDataImpl(); final ServerMetaData server = new ServerMetaData(); @@ -83,7 +110,7 @@ public class EJBHomeProxyHandle implemen server.setMetaData(metaData); server.readExternal(in); - handler = EJBHomeHandler.createEJBHomeHandler(ejb, server, client, /* TODO */ null); + handler = EJBHomeHandler.createEJBHomeHandler(executorService, ejb, server, client, /* TODO */ null); } private Object readResolve() throws ObjectStreamException { Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandle.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandle.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandle.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandle.java Sat May 17 13:12:11 2014 @@ -21,6 +21,9 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.rmi.RemoteException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; public class EJBObjectHandle implements java.io.Externalizable, javax.ejb.Handle { @@ -54,7 +57,15 @@ public class EJBObjectHandle implements @Override public void writeExternal(final ObjectOutput out) throws IOException { // write out the version of the serialized data for future use - out.writeByte(1); + out.writeByte(2); + + final boolean hasExec = handler.executor != null && handler.executor != JNDIContext.globalExecutor(); + out.writeBoolean(hasExec); + if (hasExec) { + out.writeInt(handler.executor.getMaximumPoolSize()); + final BlockingQueue<Runnable> queue = handler.executor.getQueue(); + out.writeInt(queue.size() + queue.remainingCapacity()); + } handler.client.setMetaData(metaData); handler.client.writeExternal(out); @@ -77,6 +88,20 @@ public class EJBObjectHandle implements public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final byte version = in.readByte(); // future use + ThreadPoolExecutor executorService; + if (version > 1) { + if (in.readBoolean()) { + final int queue = in.readInt(); + final BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>((queue < 2 ? 2 : queue)); + final int threads = in.readInt(); + executorService = JNDIContext.newExecutor(threads, blockingQueue); + } else { + executorService = null; + } + } else { + executorService = JNDIContext.globalExecutor(); + } + final ClientMetaData client = new ClientMetaData(); final EJBMetaDataImpl ejb = new EJBMetaDataImpl(); final ServerMetaData server = new ServerMetaData(); @@ -101,7 +126,7 @@ public class EJBObjectHandle implements final Object primaryKey = in.readObject(); - handler = EJBObjectHandler.createEJBObjectHandler(ejb, server, client, primaryKey, null); + handler = EJBObjectHandler.createEJBObjectHandler(executorService, ejb, server, client, primaryKey, null); ejbObjectProxy = handler.createEJBObjectProxy(); } Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectHandler.java Sat May 17 13:12:11 2014 @@ -31,24 +31,16 @@ import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; -import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Level; import java.util.logging.Logger; @SuppressWarnings("NullArgumentToVariableArgMethod") public abstract class EJBObjectHandler extends EJBInvocationHandler { - - public static final String OPENEJB_CLIENT_INVOKER_THREADS = "openejb.client.invoker.threads"; - public static final String OPENEJB_CLIENT_INVOKER_QUEUE = "openejb.client.invoker.queue"; - protected static final Method GETEJBHOME = getMethod(EJBObject.class, "getEJBHome", null); protected static final Method GETHANDLE = getMethod(EJBObject.class, "getHandle", null); protected static final Method GETPRIMARYKEY = getMethod(EJBObject.class, "getPrimaryKey", null); @@ -57,72 +49,6 @@ public abstract class EJBObjectHandler e protected static final Method GETHANDLER = getMethod(EJBObjectProxy.class, "getEJBObjectHandler", null); protected static final Method CANCEL = getMethod(Future.class, "cancel", boolean.class); - //TODO figure out how to configure and manage the thread pool on the client side, this will do for now... - private static final int threads = Integer.parseInt(System.getProperty(OPENEJB_CLIENT_INVOKER_THREADS, "10")); - private static final int queue = Integer.parseInt(System.getProperty(OPENEJB_CLIENT_INVOKER_QUEUE, "2")); - private static final LinkedBlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>((queue < 2 ? 2 : queue)); - - protected static final ThreadPoolExecutor executorService; - - static { - /** - This thread pool starts with 3 core threads and can grow to the limit defined by 'threads'. - If a pool thread is idle for more than 1 minute it will be discarded, unless the core size is reached. - It can accept upto the number of processes defined by 'queue'. - If the queue is full then an attempt is made to add the process to the queue for 10 seconds. - Failure to add to the queue in this time will either result in a logged rejection, or if 'block' - is true then a final attempt is made to run the process in the current thread (the service thread). - */ - - executorService = new ThreadPoolExecutor(3, (threads < 3 ? 3 : threads), 1, TimeUnit.MINUTES, blockingQueue); - executorService.setThreadFactory(new ThreadFactory() { - - private final AtomicInteger i = new AtomicInteger(0); - - @Override - public Thread newThread(final Runnable r) { - final Thread t = new Thread(r, "OpenEJB.Client." + i.incrementAndGet()); - t.setDaemon(true); - t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - @Override - public void uncaughtException(final Thread t, final Throwable e) { - Logger.getLogger(EJBObjectHandler.class.getName()).log(Level.SEVERE, "Uncaught error in: " + t.getName(), e); - } - }); - - return t; - } - - }); - - executorService.setRejectedExecutionHandler(new RejectedExecutionHandler() { - @Override - public void rejectedExecution(final Runnable r, final ThreadPoolExecutor tpe) { - - if (null == r || null == tpe || tpe.isShutdown() || tpe.isTerminated() || tpe.isTerminating()) { - return; - } - - final Logger log = Logger.getLogger(EJBObjectHandler.class.getName()); - - if (log.isLoggable(Level.WARNING)) { - log.log(Level.WARNING, "EJBObjectHandler ExecutorService at capicity for process: " + r); - } - - boolean offer = false; - try { - offer = tpe.getQueue().offer(r, 10, TimeUnit.SECONDS); - } catch (InterruptedException e) { - //Ignore - } - - if (!offer) { - log.log(Level.SEVERE, "EJBObjectHandler ExecutorService failed to run asynchronous process: " + r); - } - } - }); - } - /* * The registryId is a logical identifier that is used as a key when placing EntityEJBObjectHandler into * the BaseEjbProxyHanlder's liveHandleRegistry. EntityEJBObjectHandlers that represent the same @@ -136,26 +62,32 @@ public abstract class EJBObjectHandler e EJBHomeProxy ejbHome = null; + protected ThreadPoolExecutor executor = null; + public EJBObjectHandler() { } - public EJBObjectHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + public EJBObjectHandler(final ThreadPoolExecutor es, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { super(ejb, server, client, null, auth); + this.executor = es; } - public EJBObjectHandler(final EJBMetaDataImpl ejb, + public EJBObjectHandler(final ThreadPoolExecutor es, + final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final Object primaryKey, final JNDIContext.AuthenticationInfo auth) { super(ejb, server, client, primaryKey, auth); + this.executor = es; } protected void setEJBHomeProxy(final EJBHomeProxy ejbHome) { this.ejbHome = ejbHome; } - public static EJBObjectHandler createEJBObjectHandler(final EJBMetaDataImpl ejb, + public static EJBObjectHandler createEJBObjectHandler(final ThreadPoolExecutor executorService, + final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final Object primaryKey, @@ -165,19 +97,19 @@ public abstract class EJBObjectHandler e case EJBMetaDataImpl.BMP_ENTITY: case EJBMetaDataImpl.CMP_ENTITY: - return new EntityEJBObjectHandler(ejb, server, client, primaryKey, auth); + return new EntityEJBObjectHandler(executorService, ejb, server, client, primaryKey, auth); case EJBMetaDataImpl.STATEFUL: - return new StatefulEJBObjectHandler(ejb, server, client, primaryKey, auth); + return new StatefulEJBObjectHandler(executorService, ejb, server, client, primaryKey, auth); case EJBMetaDataImpl.STATELESS: - return new StatelessEJBObjectHandler(ejb, server, client, primaryKey, auth); + return new StatelessEJBObjectHandler(executorService, ejb, server, client, primaryKey, auth); case EJBMetaDataImpl.SINGLETON: - return new SingletonEJBObjectHandler(ejb, server, client, primaryKey, auth); + return new SingletonEJBObjectHandler(executorService, ejb, server, client, primaryKey, auth); } throw new IllegalStateException("Uknown bean type code '" + ejb.type + "' : " + ejb.toString()); @@ -305,7 +237,7 @@ public abstract class EJBObjectHandler e protected Object getEJBHome(final Method method, final Object[] args, final Object proxy) throws Throwable { if (ejbHome == null) { - ejbHome = EJBHomeHandler.createEJBHomeHandler(ejb, server, client, authenticationInfo).createEJBHomeProxy(); + ejbHome = EJBHomeHandler.createEJBHomeHandler(executor, ejb, server, client, authenticationInfo).createEJBHomeProxy(); } return ejbHome; } @@ -330,7 +262,10 @@ public abstract class EJBObjectHandler e final String requestId = UUID.randomUUID().toString(); final EJBResponse response = new EJBResponse(); final AsynchronousCall asynchronousCall = new AsynchronousCall(method, args, proxy, requestId, response); - return new FutureAdapter(executorService.submit(asynchronousCall), response, requestId); + if (executor == null) { + executor = JNDIContext.newExecutor(-1, null); + } + return new FutureAdapter(executor.submit(asynchronousCall), response, requestId); } catch (RejectedExecutionException e) { throw new EJBException("failed to allocate internal resource to execute the target task", e); } @@ -455,7 +390,7 @@ public abstract class EJBObjectHandler e if (canceled) { return true; } - if (blockingQueue.remove(target)) { + if (executor.getQueue().remove(target)) { // We successfully remove the task from the queue canceled = true; return true; Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectProxyHandle.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectProxyHandle.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectProxyHandle.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EJBObjectProxyHandle.java Sat May 17 13:12:11 2014 @@ -21,6 +21,9 @@ import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.ObjectStreamException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; public class EJBObjectProxyHandle implements Externalizable { @@ -44,7 +47,15 @@ public class EJBObjectProxyHandle implem @Override public void writeExternal(final ObjectOutput out) throws IOException { // write out the version of the serialized data for future use - out.writeByte(1); + out.writeByte(2); + + final boolean hasExec = handler.executor != null && handler.executor != JNDIContext.globalExecutor(); + out.writeBoolean(hasExec); + if (hasExec) { + out.writeInt(handler.executor.getMaximumPoolSize()); + final BlockingQueue<Runnable> queue = handler.executor.getQueue(); + out.writeInt(queue.size() + queue.remainingCapacity()); + } handler.client.setMetaData(metaData); handler.client.writeExternal(out); @@ -63,6 +74,20 @@ public class EJBObjectProxyHandle implem public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final byte version = in.readByte(); // future use + ThreadPoolExecutor executorService; + if (version > 1) { + if (in.readBoolean()) { + final int queue = in.readInt(); + final BlockingQueue<Runnable> blockingQueue = new LinkedBlockingQueue<Runnable>((queue < 2 ? 2 : queue)); + final int threads = in.readInt(); + executorService = JNDIContext.newExecutor(threads, blockingQueue); + } else { + executorService = null; + } + } else { + executorService = JNDIContext.globalExecutor(); + } + final ClientMetaData client = new ClientMetaData(); final EJBMetaDataImpl ejb = new EJBMetaDataImpl(); final ServerMetaData server = new ServerMetaData(); @@ -79,7 +104,7 @@ public class EJBObjectProxyHandle implem final JNDIContext.AuthenticationInfo authenticationInfo = JNDIContext.AuthenticationInfo.class.cast(in.readObject()); - handler = EJBObjectHandler.createEJBObjectHandler(ejb, server, client, primaryKey, authenticationInfo); + handler = EJBObjectHandler.createEJBObjectHandler(executorService, ejb, server, client, primaryKey, authenticationInfo); } private Object readResolve() throws ObjectStreamException { Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBHomeHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBHomeHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBHomeHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBHomeHandler.java Sat May 17 13:12:11 2014 @@ -20,14 +20,15 @@ import javax.ejb.EJBObject; import javax.ejb.Handle; import java.lang.reflect.Method; import java.rmi.RemoteException; +import java.util.concurrent.ThreadPoolExecutor; public class EntityEJBHomeHandler extends EJBHomeHandler { public EntityEJBHomeHandler() { } - public EntityEJBHomeHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, auth); + public EntityEJBHomeHandler(final ThreadPoolExecutor executor, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + super(executor, ejb, server, client, auth); } @Override @@ -53,7 +54,7 @@ public class EntityEJBHomeHandler extend if (primKey == null) { return null; } else { - handler = EJBObjectHandler.createEJBObjectHandler(ejb, server, client, primKey, authenticationInfo); + handler = EJBObjectHandler.createEJBObjectHandler(executor, ejb, server, client, primKey, authenticationInfo); handler.setEJBHomeProxy((EJBHomeProxy) proxy); registerHandler(ejb.deploymentID + ":" + primKey, handler); return handler.createEJBObjectProxy(); @@ -66,7 +67,7 @@ public class EntityEJBHomeHandler extend for (int i = 0; i < primaryKeys.length; i++) { primKey = primaryKeys[i]; if (primKey != null) { - handler = EJBObjectHandler.createEJBObjectHandler(ejb, server, client, primKey, authenticationInfo); + handler = EJBObjectHandler.createEJBObjectHandler(executor, ejb, server, client, primKey, authenticationInfo); handler.setEJBHomeProxy((EJBHomeProxy) proxy); registerHandler(ejb.deploymentID + ":" + primKey, handler); primaryKeys[i] = handler.createEJBObjectProxy(); @@ -80,7 +81,7 @@ public class EntityEJBHomeHandler extend for (int i = 0; i < primaryKeys.length; i++) { primKey = primaryKeys[i]; if (primKey != null) { - handler = EJBObjectHandler.createEJBObjectHandler(ejb, server, client, primKey, authenticationInfo); + handler = EJBObjectHandler.createEJBObjectHandler(executor, ejb, server, client, primKey, authenticationInfo); handler.setEJBHomeProxy((EJBHomeProxy) proxy); registerHandler(ejb.deploymentID + ":" + primKey, handler); primaryKeys[i] = handler.createEJBObjectProxy(); Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBObjectHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBObjectHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBObjectHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/EntityEJBObjectHandler.java Sat May 17 13:12:11 2014 @@ -18,22 +18,24 @@ package org.apache.openejb.client; import java.lang.reflect.Method; import java.rmi.RemoteException; +import java.util.concurrent.ThreadPoolExecutor; public class EntityEJBObjectHandler extends EJBObjectHandler { public EntityEJBObjectHandler() { } - public EntityEJBObjectHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, auth); + public EntityEJBObjectHandler(final ThreadPoolExecutor executorService, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + super(executorService, ejb, server, client, auth); } - public EntityEJBObjectHandler(final EJBMetaDataImpl ejb, + public EntityEJBObjectHandler(final ThreadPoolExecutor executorService, + final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final Object primaryKey, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, primaryKey, auth); + super(executorService, ejb, server, client, primaryKey, auth); registryId = ejb.deploymentID + ":" + primaryKey; registerHandler(registryId, this); } Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/JNDIContext.java Sat May 17 13:12:11 2014 @@ -48,16 +48,30 @@ import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.Properties; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @version $Rev$ $Date$ */ @SuppressWarnings("UseOfObsoleteCollectionType") public class JNDIContext implements InitialContextFactory, Context { + private static final Logger LOGGER = Logger.getLogger("OpenEJB.client"); public static final String DEFAULT_PROVIDER_URL = "ejbd://localhost:4201"; public static final String SERIALIZER = "openejb.ejbd.serializer"; public static final String AUTHENTICATE_WITH_THE_REQUEST = "openejb.ejbd.authenticate-with-request"; + public static final String POOL_QUEUE_SIZE = "openejb.client.invoker.queue"; + public static final String POOL_THREAD_NUMBER = "openejb.client.invoker.threads"; private String tail = "/"; private ServerMetaData server; @@ -66,8 +80,115 @@ public class JNDIContext implements Init private String moduleId; private ClientInstance clientIdentity; + private static final ThreadPoolExecutor GLOBAL_CLIENT_POOL = newExecutor(10, null); + static { + ClassLoader classLoader = Client.class.getClassLoader(); + Class<?> container; + try { + container = Class.forName("org.apache.openejb.OpenEJB", false, classLoader); + } catch (final Throwable e) { + container = null; + } + if (classLoader == ClassLoader.getSystemClassLoader() || Boolean.getBoolean("openejb.client.flus-tasks") + || (container != null && container.getClassLoader() == classLoader)) { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + waitEndOfTasks(GLOBAL_CLIENT_POOL); + } + }); + } + } + private AuthenticationInfo authenticationInfo = null; + //TODO figure out how to configure and manage the thread pool on the client side, this will do for now... + private transient int threads; + private transient LinkedBlockingQueue<Runnable> blockingQueue; + + protected transient ThreadPoolExecutor executorService; + + public static ThreadPoolExecutor globalExecutor() { + return GLOBAL_CLIENT_POOL; + } + + private ThreadPoolExecutor executor() { + if (executorService != null) { + return executorService; + } + if (threads < 0) { + return GLOBAL_CLIENT_POOL; + } + synchronized (this) { + if (executorService != null) { + return executorService; + } + executorService = newExecutor(threads, blockingQueue); + } + return executorService; + } + + public static ThreadPoolExecutor newExecutor(final int threads, final BlockingQueue<Runnable> blockingQueue) + { + /** + This thread pool starts with 3 core threads and can grow to the limit defined by 'threads'. + If a pool thread is idle for more than 1 minute it will be discarded, unless the core size is reached. + It can accept upto the number of processes defined by 'queue'. + If the queue is full then an attempt is made to add the process to the queue for 10 seconds. + Failure to add to the queue in this time will either result in a logged rejection, or if 'block' + is true then a final attempt is made to run the process in the current thread (the service thread). + */ + + final ThreadPoolExecutor executorService = new ThreadPoolExecutor(3, (threads < 3 ? 3 : threads), 1, TimeUnit.MINUTES, blockingQueue == null ? new LinkedBlockingDeque<Runnable>(Integer.parseInt(getProperty(null, POOL_QUEUE_SIZE, "2"))) : blockingQueue); + executorService.setThreadFactory(new ThreadFactory() { + + private final AtomicInteger i = new AtomicInteger(0); + + @Override + public Thread newThread(final Runnable r) { + final Thread t = new Thread(r, "OpenEJB.Client." + i.incrementAndGet()); + t.setDaemon(true); + t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(final Thread t, final Throwable e) { + Logger.getLogger(EJBObjectHandler.class.getName()).log(Level.SEVERE, "Uncaught error in: " + t.getName(), e); + } + }); + + return t; + } + + }); + + executorService.setRejectedExecutionHandler(new RejectedExecutionHandler() { + @Override + public void rejectedExecution(final Runnable r, final ThreadPoolExecutor tpe) { + + if (null == r || null == tpe || tpe.isShutdown() || tpe.isTerminated() || tpe.isTerminating()) { + return; + } + + final Logger log = Logger.getLogger(EJBObjectHandler.class.getName()); + + if (log.isLoggable(Level.WARNING)) { + log.log(Level.WARNING, "EJBObjectHandler ExecutorService at capicity for process: " + r); + } + + boolean offer = false; + try { + offer = tpe.getQueue().offer(r, 10, TimeUnit.SECONDS); + } catch (InterruptedException e) { + //Ignore + } + + if (!offer) { + log.log(Level.SEVERE, "EJBObjectHandler ExecutorService failed to run asynchronous process: " + r); + } + } + }); + return executorService; + } + public JNDIContext() { } @@ -156,9 +277,22 @@ public class JNDIContext implements Init } } + final int queue = Integer.parseInt(getProperty(env, JNDIContext.POOL_QUEUE_SIZE, "2")); + blockingQueue = new LinkedBlockingQueue<Runnable>((queue < 2 ? 2 : queue)); + threads = Integer.parseInt(getProperty(env, "openejb.client.invoker.threads", "-1")); + return this; } + private static String getProperty(final Hashtable env, final String key, final String defaultValue) + { + Object value = env == null ? null : env.get(key); + if (value != null) { + return value.toString(); + } + return System.getProperty(key, defaultValue); + } + /** * Add missing parts - expected only part of the required providerUrl * <p/> @@ -217,7 +351,7 @@ public class JNDIContext implements Init } public EJBHomeProxy createEJBHomeProxy(final EJBMetaDataImpl ejbData) { - final EJBHomeHandler handler = EJBHomeHandler.createEJBHomeHandler(ejbData, server, client, authenticationInfo); + final EJBHomeHandler handler = EJBHomeHandler.createEJBHomeHandler(executor(), ejbData, server, client, authenticationInfo); final EJBHomeProxy proxy = handler.createEJBHomeProxy(); handler.ejb.ejbHomeProxy = proxy; @@ -229,7 +363,7 @@ public class JNDIContext implements Init final EJBMetaDataImpl ejb = (EJBMetaDataImpl) result; final Object primaryKey = ejb.getPrimaryKey(); - final EJBObjectHandler handler = EJBObjectHandler.createEJBObjectHandler(ejb, server, client, primaryKey, authenticationInfo); + final EJBObjectHandler handler = EJBObjectHandler.createEJBObjectHandler(executor(), ejb, server, client, primaryKey, authenticationInfo); return handler.createEJBObjectProxy(); } @@ -574,6 +708,23 @@ public class JNDIContext implements Init @Override public void close() throws NamingException { + waitEndOfTasks(executorService); + } + + private static void waitEndOfTasks(final ExecutorService executor) + { + if (executor == null) { + return; + } + + final List<Runnable> runnables = executor.shutdownNow(); + for (final Runnable r : runnables) { + try { + r.run(); + } catch (final Throwable th) { + LOGGER.log(Level.SEVERE, th.getMessage(), th); + } + } } @Override Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBHomeHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBHomeHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBHomeHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBHomeHandler.java Sat May 17 13:12:11 2014 @@ -18,14 +18,15 @@ package org.apache.openejb.client; import javax.ejb.RemoveException; import java.lang.reflect.Method; +import java.util.concurrent.ThreadPoolExecutor; public class SingletonEJBHomeHandler extends EJBHomeHandler { public SingletonEJBHomeHandler() { } - public SingletonEJBHomeHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, auth); + public SingletonEJBHomeHandler(final ThreadPoolExecutor executor, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + super(executor, ejb, server, client, auth); } @Override @@ -44,7 +45,7 @@ public class SingletonEJBHomeHandler ext return null; } - protected EJBObjectHandler newEJBObjectHandler() { + protected EJBObjectHandler newEJBObjectHandler() { // shouldn't be called return new SingletonEJBObjectHandler(); } Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBObjectHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBObjectHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBObjectHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/SingletonEJBObjectHandler.java Sat May 17 13:12:11 2014 @@ -18,6 +18,8 @@ package org.apache.openejb.client; import java.lang.reflect.Method; import java.rmi.RemoteException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadPoolExecutor; public class SingletonEJBObjectHandler extends EJBObjectHandler { @@ -26,16 +28,17 @@ public class SingletonEJBObjectHandler e public SingletonEJBObjectHandler() { } - public SingletonEJBObjectHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, auth); + public SingletonEJBObjectHandler(final ThreadPoolExecutor executorService, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + super(executorService, ejb, server, client, auth); } - public SingletonEJBObjectHandler(final EJBMetaDataImpl ejb, + public SingletonEJBObjectHandler(final ThreadPoolExecutor executorService, + final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final Object primaryKey, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, primaryKey, auth); + super(executorService, ejb, server, client, primaryKey, auth); } public static Object createRegistryId(final Object primKey, final Object deployId, final String containerID) { Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBHomeHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBHomeHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBHomeHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBHomeHandler.java Sat May 17 13:12:11 2014 @@ -19,14 +19,15 @@ package org.apache.openejb.client; import javax.ejb.RemoveException; import java.lang.reflect.Method; import java.rmi.RemoteException; +import java.util.concurrent.ThreadPoolExecutor; public class StatefulEJBHomeHandler extends EJBHomeHandler { public StatefulEJBHomeHandler() { } - public StatefulEJBHomeHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, auth); + public StatefulEJBHomeHandler(final ThreadPoolExecutor executor, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + super(executor, ejb, server, client, auth); } @Override Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBObjectHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBObjectHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBObjectHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatefulEJBObjectHandler.java Sat May 17 13:12:11 2014 @@ -18,22 +18,25 @@ package org.apache.openejb.client; import java.lang.reflect.Method; import java.rmi.RemoteException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadPoolExecutor; public class StatefulEJBObjectHandler extends EJBObjectHandler { public StatefulEJBObjectHandler() { } - public StatefulEJBObjectHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, auth); + public StatefulEJBObjectHandler(final ThreadPoolExecutor executorService, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + super(executorService, ejb, server, client, auth); } - public StatefulEJBObjectHandler(final EJBMetaDataImpl ejb, + public StatefulEJBObjectHandler(final ThreadPoolExecutor executorService, + final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final Object primaryKey, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, primaryKey, auth); + super(executorService, ejb, server, client, primaryKey, auth); registerHandler(primaryKey, this); } Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBHomeHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBHomeHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBHomeHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBHomeHandler.java Sat May 17 13:12:11 2014 @@ -18,14 +18,15 @@ package org.apache.openejb.client; import javax.ejb.RemoveException; import java.lang.reflect.Method; +import java.util.concurrent.ThreadPoolExecutor; public class StatelessEJBHomeHandler extends EJBHomeHandler { public StatelessEJBHomeHandler() { } - public StatelessEJBHomeHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, auth); + public StatelessEJBHomeHandler(final ThreadPoolExecutor executor, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + super(executor, ejb, server, client, auth); } @Override Modified: tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBObjectHandler.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBObjectHandler.java?rev=1595470&r1=1595469&r2=1595470&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBObjectHandler.java (original) +++ tomee/tomee/trunk/server/openejb-client/src/main/java/org/apache/openejb/client/StatelessEJBObjectHandler.java Sat May 17 13:12:11 2014 @@ -18,6 +18,8 @@ package org.apache.openejb.client; import java.lang.reflect.Method; import java.rmi.RemoteException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ThreadPoolExecutor; public class StatelessEJBObjectHandler extends EJBObjectHandler { @@ -26,16 +28,17 @@ public class StatelessEJBObjectHandler e public StatelessEJBObjectHandler() { } - public StatelessEJBObjectHandler(final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, auth); + public StatelessEJBObjectHandler(final ThreadPoolExecutor executorService, final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final JNDIContext.AuthenticationInfo auth) { + super(executorService, ejb, server, client, auth); } - public StatelessEJBObjectHandler(final EJBMetaDataImpl ejb, + public StatelessEJBObjectHandler(final ThreadPoolExecutor executorService, + final EJBMetaDataImpl ejb, final ServerMetaData server, final ClientMetaData client, final Object primaryKey, final JNDIContext.AuthenticationInfo auth) { - super(ejb, server, client, primaryKey, auth); + super(executorService, ejb, server, client, primaryKey, auth); } public static Object createRegistryId(final Object primKey, final Object deployId, final String containerID) {