jakarta.enterprise.concurrent.ContextServiceDefinition Maven / Gradle / Ivy
/*
* Copyright (c) 2021,2022 Contributors to the Eclipse Foundation
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/
package jakarta.enterprise.concurrent;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
/**
* Defines a {@link ContextService}
* to be registered in JNDI by the container
* under the JNDI name that is specified in the
* {@link #name()} attribute.
*
* Application components can refer to this JNDI name in the
* {@link jakarta.annotation.Resource#lookup() lookup} attribute of a
* {@link jakarta.annotation.Resource} annotation,
*
* {@literal @}ContextServiceDefinition(
* name = "java:app/concurrent/MyContext",
* propagated = APPLICATION,
* unchanged = TRANSACTION,
* cleared = ALL_REMAINING)
* public class MyServlet extends HttpServlet {
* {@literal @}Resource(lookup = "java:app/concurrent/MyContext",
* name = "java:app/concurrent/env/MyContextRef")
* ContextService appContextSvc;
*
*
* Resource environment references in a deployment descriptor
* can similarly specify the lookup-name
,
*
*
* <resource-env-ref>
* <resource-env-ref-name>java:app/env/concurrent/MyContextRef</resource-env-ref-name>
* <resource-env-ref-type>jakarta.enterprise.concurrent.ContextService</resource-env-ref-type>
* <lookup-name>java:app/concurrent/MyContext</lookup-name>
* </resource-env-ref>
*
*
* The {@link #cleared()}, {@link #propagated()}, and {@link #unchanged()}
* attributes enable the application to configure how thread context
* is applied to tasks and actions that are contextualized by the
* ContextService
.
* Constants are provided on this class for context types that are
* defined by the Jakarta EE Concurrency specification.
* In addition to those constants, a Jakarta EE product provider
* may choose to accept additional vendor-specific context types.
* Usage of vendor-specific types will make applications non-portable.
*
* Overlap of the same context type across multiple lists is an error and
* prevents the ContextService
instance from being created.
* If {@link #ALL_REMAINING} is not present in any of the lists, it is
* implicitly appended to the {@link #cleared()} context types.
*
* You can also define a {@code ContextService} with the
* {@code } deployment descriptor element.
* For example,
*
*
* <context-service>
* <name>java:app/concurrent/MyContext</name>
* <cleared>Security</cleared>
* <cleared>Transaction</cleared>
* <propagated>Application</propagated>
* <unchanged>Remaining</unchanged>
* </context-service>
*
*
* If a {@code context-service} and {@code ContextServiceDefinition}
* have the same name, their attributes are merged to define a single
* {@code ContextService} definition, with each attribute that is specified
* in the {@code context-service} deployment descriptor entry taking
* precedence over the corresponding attribute of the annotation.
*
* @since 3.0
*/
@Repeatable(ContextServiceDefinition.List.class)
@Retention(RUNTIME)
@Target(TYPE)
public @interface ContextServiceDefinition {
/**
* JNDI name of the {@link ContextService} instance being defined.
* The JNDI name must be in a valid Jakarta EE namespace,
* such as,
*
*
* - java:comp
* - java:module
* - java:app
* - java:global
*
*
* @return ContextService
JNDI name.
*/
String name();
/**
* Types of context to clear whenever a thread runs the
* contextual task or action. The thread's previous context
* is restored afterward.
*
*
Constants are provided on this class for the context types
* that are defined by the Jakarta EE Concurrency specification.
*
* @return context types to clear.
*/
String[] cleared() default { TRANSACTION };
/**
* Types of context to capture from the requesting thread
* and propagate to a thread that runs the contextual task
* or action.
* The captured context is re-established when threads
* run the contextual task or action, with the respective
* thread's previous context being restored afterward.
*
*
Constants are provided on this class for the context types
* that are defined by the Jakarta EE Concurrency specification.
*
* @return context types to capture and propagate.
*/
String[] propagated() default { ALL_REMAINING };
/**
* Types of context that are left alone when a thread
* runs the contextual task or action.
*
For example, with unchanged = TRANSACTION
* if a transaction is started after a function is
* contextualized, but before the function is run on the same thread,
* the transaction will be active in the contextual function:
*
* Consumer<String, Integer> updateDB = contextService.contextualConsumer(fn);
*
*// later, on another thread
*tx.begin();
*updateDB.accept("java:comp/env/jdbc/ds1");
*//...additional transactional work
*tx.commit();
*
* Constants are provided on this class for the context types
* that are defined by the Jakarta EE Concurrency specification.
*
* @return context types to leave unchanged.
*/
String[] unchanged() default {};
/**
* All available thread context types that are not specified
* elsewhere. This includes thread context types from custom
* {@link jakarta.enterprise.concurrent.spi.ThreadContextProvider ThreadContextProviders}
* that are not specified elsewhere.
*
* For example, to define a ContextService
that
* propagates {@link #SECURITY} context,
* leaves {@link #TRANSACTION} context alone,
* and clears every other context type:
*
* {@literal @}ContextServiceDefinition(
* name = "java:module/concurrent/SecurityContext",
* propagated = SECURITY,
* unchanged = TRANSACTION,
* cleared = ALL_REMAINING)
* public class MyServlet extends HttpServlet ...
*
*/
static final String ALL_REMAINING = "Remaining";
/**
* Context pertaining to the application component or module,
* including its Jakarta EE namespace (such as
* java:comp/env/
) and thread context class loader.
*
* A cleared application context means that the thread is
* not associated with any application component and lacks
* access to the Jakarta EE namespace and thread context class
* loader of the application.
*/
static final String APPLICATION = "Application";
// TODO CDI context is the topic of
// https://github.com/jakartaee/concurrency/issues/105
/**
* Context that controls the credentials that are associated
* with the thread, including the caller subject and
* invocation/RunAs subject.
*
* A cleared security context gives the thread unauthenticated
* subjects.
*/
static final String SECURITY = "Security";
/**
* Context that controls the transaction that is associated
* with the thread.
*
* When cleared transaction context is applied to a thread,
* any global transaction that was previously present there is
* first suspended such that the contextual task or action can
* begin and manage, as permitted by the container, its own new
* {@code jakarta.transaction.UserTransaction}.
* After the contextual task or action completes, the prior
* transaction is resumed on the thread. This is equivalent to
* the execution property, {@link ManagedTask#TRANSACTION} with
* a value of {@link ManagedTask#SUSPEND}.
*
* The execution property, {@link ManagedTask#TRANSACTION},
* if specified, takes precedence over the behavior for
* transaction context that is specified on the resource
* definition annotations.
*
* Jakarta EE providers need not support the propagation
* of transactions to other threads and can reject resource
* definition annotations that include transaction as a
* propagated context.
*/
// TODO the last item above is the topic of
// https://github.com/jakartaee/concurrency/issues/102
// and can be updated accordingly when that capability is added.
static final String TRANSACTION = "Transaction";
/**
* Enables multiple ContextServiceDefinition
* annotations on the same type.
*/
@Retention(RUNTIME)
@Target(TYPE)
public @interface List {
ContextServiceDefinition[] value();
}
}