You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ga...@apache.org on 2008/03/07 20:56:28 UTC
svn commit: r634792 [9/9] - in /geronimo/sandbox/concurrent: ./
concurrent-deployer/ concurrent-deployer/src/ concurrent-deployer/src/main/
concurrent-deployer/src/main/plan/ concurrent/ concurrent/src/
concurrent/src/main/ concurrent/src/main/plan/ ge...
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,277 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.Map;
+
+/**
+ * The ContextService provides methods for creating <i>contextual dynamic proxy</i>
+ * objects.
+ * <p>
+ *
+ * The proxy objects follow the same rules as defined for the
+ * {@link java.lang.reflect.Proxy} class with the following additions:
+ * <ul>
+ * <li>The proxy instance will retain the context of the application
+ * container's thread (creator's context).
+ * <li>The proxy instance will implement all of the interfaces specified on the
+ * <code>createContextObject</code> methods.
+ * <li>All interface method invocations on a proxy instance run in the
+ * creator's context.
+ * <li>Invocation of the <code>hashCode</code>, <code>equals</code>, and
+ * <code>toString</code> methods declared in <code>java.lang.Object</code>
+ * on a sproxy instance will not run in the creator's context.
+ * <li>The proxy instance must implement <code>java.io.Serializable</code>.
+ * <li>The proxied object instance must implement
+ * <code>java.io.Serializable</code> if the proxy instance is serialized.
+ * <li>Context properties can be stored with the proxy instance. Custom
+ * property keys must not begin with "ctxsvc.".
+ * <li>Context properties are to be used for controlling how various contextual
+ * information is retreived and applied to the thread. Although application
+ * components can store arbitrary property keys and values, it is not
+ * recommended. Java EE product providers may impose limits to the size of the
+ * keys and values.
+ * <li>Context property keys and values must all be of type
+ * <code>java.lang.String</code>. Use of the <code>put</code> and
+ * <code>putAll</code> methods on the <code>java.util.Hashtable</code>
+ * superclass are discouraged.
+ * </ul>
+ *
+ */
+public interface ContextService {
+ /**
+ * A contextual object property that disables the normal transaction
+ * suspension and UserTransaction access from the proxied methods.
+ * <p>
+ *
+ * If "false" (the default if unspecified), any transaction that is
+ * currently active on the thread will be suspended and a UserTransaction
+ * (accessible in the local JNDI namespace as "java:comp/UserTransaction")
+ * will be available. When the proxied method returns the original
+ * transaction is restored.
+ * <p>
+ *
+ * If "true", the proxied method will run within the transaction (if any) of
+ * the current thread. A UserTransaction will only be available if the the
+ * container thread (for example, a Servlet or Bean Managed Transaction
+ * EJB).
+ */
+ public String USE_PARENT_TRANSACTION = "ctxsvc.useparenttran";
+
+ /**
+ * Creates a new contextual object proxy for the input object instance.
+ * <p>
+ *
+ * Each method invocation will have the context of the application component
+ * instance that created the context object.
+ * <p>
+ *
+ * The contextual object is useful when developing or using Java SE
+ * threading mechanisms spraying events to other component instances or
+ * communicating with component instances on different Java processes.
+ * <p>
+ *
+ * If the application component that created the proxy is started or
+ * deployed, all methods on reflected interfaces will throw a
+ * <code>java.lang.IllegalState</code> exception.
+ * <p>
+ *
+ * For example, to call a normal Runnable with the correct context using a
+ * Java™ ExecutorService:
+ * <P>
+ *
+ * <pre>
+ * public class MyRunnable implements Runnable {
+ * public void run() {
+ * System.out.println("MyRunnable.run with J2EE Context available.");
+ * }
+ * }
+ *
+ * InitialContext ctx = new InitialContext();
+ *
+ * ThreadFactory threadFactory = (ThreadFactory) ctx
+ * .lookup("java:comp/env/concurrent/ThreadFactory");
+ *
+ * ContextService ctxService = (ContextService) ctx
+ * .lookup("java:comp/env/concurrent/ContextService");
+ *
+ * Object rProxy = ctxService.createContextObject(myRunnableInstance,
+ * new Class[] { Runnable.class });
+ *
+ * ExecutorService exSvc = Executors.newThreadPool(10, threadFactory);
+ *
+ * Future f = exSvc.submit((Runnable) rProxy);
+ * </pre>
+ *
+ * @param instance
+ * the instance of the object to proxy.
+ * @param interfaces
+ * the interfaces that the proxy should implement.
+ * @return a proxy for the input object that implements all of the specified
+ * interfaces.
+ * @throws IllegalArgumentException
+ * if the Class does not have an interface or there is not an
+ * accessible default constructor.
+ */
+ public Object createContextObject(Object instance, Class<?>[] interfaces);
+
+ /**
+ * Creates a new contextual object proxy for the input object instance.
+ * <p>
+ *
+ * The contextual object is useful when developing or using Java SE
+ * threading mechanisms spraying events to other component instances or
+ * communicating with component instances on different Java processes.
+ * <p>
+ *
+ * If the application component that created the proxy is started or
+ * deployed, all methods on reflected interfaces will throw a
+ * <code>java.lang.IllegalState</code> exception.
+ * <p>
+ *
+ * This method accepts a {@link Properties} object which allows the
+ * contextual object creator to define what contexts or behaviors to capture
+ * when creating the contextual object. The specified properties will remain
+ * with the contextual object until the properties are updated or removed
+ * using the {@link #setProperties(Object, Properties)} method.
+ * <p>
+ *
+ * For example, to call a Message Driven Bean (MDB) with the sender's
+ * context, but within the MDB's transaction:
+ * <P>
+ *
+ * <pre>
+ * public class MyServlet ... {
+ * public void doPost() throws NamingException, JMSException {
+ * InitialContext ctx = new InitialContext();
+ *
+ * // Get the ContextService that only propagates
+ * // security context.
+ * ContextService ctxSvc = (ContextService)
+ * ctx.lookup("java:comp/env/SecurityContext");
+ *
+ * // Set any custom context data.
+ * Properties ctxProps = new Properties();
+ * ctxProps.setProperty("vendor_a.security.tokenexpiration", "15000");
+ *
+ * ProcessMessage msgProcessor =
+ * (ProcessMessage) ctxSvc.createContextObject(new MessageProcessor(),
+ * new Class[]{ProcessMessage.class},
+ * ctxProps);
+ *
+ * ConnectionFactory cf = (ConnectionFactory)
+ * ctx.lookup("java:comp/env/MyTopicConnectionFactory");
+ * Destination dest = (Destination) ctx.lookup("java:comp/env/MyTopic");
+ * Connection con = cf.createConnection();
+ *
+ * Session session = con.createSession(true, Session.AUTO_ACKNOWLEDGE);
+ * MessageProducer producer = session.createProducer(dest);
+ *
+ * Message msg = session.createObjectMessage((Serializable)msgProcessor);
+ * producer.send(dest, msg);
+ * ...
+ *
+ * }
+ *
+ * public class MyMDB ... {
+ * public void onMessage(Message msg) {
+ * // Get the ProcessMessage context object from the message.
+ * ObjectMessage omsg = (ObjectMessage)msg;
+ * ProcessMessage msgProcessor = (ProcessMessage)omsg.getObject();
+ *
+ * // Update the context object and verify that the processMessage()
+ * // method runs inside the current transaction. If we have a failure,
+ * // we don't want to consume the message.
+ * InitialContext ctx = new InitialContext();
+ * ContextService ctxSvc = (ContextService)
+ * ctx.lookup("java:comp/env/SecurityContext");
+ * Properties ctxProps = ctxSvc.getProperties(msgProcessor);
+ * ctxProps.setProperty(ContextService.USE_PARENT_TRANSACTION, "true");
+ * ctxSvc.setProperties(msgProcessor, ctxProps);
+ *
+ * // Process the message in the specified context.
+ * msgProcessor.processMessage(msg);
+ * }
+ * }
+ *
+ * public interface ProcessMessage {
+ * public void processMessage(Message msg);
+ * }
+ *
+ * public class MessageProcessor implements ProcessMessage, Serializable {
+ * public void processMessage(Message msg) {
+ * // Process the message with the application container
+ * // context that sent the message.
+ *
+ * }
+ * }
+ * </pre>
+ *
+ * @param instance
+ * the instance of the object to proxy.
+ * @param interfaces
+ * the interfaces that the proxy should implement.
+ * @param contextProperties
+ * the properties to use when creating and running the context
+ * object.
+ * @return a proxy for the input object that implements all of the specified
+ * interfaces.
+ * @throws IllegalArgumentException
+ * if the Class does not have an interface or there is not an
+ * accessible default constructor.
+ * @throws ClassCastException
+ * thrown if one of the keys or values in the specified
+ * Properties object are not of type String.
+ */
+ public Object createContextObject(Object instance, Class<?>[] interfaces,
+ Map<String, String> contextProperties);
+
+ /**
+ * Sets the properties on the context proxy instance.
+ * <p>
+ *
+ * All property keys and values must be strings. Storing other class types
+ * may result in a <code>java.lang.ClassCastException</code>.
+ *
+ * @param contextObject
+ * the contextual proxy instance to set the properties.
+ * @param contextProperties
+ * the properties to use when running the context object. Specify
+ * an empty Properties object to erase all current properties.
+ * @throws IllegalArgumentException
+ * thrown if the input contextObject is not a valid contextual
+ * object proxy created with the
+ * <code>createContextObject</code> method.
+ * @throws ClassCastException
+ * thrown if one of the keys or values in the specified
+ * Properties object are not of type String.
+ */
+ public void setProperties(Object contextObject, Map<String, String> contextProperties);
+
+ /**
+ * Gets the current properties on the context proxy instance.
+ *
+ * @param contextObject
+ * the contextual proxy instance to set the properties.
+ * @return the current context object properties
+ * @throws IllegalArgumentException
+ * thrown if the input contextObject is not a valid contextual
+ * object proxy created with the
+ * <code>createContextObject</code> method.
+ */
+ public Map<String, String> getProperties(Object contextObject);
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ContextService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,78 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Exception indicating that the result of a value-producing task cannot be retrieved because the
+ * remote executor that the task is running on is no longer available.<p>
+ *
+ * Use the {@link java.lang.Throwable#getCause()} method to determine why the executor is no longer available.
+ */
+public class ExecutorNotAvailableException extends ExecutionException {
+
+ private static final long serialVersionUID = 4086046729432722254L;
+
+ /**
+ * Constructs an ExecutorNotAvailableException with <code>null</code> as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a call to
+ * {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
+ */
+ public ExecutorNotAvailableException() {
+ super();
+ }
+
+ /**
+ * Constructs an ExecutorNotAvailableException exception with the specified detail message.<p>
+ *
+ * The cause is not initialized, and may subsequently be initialized by a call to
+ * {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
+ *
+ * @param message the detail message (which is saved for later retrieval by the {@link java.lang.Throwable#getMessage()} method).
+ */
+ public ExecutorNotAvailableException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs an ExecutorNotAvailableException exception with the specified detail message and cause.<p>
+ *
+ * Note that the detail message associated with cause is not automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval by the {@link java.lang.Throwable#getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
+ * (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
+ */
+ public ExecutorNotAvailableException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs an ExecutorNotAvailableException exception with the specified cause and a
+ * detail message of (cause==null ? null : cause.toString())
+ * (which typically contains the class and detail message of cause).
+ *
+ * @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
+ * (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
+ */
+ public ExecutorNotAvailableException(Throwable cause) {
+ super(cause);
+ }
+
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ExecutorNotAvailableException.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,45 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.Locale;
+
+/**
+ * A tasks submitted to an {@link javax.util.concurrent.ManagedExecutorService}
+ * can optionally implement this interface.<p>
+ *
+ * The intent of this interface is to allow management facilities to inspect the task to determine
+ * the intent of the task and its state. Implementations should not depend upon any thread execution
+ * context and should typically return only readily-available instance data.
+ */
+public interface Identifiable {
+
+ /**
+ * The name or ID of the identifiable object.
+ * @return the name or ID of the identifiable object.
+ */
+ public String getIdentityName();
+
+ /**
+ * The description of the identifiable object translated for a given locale.
+ * @param locale the locale to use to generate the description. If null, the default locale will be
+ * used.
+ * @return the description of the identifiable object in the specified locale.
+ */
+ public String getIdentityDescription(Locale locale);
+
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Identifiable.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,283 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+
+
+/**
+ * A manageable version of a {@link java.util.concurrent.ExecutorService}.<p>
+ *
+ * A ManagedExecutorService provides methods for submitting tasks for execution
+ * in a managed environment. Implementations of the ManagedExecutorService are
+ * provided by a Java™ EE Product Provider. Application Component Providers
+ * use the Java Naming and Directory Interface™ (JNDI) to look-up instances of one
+ * or more ManagedExecutorService objects using resource environment references.<p>
+ *
+ * The Concurrency Utilities for Java™ EE specification describes several
+ * behaviors that a ManagedExecutorService can implement. The Application
+ * Component Provider and Deployer identify these requirements and map the
+ * resource environment reference appropriately.<p>
+ *
+ * The most common uses for a ManagedExecutorService is to run short-duration asynchronous
+ * tasks in the local JVM from a container such as an Enterprise
+ * JavaBean™ (EJB™) or servlet. Use a managed ThreadFactory for long-running
+ * daemon tasks.<p>
+ *
+ * Tasks run within the application component context that either
+ * submitted the task or created the ManagedExecutorService instance (server-managed or component-managed).
+ * All tasks run without an explicit transaction (they do not enlist in the application
+ * component's transaction). If a transaction is required, use a
+ * {@link javax.transaction.UserTransaction} instance. A UserTransaction instance is
+ * available in JNDI using the name: "java:comp/UserTransaction"<p>
+ *
+ * Example:<pre>
+ * public run() {
+ * // Begin of task
+ * InitialContext ctx = new InitialContext();
+ * UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
+ * ut.begin();
+ *
+ * // Perform transactional business logic
+ *
+ * ut.commit();
+ * }</PRE>
+ *
+ * Asynchronous tasks are typically submitted to the ManagedExecutorService using one
+ * of the <code>submit</code> methods, each of which return a {@link java.util.concurrent.Future}
+ * instance. The <code>Future</code> represents the result of the task and can also be used to
+ * check if the task is complete or wait for its completion.<p>
+ *
+ * If the task is cancelled, the result fo the task is a
+ * {@link java.util.concurrent.CancellationException} exception. If the task is unable
+ * to run due to start due to a reason other than cancellation, the result is a
+ * {@link javax.util.concurrent.AbortedException} exception.<p>
+ *
+ * Example:<pre>
+ * /**
+ * * Retrieve all accounts from several account databases in parallel.
+ * * Resource Mappings:
+ * * type: javax.util.concurrent.ManagedExecutorService
+ * * jndi-name: mes/ThreadPool
+ * * attributes:
+ * * Run Location = Local
+ * */
+ * public List<Account> getAccounts(long accountId) {
+ * try {
+ * javax.naming.InitialContext ctx = new InitialContext();
+ * <b>ManagedExecutorService mes = (ManagedExecutorService)
+ * ctx.lookup("java:comp/env/concurrent/ThreadPool");</b>
+ *
+ * // Create a set of tasks to perform the account retrieval.
+ * ArrayList<Callable<Account>> retrieverTasks = new ArrayList<Callable<Account>>();
+ * retrieverTasks.add(new EISAccountRetriever());
+ * retrieverTasks.add(new RDBAccountRetriever());
+ *
+ * // Submit the tasks to the thread pool and wait for them
+ * // to complete (successfully or otherwise).
+ * <b>List<Future<Account>> taskResults= mes.invokeAll(retrieverTasks);</b>
+ *
+ * // Retrieve the results from the resulting Future list.
+ * ArrayList<Account> results = new ArrayList<Account>();
+ * for(Future<Account> taskResult : taskResults) {
+ * try {
+ * <b>results.add(taskResult.get());</b>
+ * } catch (ExecutionException e) {
+ * Throwable cause = e.getCause();
+ * // Handle the AccountRetrieverError.
+ * }
+ * }
+ *
+ * return results;
+ *
+ * } catch (NamingException e) {
+ * // Throw exception for fatal error.
+ * } catch (InterruptedException e) {
+ * // Throw exception for shutdown or other interrupt condition.
+ * }
+ * }
+ *
+ * }
+ *
+ * public class EISAccountRetriever implements Callable<Account> {
+ * public Account call() {
+ * // Connect to our eis system and retrieve the info for the account.
+ * //...
+ * return null;
+ * }
+ * }
+ *
+ * public class RDBAccountRetriever implements Callable<Account> {
+ * public Account call() {
+ * // Connect to our database and retrieve the info for the account.
+ * //...
+ * }
+ * }
+ *
+ * public class Account {
+ * // Some account data...
+ * }
+ *
+ *</pre>
+ */
+public interface ManagedExecutorService extends ExecutorService
+{
+ /**
+ * This method has the same semantics as {@link ExecutorService#submit(java.lang.Runnable)}
+ * but also includes the ability to be notified when the task's lifecycle changes.
+ *
+ * @param task the task to submit
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will return <tt>null</tt>
+ * upon completion.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution
+ * @throws NullPointerException if task null
+ */
+ Future<?> submit(Runnable task, ManagedTaskListener taskListener);
+
+ /**
+ * This method has the same semantics as {@link ExecutorService#submit(java.lang.Runnable, T)}
+ * but also includes the ability to be notified when the task's lifecycle changes.
+ *
+ * @param task the task to submit
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @param result the result to return
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will return the given result
+ * upon completion.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution
+ * @throws NullPointerException if task null
+ */
+ <T> Future<T> submit(Runnable task, T result, ManagedTaskListener taskListener);
+
+ /**
+ * This method has the same semantics as {@link ExecutorService#submit(java.util.concurrent.Callable)}
+ * but also includes the ability to be notified when the task's lifecycle changes.
+ *
+ * @param task the task to submit
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return a Future representing pending completion of the task
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution
+ * @throws NullPointerException if task null
+ */
+ <T> Future<T> submit(Callable<T> task, ManagedTaskListener taskListener);
+
+ /**
+ * This method has the same semantics as {@link ExecutorService#invokeAll(java.util.Collection)}
+ * but also includes the ability to be notified when each task's lifecycle changes.
+ *
+ * @param tasks the collection of tasks
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return A list of Futures representing the tasks, in the same
+ * sequential order as produced by the iterator for the given task
+ * list, each of which has completed.
+ * @throws InterruptedException if interrupted while waiting, in
+ * which case unfinished tasks are cancelled.
+ * @throws NullPointerException if tasks or any of its elements are <tt>null</tt>
+ * @throws RejectedExecutionException if any task cannot be scheduled
+ * for execution
+ */
+ <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks, ManagedTaskListener taskListener)
+ throws InterruptedException;
+
+ /**
+ * This method has the same semantics as
+ * {@link ExecutorService#invokeAll(java.util.Collection, long, java.util.concurrent.TimeUnit)}
+ * but also includes the ability to be notified when each task's lifecycle changes.
+ *
+ * @param tasks the collection of tasks
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return A list of Futures representing the tasks, in the same
+ * sequential order as produced by the iterator for the given
+ * task list. If the operation did not time out, each task will
+ * have completed. If it did time out, some of these tasks will
+ * not have completed.
+ * @throws InterruptedException if interrupted while waiting, in
+ * which case unfinished tasks are cancelled.
+ * @throws NullPointerException if tasks, any of its elements, or
+ * unit are <tt>null</tt>
+ * @throws RejectedExecutionException if any task cannot be scheduled
+ * for execution
+ */
+ <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit, ManagedTaskListener taskListener)
+ throws InterruptedException;
+
+ /**
+ * This method has the same semantics as
+ * {@link ExecutorService#invokeAny(java.util.Collection)}
+ * but also includes the ability to be notified when each task's lifecycle changes.
+ *
+ * Executes the given tasks, returning the result
+ * of one that has completed successfully (i.e., without throwing
+ * an exception), if any do. Upon normal or exceptional return,
+ * tasks that have not completed are cancelled.
+ * The results of this method are undefined if the given
+ * collection is modified while this operation is in progress.
+ * @param tasks the collection of tasks
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return The result returned by one of the tasks.
+ * @throws InterruptedException if interrupted while waiting
+ * @throws NullPointerException if tasks or any of its elements
+ * are <tt>null</tt>
+ * @throws IllegalArgumentException if tasks empty
+ * @throws ExecutionException if no task successfully completes
+ * @throws RejectedExecutionException if tasks cannot be scheduled
+ * for execution
+ */
+ <T> T invokeAny(Collection<Callable<T>> tasks, ManagedTaskListener taskListener)
+ throws InterruptedException, ExecutionException;
+
+ /**
+ * This method has the same semantics as
+ * {@link ExecutorService#invokeAny(java.util.Collection, long, java.util.concurrent.TimeUnit)}
+ * but also includes the ability to be notified when each task's lifecycle changes.
+ *
+ * @param tasks the collection of tasks
+ * @param timeout the maximum time to wait
+ * @param unit the time unit of the timeout argument
+ * @return The result returned by one of the tasks.
+ * @throws InterruptedException if interrupted while waiting
+ * @throws NullPointerException if tasks, any of its elements, or
+ * unit are <tt>null</tt>
+ * @throws TimeoutException if the given timeout elapses before
+ * any task successfully completes
+ * @throws ExecutionException if no task successfully completes
+ * @throws RejectedExecutionException if tasks cannot be scheduled
+ * for execution
+ */
+ <T> T invokeAny(Collection<Callable<T>> tasks,
+ long timeout, TimeUnit unit, ManagedTaskListener taskListener)
+ throws InterruptedException, ExecutionException, TimeoutException;
+
+
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedExecutorService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,206 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+
+
+/**
+ * A manageable version of a {@link java.util.concurrent.ScheduledExecutorService}.<p>
+ *
+ * A ManagedScheduledExecutorService provides methods for submitting delayed or
+ * periodic tasks for execution in a managed environment.
+ * Implementations of the ManagedScheduledExecutorService are
+ * provided by a Java™ EE Product Provider. Application Component Providers
+ * use the Java Naming and Directory Interface™ (JNDI) to look-up instances of one
+ * or more ManagedExecutorService objects using resource environment references.<p>
+ *
+ * The Concurrency Utilities for Java™ EE specification describes several
+ * behaviors that a ManagedScheduledExecutorService can implement. The Application
+ * Component Provider and Deployer identify these requirements and map the
+ * resource environment reference appropriately.<p>
+ *
+ * Tasks run within the application component context that either
+ * submitted the task or created the ManagedExecutorService instance (server-managed or component-managed).
+ * All tasks run without an explicit transaction (they do not enlist in the application
+ * component's transaction). If a transaction is required, use a
+ * {@link javax.transaction.UserTransaction} instance. A UserTransaction instance is
+ * available in JNDI using the name: "java:comp/UserTransaction"<p>
+ *
+ * Example:<pre>
+ * public run() {
+ * // Begin of task
+ * InitialContext ctx = new InitialContext();
+ * UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
+ * ut.begin();
+ *
+ * // Perform transactional business logic
+ *
+ * ut.commit();
+ * }</PRE>
+ *
+ * Asynchronous tasks are typically submitted to the ManagedScheduledExecutorService using one
+ * of the <code>submit</code> or <code>schedule</code>methods, each of which return a {@link java.util.concurrent.Future}
+ * instance. The Future represents the result of the task and can also be used to
+ * check if the task is complete or wait for its completion.<p>
+ *
+ * If the task is cancelled, the result fo the task is a
+ * {@link java.util.concurrent.CancellationException} exception. If the task is unable
+ * to run due to start due to a reason other than cancellation, the result is a
+ * {@link javax.util.concurrent.AbortedException} exception. If the task is scheduled
+ * with a {@link javax.util.concurrent.Trigger} and the Trigger forces the task to be skipped,
+ * the result will be a {@link javax.util.concurrent.SkippedException} exception.<p>
+ *
+ * Tasks can be scheduled to run periodically using the <code>schedule</code> methods that
+ * take a <code>Trigger</code> as an argument and the <code>scheduleAtFixedRate</code> and
+ * <code>scheduleWithFixedDelay</code> methods. The result of the <code>Future</code> will
+ * be represented by the currently scheduled or running instance of the task. Future and past executions
+ * of the task are not represented by the Future. The state of the <code>Future</code> will therefore change
+ * and multiple results are expected.<p>
+ *
+ * For example, if a task is repeat, the lifecycle of the task would be:<br>
+ * (Note: See {@link javax.util.concurrent.ManagedTaskListener} for task lifecycle management details.)<p>
+ *
+ * <table>
+ * <tr><td valign="top"><strong>Sequence</strong></td><td valign="top"><strong>State</strong></td><td valign="top"><strong>Action</strong></td><td valign="top"><strong>Listener</strong></td><td valign="top"><strong>Next state</strong></td></tr>
+ * <tr><td valign="top">1A.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2A.</td><td valign="top">Submitted</td><td valign="top">About to call run()</td><td valign="top">taskStarting</td><td valign="top">Started</td></tr>
+ * <tr><td valign="top">3A.</td><td valign="top">Started</td><td valign="top">Exit run()</td><td valign="top">taskDone</td><td valign="top">Reschedule</td></tr>
+ * <tr><td valign="top">1B.</td><td valign="top">Reschedule</td><td valign="top"></td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2B.</td><td valign="top">Submitted</td><td valign="top">About to call run()</td><td valign="top">taskStarting</td><td valign="top">Started</td></tr>
+ * <tr><td valign="top">3B.</td><td valign="top">Started</td><td valign="top">Exit run()</td><td valign="top">taskDone</td><td valign="top">Reschedule</td></tr>
+ * </table>
+ *
+ *
+ *
+ */
+public interface ManagedScheduledExecutorService extends ScheduledExecutorService, ManagedExecutorService
+{
+ /**
+ * Creates and executes a task based on a Trigger. The Trigger determines
+ * when the task should run and how often.
+ *
+ * @param command the task to execute.
+ * @param trigger the trigger that determines when the task should fire.
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will return <tt>null</tt>
+ * upon completion.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if command is null
+ */
+ public ScheduledFuture<?> schedule(Runnable command, Trigger trigger, ManagedTaskListener taskListener);
+
+ /**
+ * Creates and executes a task based on a Trigger. The Trigger determines
+ * when the task should run and how often.
+ *
+ * @param callable the function to execute.
+ * @param trigger the trigger that determines when the task should fire.
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return a ScheduledFuture that can be used to extract result or cancel.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if callable is null
+ */
+ public <V> ScheduledFuture<V> schedule(Callable<V> callable, Trigger trigger, ManagedTaskListener taskListener);
+
+ /**
+ * Creates and executes a one-shot action that becomes enabled
+ * after the given delay.
+ * @param command the task to execute.
+ * @param delay the time from now to delay execution.
+ * @param unit the time unit of the delay parameter.
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will return <tt>null</tt>
+ * upon completion.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if command is null
+ */
+ public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit, ManagedTaskListener taskListener);
+
+ /**
+ * Creates and executes a ScheduledFuture that becomes enabled after the
+ * given delay.
+ * @param callable the function to execute.
+ * @param delay the time from now to delay execution.
+ * @param unit the time unit of the delay parameter.
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return a ScheduledFuture that can be used to extract result or cancel.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if callable is null
+ */
+ public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit, ManagedTaskListener taskListener);
+
+ /**
+ * Creates and executes a periodic action that becomes enabled first
+ * after the given initial delay, and subsequently with the given
+ * period; that is executions will commence after
+ * <tt>initialDelay</tt> then <tt>initialDelay+period</tt>, then
+ * <tt>initialDelay + 2 * period</tt>, and so on.
+ * If any execution of the task
+ * encounters an exception, subsequent executions are suppressed.
+ * Otherwise, the task will only terminate via cancellation or
+ * termination of the executor.
+ * @param command the task to execute.
+ * @param initialDelay the time to delay first execution.
+ * @param period the period between successive executions.
+ * @param unit the time unit of the initialDelay and period parameters
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will throw an exception upon
+ * cancellation.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if command is null
+ * @throws IllegalArgumentException if period less than or equal to zero.
+ */
+ public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit, ManagedTaskListener taskListener);
+
+ /**
+ * Creates and executes a periodic action that becomes enabled first
+ * after the given initial delay, and subsequently with the
+ * given delay between the termination of one execution and the
+ * commencement of the next. If any execution of the task
+ * encounters an exception, subsequent executions are suppressed.
+ * Otherwise, the task will only terminate via cancellation or
+ * termination of the executor.
+ * @param command the task to execute.
+ * @param initialDelay the time to delay first execution.
+ * @param delay the delay between the termination of one
+ * execution and the commencement of the next.
+ * @param unit the time unit of the initialDelay and delay parameters
+ * @param taskListener the ManagedTaskListener instance to receive a task's lifecycle events.
+ * @return a Future representing pending completion of the task,
+ * and whose <tt>get()</tt> method will throw an exception upon
+ * cancellation.
+ * @throws RejectedExecutionException if task cannot be scheduled
+ * for execution.
+ * @throws NullPointerException if command is null
+ * @throws IllegalArgumentException if delay less than or equal to zero.
+ */
+ public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit, ManagedTaskListener taskListener);
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedScheduledExecutorService.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,136 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.concurrent.Future;
+
+
+
+/**
+ * A ManagedTaskListener is used to monitor the state of a task's Future.
+ * It can be registered with a {@link javax.util.concurrent.ManagedExecutorService} using the
+ * <code>submit</code> methods and will be invoked when the state of the Future changes.
+ * Each listener method will run with the same context in which the task runs.
+ * The listener becomes a Contextual Task. All listeners run without an explicit transaction (they do not enlist in the application
+ * component's transaction). If a transaction is required, use a
+ * {@link javax.transaction.UserTransaction} instance.<p>
+ *
+ * Each listener instance will be invoked within the same process in which the listener was registered.
+ * If a single listener is submitted to multiple ManagedExecutorService instances, the
+ * listener object may be invoked concurrently by multiple threads.<p>
+ *
+ * Each listener method supports a minimum quality of service of at-most-once. A listener is not
+ * guaranteed to be invoked due to a process failure or termination.
+ *
+ * <b>State Transition Diagram</b>
+ * The following state transition figure and tables describe
+ * the possible task lifecycle events that can occur when a
+ * ManagedTaskListener is associated with a task. Each method is invoked
+ * when the state of the future moves from one state to another.<p>
+ * <img src="doc-files/TaskListener_StateDiagram.gif"><p>
+ *
+ * <b>A. The task runs normally:</b>
+ * <table>
+ * <tr><td valign="top"><strong><u>Sequence</u></strong></td><td valign="top"><strong><u>State</u></strong></td><td valign="top"><strong><u>Action</u></strong></td><td valign="top"><strong><u>Listener</u></strong></td><td valign="top"><strong><u>Next state</u></strong></td></tr>
+ * <tr><td valign="top">1.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2.</td><td valign="top">Submitted</td><td valign="top">About to call run()</td><td valign="top">taskStarting</td><td valign="top">Started</td></tr>
+ * <tr><td valign="top">3.</td><td valign="top">Started</td><td valign="top">Exit run()</td><td valign="top">taskDone</td><td valign="top">Done</td></tr>
+ * </table><p>
+ *
+ * <b>B. The task is cancelled during taskSubmitted():</b>
+ * <table>
+ * <tr><td valign="top"><strong><u>Sequence</u></strong></td><td valign="top"><strong><u>State</u></strong></td><td valign="top"><strong><u>Action</u></strong></td><td valign="top"><strong><u>Listener</u></strong></td><td valign="top"><strong><u>Next state</u></strong></td></tr>
+ * <tr><td valign="top">1.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted<br>Future is cancelled.</td><td valign="top">Cancelling</td></tr>
+ * <tr><td valign="top">2.</td><td valign="top">Cancelling</td><td valign="top"> </td><td valign="top">taskAborted</td><td valign="top">Cancelled</td></tr>
+ * <tr><td valign="top">3.</td><td valign="top">Cancelled</td><td valign="top"> </td><td valign="top">taskDone</td><td valign="top">Done</td></tr>
+ * </table><p>
+ *
+ * <b>C. The task is cancelled or aborted after submitted, but before started:</b>
+ * <table>
+ * <tr><td valign="top"><strong><u>Sequence</u></strong></td><td valign="top"><strong><u>State</u></strong></td><td valign="top"><strong><u>Action</u></strong></td><td valign="top"><strong><u>Listener</u></strong></td><td valign="top"><strong><u>Next state</u></strong></td></tr>
+ * <tr><td valign="top">1.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2.</td><td valign="top">Submitted</td><td valign="top">cancel() or abort</td><td valign="top">taskAborted</td><td valign="top">Cancelled</td></tr>
+ * <tr><td valign="top">3.</td><td valign="top">Cancelled</td><td valign="top"> </td><td valign="top">taskDone</td><td valign="top">Done</td></tr>
+ * </table><p>
+ *
+ * <b>D. The task is cancelled when it is starting:</b>
+ * <table>
+ * <tr><td valign="top"><strong><u>Sequence</u></strong></td><td valign="top"><strong><u>State</u></strong></td><td valign="top"><strong><u>Action</u></strong></td><td valign="top"><strong><u>Listener</u></strong></td><td valign="top"><strong><u>Next state</u></strong></td></tr>
+ * <tr><td valign="top">1.</td><td valign="top">None</td><td valign="top">submit()</td><td valign="top">taskSubmitted</td><td valign="top">Submitted</td></tr>
+ * <tr><td valign="top">2.</td><td valign="top">Submitted</td><td valign="top">About to call run()</td><td valign="top">taskStarting<br>Future is cancelled.</td><td valign="top">Cancelling</td></tr>
+ * <tr><td valign="top">3.</td><td valign="top">Cancelling</td><td valign="top"> </td><td valign="top">taskAborted</td><td valign="top">Cancelled</td></tr>
+ * <tr><td valign="top">4.</td><td valign="top">Cancelled</td><td valign="top"> </td><td valign="top">taskDone</td><td valign="top">Done</td></tr>
+ * </table>
+ */
+public interface ManagedTaskListener
+{
+ /**
+ * Called after the task has been submitted to the Executor.
+ * The task will not enter the starting state until the taskSubmitted
+ * listener has completed. This method may be called from
+ * the same thread that the task was submitted with. <p>
+ *
+ * This event does not indicate that the task has been scheduled for execution.
+ *
+ * @param future the future instance that was created when the task was submitted.
+ * The <code>Future.get()</code> methods should not be used within the scope
+ * of this listener method, as they may cause deadlocks.
+ * @param executor the executor used to run the associated Future.
+ */
+ void taskSubmitted(Future<?> future, ManagedExecutorService executor);
+
+ /**
+ * Called when a tasks Future has been cancelled anytime
+ * during the life of a task. This method may be called after taskDone().
+ *
+ * The <code>Future.isCancelled()</code> method returns false if the task was aborted
+ * through another means other than Future.cancel(). The Future.get() method will throw
+ * an exception that will represent the cause of the cancellation:
+ * <ul>
+ * <li>{@link java.util.concurrent.CancellationException} if the task was cancelled,
+ * <li>{@link javax.util.concurrent.SkippedException} if the task was skipped or
+ * <li>{@link javax.util.concurrent.AbortedException} if the task failed to start for another reason.
+ * </ul>
+ * The <code>AbortedException#getCause()</code> method will return the exception
+ * that caused the task to fail to start.
+ *
+ * @param future the future instance that was created when the task was submitted.
+ * @param executor the executor used to run the associated Future.
+ */
+ void taskAborted(Future<?> future, ManagedExecutorService executor, Throwable exception);
+
+ /**
+ * Called when a submitted task has completed running, successful or otherwise after
+ * submitted.
+ * @param future the future instance that was created when the task was submitted.
+ * @param executor the executor used to run the associated Future.
+ */
+ void taskDone(Future<?> future, ManagedExecutorService executor, Throwable exception);
+
+ /**
+ * Called when a task is about to start running.<p>
+ *
+ * This method may be called from the same thread that the task was submitted with.
+ *
+ * @param future the future instance that was created when the task was submitted.
+ * The <code>Future.get()</code> methods should not be used within the scope
+ * of this listener method, as they may cause deadlocks.
+ * @param executor the executor used to run the associated Future.
+ */
+ void taskStarting(Future<?> future, ManagedExecutorService executor);
+
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedTaskListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,79 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * A manageable version of a {@link java.util.concurrent.ThreadFactory}.<p>
+ *
+ * A ManagedThreadFactory provides a method for creating threads for execution
+ * in a managed environment. Implementations of the ManagedThreadFactory are
+ * provided by a Java™ EE Product Provider. Application Component Providers
+ * use the Java Naming and Directory Interface™ (JNDI) to look-up instances of one
+ * or more ManagedThreadFactory objects using resource environment references.<p>
+ *
+ * The Concurrency Utilities for Java™ EE specification describes several
+ * behaviors that a ManagedThreadFactory can implement. The Application
+ * Component Provider and Deployer identify these requirements and map the
+ * resource environment reference appropriately.<p>
+ *
+ * The Runnable task that is allocated to the new thread using the
+ * {@link java.util.concurrent.ThreadFactory#newThread(java.lang.Runnable)} method
+ * will run with the application component context of the component instance
+ * that created (looked-up) this ManagedThreadFactory instance.<p>
+ *
+ * The task runs without an explicit transaction (they do not enlist in the application
+ * component's transaction). If a transaction is required, use a
+ * {@link javax.transaction.UserTransaction} instance. A UserTransaction instance is
+ * available in JNDI using the name: "java:comp/UserTransaction"<p>
+ *
+ * Example:<pre>
+ * public run() {
+ * // Begin of task
+ * InitialContext ctx = new InitialContext();
+ * UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction");
+ * ut.begin();
+ *
+ * // Perform transactional business logic
+ *
+ * ut.commit();
+ * }</PRE>
+ *
+ * A ManagedThreadFactory can be used with Java SE ExecutorService implementations directly.<p>
+ *
+ * Example:<pre>
+ * /**
+ * * Create a ThreadPoolExecutor using a ManagedThreadFactory.
+ * * Resource Mappings:
+ * * type: javax.util.concurrent.ManagedThreadFactory
+ * * jndi-name: concurrent/tf/DefaultThreadFactory
+ * */
+ * public ExecutorService getManagedThreadPool() {
+ * InitialContext ctx = new InitialContext();
+ * ManagedThreadFactory tf = (ManagedThreadFactory)
+ * ctx.lookup("java:comp/env/concurrent/tf/DefaultThreadFactory");
+ *
+ * // All threads will run as part of this application component.
+ * return new ThreadPoolExecutor(5, 10, 5, TimeUnit.SECONDS,
+ * new ArrayBlockingQueue<Runnable>(10), tf);
+ * }
+ * </pre>
+ */
+public interface ManagedThreadFactory extends ThreadFactory {
+
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/ManagedThreadFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,80 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Exception indicating that the result of a value-producing task, cannot be retrieved because the
+ * task run was skipped. A task can be skipped if the {@link Trigger#skipRun(Future, Date)}
+ * method returns false or if it throws an unchecked exception.<p>
+ *
+ * Use the {@link java.lang.Throwable#getCause()} method to determine if an unchecked exception was
+ * thrown from the Trigger.
+ */
+public class SkippedException extends ExecutionException {
+
+ private static final long serialVersionUID = 6962107961025815578L;
+
+ /**
+ * Constructs an SkippedException with <code>null</code> as its detail message.
+ * The cause is not initialized, and may subsequently be initialized by a call to
+ * {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
+ */
+ public SkippedException() {
+ super();
+ }
+
+ /**
+ * Constructs an SkippedException exception with the specified detail message.<p>
+ *
+ * The cause is not initialized, and may subsequently be initialized by a call to
+ * {@link java.lang.Throwable#initCause(java.lang.Throwable)}.
+ *
+ * @param message the detail message (which is saved for later retrieval by the {@link java.lang.Throwable#getMessage()} method).
+ */
+ public SkippedException(String message) {
+ super(message);
+ }
+
+ /**
+ * Constructs an SkippedException exception with the specified detail message and cause.<p>
+ *
+ * Note that the detail message associated with cause is not automatically incorporated in
+ * this exception's detail message.
+ *
+ * @param message the detail message (which is saved for later retrieval by the {@link java.lang.Throwable#getMessage()} method).
+ * @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
+ * (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
+ */
+ public SkippedException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs an SkippedException exception with the specified cause and a
+ * detail message of (cause==null ? null : cause.toString())
+ * (which typically contains the class and detail message of cause).
+ *
+ * @param cause the cause (which is saved for later retrieval by the {@link java.lang.Throwable#getCause()} method).
+ * (A null value is permitted, and indicates that the cause is nonexistent or unknown.)
+ */
+ public SkippedException(Throwable cause) {
+ super(cause);
+ }
+
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/SkippedException.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java (added)
+++ geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java Fri Mar 7 11:56:14 2008
@@ -0,0 +1,127 @@
+/**
+ * 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 javax.util.concurrent;
+
+import java.util.Date;
+import java.util.concurrent.Future;
+
+/**
+ * Triggers allow application developers to plug in rules
+ * for when and how often a task should run.
+ * The trigger can be as simple as a single, absolute date-time or can include
+ * Java™ EE business calendar logic.
+ *
+ * A Trigger implementation is created by the application developer
+ * (or may be supplied to the application externally) and is registered
+ * with a task when it is submitted to a {@link javax.util.concurrent.ManagedScheduledExecutorService}
+ * using any of the <code>schedule</code> methods.
+ *
+ * Each method will run with the same context in which the task runs.
+ * The Trigger becomes a Contextual Task.<p>
+ *
+ * Each Trigger instance will be invoked within the same process in which it was registered.<p>
+ *
+ * Example:<pre>
+ * /**
+ * * A trigger that only returns a single date.
+ * */
+ * public class SingleDateTrigger implements Trigger {
+ * private Date fireTime;
+ *
+ * public TriggerSingleDate(Date newDate) {
+ * fireTime = newDate;
+ * }
+ *
+ * public Date getNextRunTime(
+ * Future lastFuture, Date baseTime, Date lastActualRunTime,
+ * Date lastScheduledRunTime, Date lastCompleteTime) {
+ *
+ * if(baseTime.after(fireTime)) {
+ * return null;
+ * }
+ * return fireTime;
+ * }
+ *
+ * public boolean skipRun(Future lastFuture, Date scheduledRunTime) {
+ * return scheduledRunTime.after(fireTime);
+ * }
+ * }
+ *
+ * /**
+ * * A fixed-rate trigger that will skip any runs if
+ * * the latencyAllowance threshold is exceeded (the task
+ * * ran too late).
+ * */
+ * public class TriggerFixedRateLatencySensitive implements Trigger {
+ * private Date startTime;
+ * private long delta;
+ * private long latencyAllowance;
+ *
+ * public TriggerFixedRateLatencySensitive(Date startTime, long delta, long latencyAllowance) {
+ * this.startTime = startTime;
+ * this.delta = delta;
+ * this.latencyAllowance = latencyAllowance;
+ * }
+ *
+ * public Date getNextRunTime(Future lastFuture, Date baseTime, Date lastActualRunTime, Date lastScheduledRunTime, Date lastCompleteTime) {
+ * if(lastActualRunTime==null) {
+ * return startTime;
+ * }
+ * return new Date(lastScheduledRunTime.getTime() + delta);
+ * }
+ *
+ * public boolean skipRun(Future lastFuture, Date scheduledRunTime) {
+ * return System.currentTimeMillis() - scheduledRunTime.getTime() > latencyAllowance;
+ * }
+ * }
+ *
+ * </pre>
+ *
+ */
+public interface Trigger {
+
+ /**
+ * Retrieve the next time that the task should run after.
+ *
+ * @param lastFuture the state of the Future after the last run.
+ * This value will be null if the task has not yet run.
+ * @param submitTime the time in which the task was originally submitted.
+ * @param lastActualRunTime the time in which the last task actually ran.
+ * This value will be null if the task has not yet run.
+ * @param lastScheduledRunTime the time in which the last task was scheduled to run.
+ * This value will be null if the task has not yet run.
+ * @param lastCompleteTime the time in which the last task completed.
+ * This value will be null if the task has not yet run.
+ * @return the date/time in which the next task iteration should execute on or after.
+ */
+ Date getNextRunTime(Future<?> lastFuture, Date submitTime, Date lastActualRunTime, Date lastScheduledRunTime, Date lastCompleteTime);
+
+ /**
+ * Return true if this run instance should be skipped.<p>
+ *
+ * This is useful if the task shouldn't run because it is late or if the task is
+ * paused or suspended.<p>
+ *
+ * Once this task is skipped, the state of it's Future's result will throw a {@link SkippedException}.
+ * Unchecked exceptions will be wrapped in a SkippedException.
+ *
+ * @param scheduledRunTime the date/time that the task was originally scheduled to run.
+ *
+ * @return true if the task should be skipped and rescheduled.
+ */
+ boolean skipRun(Future<?> lastFuture, Date scheduledRunTime);
+}
Propchange: geronimo/sandbox/concurrent/geronimo-concurrent_spec/src/main/java/javax/util/concurrent/Trigger.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: geronimo/sandbox/concurrent/geronimo.trunk.patch
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/geronimo.trunk.patch?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/geronimo.trunk.patch (added)
+++ geronimo/sandbox/concurrent/geronimo.trunk.patch Fri Mar 7 11:56:14 2008
@@ -0,0 +1,64 @@
+Index: plugins/j2ee/j2ee-deployer/src/main/plan/plan.xml
+===================================================================
+--- plugins/j2ee/j2ee-deployer/src/main/plan/plan.xml (revision 633583)
++++ plugins/j2ee/j2ee-deployer/src/main/plan/plan.xml (working copy)
+@@ -124,7 +124,7 @@
+ <name>ResourceRefBuilder</name>
+ </pattern>
+ <pattern>
+- <name>AdminObjectRefBuilder</name>
++ <name>ManagedResourceRefBuilder</name>
+ </pattern>
+ <pattern>
+ <name>EnvironmentEntryBuilder</name>
+Index: assemblies/geronimo-jetty6-javaee5/pom.xml
+===================================================================
+--- assemblies/geronimo-jetty6-javaee5/pom.xml (revision 633583)
++++ assemblies/geronimo-jetty6-javaee5/pom.xml (working copy)
+@@ -567,6 +567,21 @@
+ <version>${version}</version>
+ <type>car</type>
+ </dependency>
++
++ <dependency>
++ <groupId>org.apache.geronimo.configs</groupId>
++ <artifactId>concurrent</artifactId>
++ <version>${version}</version>
++ <type>car</type>
++ </dependency>
++
++ <dependency>
++ <groupId>org.apache.geronimo.configs</groupId>
++ <artifactId>concurrent-deployer</artifactId>
++ <version>${version}</version>
++ <type>car</type>
++ </dependency>
++
+ </dependencies>
+
+ <build>
+Index: assemblies/geronimo-tomcat6-javaee5/pom.xml
+===================================================================
+--- assemblies/geronimo-tomcat6-javaee5/pom.xml (revision 633583)
++++ assemblies/geronimo-tomcat6-javaee5/pom.xml (working copy)
+@@ -547,6 +547,20 @@
+ <type>car</type>
+ </dependency>
+
++ <dependency>
++ <groupId>org.apache.geronimo.configs</groupId>
++ <artifactId>concurrent</artifactId>
++ <version>${version}</version>
++ <type>car</type>
++ </dependency>
++
++ <dependency>
++ <groupId>org.apache.geronimo.configs</groupId>
++ <artifactId>concurrent-deployer</artifactId>
++ <version>${version}</version>
++ <type>car</type>
++ </dependency>
++
+ </dependencies>
+
+ <build>
Added: geronimo/sandbox/concurrent/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/sandbox/concurrent/pom.xml?rev=634792&view=auto
==============================================================================
--- geronimo/sandbox/concurrent/pom.xml (added)
+++ geronimo/sandbox/concurrent/pom.xml Fri Mar 7 11:56:14 2008
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+
+<!-- $Rev: 513306 $ $Date: 2008/03/04 19:02:07 $ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.geronimo.plugins</groupId>
+ <artifactId>plugins</artifactId>
+ <version>2.2-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>concurrent</artifactId>
+ <name>Geronimo Plugins, Concurrency Utilities for Java EE</name>
+ <packaging>pom</packaging>
+
+ <description>
+ Implementation of the Concurrency Utilities for Java EE specification.
+ </description>
+
+ <modules>
+ <module>geronimo-concurrent_spec</module>
+ <module>geronimo-concurrent-management</module>
+ <module>geronimo-concurrent-core</module>
+ <module>geronimo-concurrent</module>
+ <module>geronimo-concurrent-builder</module>
+ <module>concurrent</module>
+ <module>concurrent-deployer</module>
+ </modules>
+
+</project>
Propchange: geronimo/sandbox/concurrent/pom.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/concurrent/pom.xml
------------------------------------------------------------------------------
svn:executable =