javax.enterprise.concurrent.ContextService Maven / Gradle / Ivy
Show all versions of javax.enterprise.concurrent-api Show documentation
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2011 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package javax.enterprise.concurrent;
import java.util.Map;
/**
* The ContextService provides methods for creating dynamic proxy objects
* (as defined by {@link java.lang.reflect.Proxy java.lang.reflect.Proxy}) with
* the addition of context typically associated with applications executing in a
* Java™ EE environment.
* Examples of such context are classloading, namespace, security, etc.
*
*
* The proxy objects follow the same rules as defined for the
* {@link java.lang.reflect.Proxy java.lang.reflect.Proxy} class with the following additions:
*
* - The proxy instance will retain the context of the creator's
* thread.
*
- The proxy instance will implement all of the interfaces specified on the
* {@code createContextualProxy} methods.
*
- The object to have a proxy instance created for should not be a
* component managed by the Java™ EE Product Provider, such as a web
* component or an EJB.
*
- All interface method invocations on a proxy instance run in the
* creator's context with the exception of {@code hashCode},
* {@code equals}, {@code toString} and all other methods declared in
* {@link java.lang.Object}.
*
- The proxy instance must implement {@link java.io.Serializable}.
*
- The proxied object instance must implement
* {@link java.io.Serializable} if the proxy instance is serialized.
*
- Execution properties can be stored with the proxy instance. Custom
* property keys must not begin with "javax.enterprise.concurrent.".
*
- Execution properties are to be used for controlling how various contextual
* information is retrieved 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.
*
*
*
* @since 1.0
*/
public interface ContextService {
/**
* An execution property that disables the normal transaction
* suspension and {@code UserTransaction} access from the proxied methods. This is
* useful only when the proxy method is invoked to run on the same thread.
* This property will be ignored when the proxy object is submitted for
* execution asynchronously on a different thread, such as if it is specified
* in the execution properties of a {@link ManagedTask} which is submitted to
* an {@link java.util.concurrent.Executor} or any of its subclasses.
*
* 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.
*
* If "true", the proxied method will run within the transaction (if any) of
* the current thread. A UserTransaction will only be available if it is
* also available in the container thread (for example, a Servlet or Bean
* Managed Transaction EJB).
*
*/
public final String USE_PARENT_TRANSACTION = "javax.enterprise.concurrent.USE_PARENT_TRANSACTION";
/**
* Creates a new contextual object proxy for the input object instance.
*
* Each method invocation will have the context of the application component
* instance that created the contextual object proxy.
*
* The contextual object is useful when developing or using Java™ SE
* threading mechanisms propagating events to other component instances or
* communicating with component instances on different Java processes.
*
* If the application component that created the proxy is not started or
* deployed, all methods on reflected interfaces will throw a
* {@code java.lang.IllegalStateException}.
*
* For example, to execute a Runnable which is contextualized with the
* creator's context using a Java™ SE ExecutorService:
*
*
* public class MyRunnable implements Runnable {
* public void run() {
* System.out.println("MyRunnable.run with Java EE 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");
*
* MyRunnable myRunnableInstance = ...;
*
* Runnable rProxy = ctxService.createContextualProxy(myRunnableInstance, Runnable.class);
*
* ExecutorService exSvc = Executors.newThreadPool(10, threadFactory);
*
* Future f = exSvc.submit(rProxy);
*
*
*
* @param instance the instance of the object to proxy.
* @param intf the interface that the proxy should implement.
* @return a proxy for the input object that implements the specified interface.
* @throws java.lang.IllegalArgumentException - if the instance does not implement the specified
* interface or there is not an accessible default constructor.
*
*/
public T createContextualProxy(T instance, Class intf);
/**
* Creates a new contextual object proxy for the input object instance.
*
* This method is similar to {@code T createContextualProxy(T instance, Class intf)}
* except that this method can be used if the proxy has to support multiple
* interfaces.
*
* Example:
*
*
* public class MyRunnableWork implements Runnable, SomeWorkInterface {
* public void run() {
* System.out.println("MyRunnableWork.run with Java EE Context available.");
* }
* public void someWorkInterfaceMethod() {
* ...
* }
* }
*
* ThreadFactory threadFactory = ...;
*
* ContextService ctxService = ...;
*
* MyRunnableWork myRunnableWorkInstance = ...;
*
* Object proxy = ctxService.createContextualProxy(myRunnableWorkInstance,
* Runnable.class, SomeWorkInterface.class);
*
* // call SomeWorkInterface method on the proxy
* ((SomeWorkInterface) proxy).someWorkInterfaceMethod();
*
* ExecutorService exSvc = Executors.newThreadPool(10, threadFactory);
*
* // submit the proxy as a Runnable to the ExecutorService
* Future f = exSvc.submit( (Runnable)proxy);
*
*
*
* @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 java.lang.IllegalArgumentException - if the instance does not implement
* all the specified interfaces or there is not an accessible default constructor.
*
*/
public Object createContextualProxy(Object instance, Class>... interfaces);
/**
* Creates a new contextual object proxy for the input object instance.
*
* The contextual object is useful when developing or using Java™ SE
* threading mechanisms propagating events to other component instances or
* communicating with component instances on different Java processes.
*
* If the application component that created the proxy is not started or
* deployed, all methods on reflected interfaces will throw a
* {@code java.lang.IllegalStateException}.
*
* This method accepts a {@code Map} 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.
*
*
* For example, to call a Message Driven Bean (MDB) with the sender's
* context, but within the MDB's transaction:
*
*
* 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 through execution properties
* Map<String, String> execProps = new HashMap<>();
* execProps.put("vendor_a.security.tokenexpiration", "15000");
* // Specify that contextual object should run inside the current
* // transaction. If we have a failure, we don't want to consume
* // the message.
* execProps.put(ContextService.USE_PARENT_TRANSACTION, "true");
*
* ProcessMessage msgProcessor =
* ctxSvc.createContextualProxy(new MessageProcessor(), execProps,
* ProcessMessage.class);
*
* 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 contextual object from the message.
* ObjectMessage omsg = (ObjectMessage)msg;
* ProcessMessage msgProcessor = (ProcessMessage)omsg.getObject();
*
* // 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.
*
* }
* }
*
*
*
* @param instance the instance of the object to proxy.
* @param executionProperties the properties to use when creating and running the context
* object.
* @param intf the interface that the proxy should implement.
* @return a proxy for the input object that implements the specified interface.
*
* @throws java.lang.IllegalArgumentException - if the instance does not
* implement the specified interface or there is not an accessible
* default constructor.
*/
public T createContextualProxy(T instance,
Map executionProperties,
Class intf);
/**
* Creates a new contextual object proxy for the input object instance.
*
* This method is similar to {@code T createContextualProxy(T instance, Map executionProperties, Class intf)}
* except that this method can be used if the proxy has to support multiple
* interfaces.
*
* @param instance the instance of the object to proxy.
* @param executionProperties the properties to use when creating and running the context
* object.
* @param interfaces the interfaces that the proxy should implement.
* @return a proxy for the input object that implements all of the specified
* interfaces.
*
* @throws java.lang.IllegalArgumentException - if the instance does not
* implement all the specified interfaces or there is not an
* accessible default constructor.
*/
public Object createContextualProxy(Object instance,
Map executionProperties,
Class>... interfaces);
/**
* Gets the current execution properties on the context proxy instance.
*
* @param contextualProxy the contextual proxy instance to retrieve the execution properties.
* @return A copy of the current contextual object execution properties, or null if
* the contextualProxy is created without specifying any execution properties.
*
* @throws java.lang.IllegalArgumentException thrown if the input contextualProxy is not a valid
* contextual object proxy created with the
* {@code createContextualProxy} method.
*/
public Map getExecutionProperties(Object contextualProxy);
}