Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDI Lite packaging, deployment and lifecycle specification #546

Merged
merged 6 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@
* <li>{@link Validation @Validation}</li>
* </ul>
* <p>
* Extension methods may declare arbitrary number of parameters. Which parameters may be declared depends
* on the particular execution phase and is documented in the corresponding extension annotation.
* All the parameters will be provided by the container when the extension method is executed.
* Extension methods may declare arbitrary number of parameters. In each execution phase, different types
* of parameters may be declared, as documented in the corresponding extension annotation. All the parameters
* will be provided by the container when the extension method is invoked. If an extension method declares
* a parameter of a type unsupported in the execution phase, the container treats it as a deployment problem.
* <p>
* Extension methods may be assigned a priority using {@link jakarta.annotation.Priority @Priority}.
* Extension methods with smaller priority values are invoked first. Extension methods without specified priority
* have a default priority of {@link jakarta.interceptor.Interceptor.Priority#APPLICATION Priority.APPLICATION} + 500.
* If two extension methods have equal priority, the ordering between them is undefined. Note that priority
* only affects order of extension methods in a single phase.
* <p>
* If the extension declares multiple extension methods, they are all invoked on the same instance of the class.
* For each build compatible extension, the container creates a single instance. All extension methods
* are invoked on the same instance.
* <p>
* When extension methods are invoked, a CDI container does not have to be running, so calling {@code CDI.current()}
* from an extension method, or attempting to access a running CDI container in any other way, results in
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* <p>The build compatible extension SPI. See:</p>
*
* <ul>
* <li>{@link jakarta.enterprise.inject.build.compatible.spi.BuildCompatibleExtension}</li>
* <li>{@link jakarta.enterprise.inject.build.compatible.spi.Discovery}</li>
* <li>{@link jakarta.enterprise.inject.build.compatible.spi.Enhancement}</li>
* <li>{@link jakarta.enterprise.inject.build.compatible.spi.Registration}</li>
* <li>{@link jakarta.enterprise.inject.build.compatible.spi.Synthesis}</li>
* <li>{@link jakarta.enterprise.inject.build.compatible.spi.Validation}</li>
* </ul>
*/
package jakarta.enterprise.inject.build.compatible.spi;
4 changes: 2 additions & 2 deletions spec/src/main/asciidoc/architecture.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ For example, the container might be a Jakarta EE container or an embeddable Jaka
<<injection_and_resolution>>, <<contexts>>, <<lifecycle>>, <<events>> and <<interceptor_resolution>> define the semantics and behavior of the services, the responsibilities of the container implementation and the APIs used by the application to interact directly with the container.
{cdi_full} adds <<decorators>>.

<<packaging_deployment_lite>> and <<packaging_deployment>> defines how applications that use the services defined by this specification must be packaged into bean archives, and the responsibilities of the container implementation at application initialization time.
<<packaging_deployment>> and <<packaging_deployment_full>> defines how applications that use the services defined by this specification must be packaged into bean archives, and the responsibilities of the container implementation at application initialization time.

<<spi>>, <<spi_lite>>, <<contextual>> and <<context>> define an SPI that allows portable extensions to integrate with the container.
<<spi_lite>>, <<spi_full>>, <<contextual>> and <<context>> define an SPI that allows portable extensions to integrate with the container.

=== Relationship to other specifications

Expand Down
4 changes: 2 additions & 2 deletions spec/src/main/asciidoc/cdi-spec.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ include::core/decorators.asciidoc[]

include::core/events_full.asciidoc[]

include::core/spi.asciidoc[]
include::core/spi_full.asciidoc[]

include::core/packagingdeployment.asciidoc[]
include::core/packagingdeployment_full.asciidoc[]

:leveloffset: -1

Expand Down
5 changes: 2 additions & 3 deletions spec/src/main/asciidoc/core/definition.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -528,9 +528,8 @@ For example, the following annotation declares a "business process scope":
public @interface BusinessProcessScoped {}
----

Custom scopes are normally defined by portable extensions, which must also provide a _context object_, as defined in <<context>>, that implements the custom scope.

// TODO mention build compatible extensions, as they require providing a _class_, not an object
Custom scopes are normally defined by extensions, which must also provide an implementation of the `Context` interface, as defined in <<context>>, that implements the custom scope.
Portable extensions provide a _context object_ directly, while build compatible extensions provide a class that the container has to instantiate to obtain the context object.

[[declaring_bean_scope]]

Expand Down
6 changes: 0 additions & 6 deletions spec/src/main/asciidoc/core/events.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,6 @@ An observer method has an event qualifier if it has an observed event qualifier

If the runtime type of the event object contains an unresolvable type variable, the container must throw an `IllegalArgumentException`.

For a custom implementation of the `ObserverMethod` interface defined in <<observer_method>>, the container must call `getObservedType()` and `getObservedQualifiers()` to determine the observed event type and qualifiers, and `isAsync()` to determine whether the observer is asynchronous or synchronous.
// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions?

[[observers_assignability]]

==== Assignability of type variables, raw and parameterized types
Expand Down Expand Up @@ -537,9 +534,6 @@ The `BeanManager.getEvent()` or `Event.fire()` method rethrows the exception.
If the exception is a checked exception, it is wrapped and rethrown as an (unchecked) `ObserverException`.


For a custom implementation of the `ObserverMethod` interface defined in <<observer_method>>, the container must call `getTransactionPhase()` to determine if the observer method is transactional observer method, and `notify()` which accepts `jakarta.enterprise.inject.spi.EventContext` to invoke the method.
// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions?

[[async_exception]]

==== Handling multiple exceptions thrown during an asynchronous event
Expand Down
15 changes: 15 additions & 0 deletions spec/src/main/asciidoc/core/events_full.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ In addition to rules defined in <<builtin_event>>, the following rule applies.

The built-in implementation must be a passivation capable dependency, as defined in <<passivation_capable_dependency>>.

[[observer_resolution_full]]

=== Observer resolution in {cdi_full}

In addition to rules defined in <<observer_resolution>>, the following rule applies.

For a custom implementation of the `ObserverMethod` interface defined in <<observer_method>>, the container must call `getObservedType()` and `getObservedQualifiers()` to determine the observed event type and qualifiers, and `isAsync()` to determine whether the observer is asynchronous or synchronous.

[[observer_methods_full]]

Expand All @@ -33,3 +40,11 @@ In addition to rules defined in <<observes>>, the following rules apply.

Decorators may not declare observer methods.
If a decorator has a method with a parameter annotated `@Observes` or `@ObservesAsync`, the container automatically detects the problem and treats it as a definition error.

[[observer_notification_full]]

=== Observer notification in {cdi_full}

In addition to rules defined in <<observer_notification>>, the following rule applies.

For a custom implementation of the `ObserverMethod` interface defined in <<observer_method>>, the container must call `getTransactionPhase()` to determine if the observer method is transactional observer method, and `notify()` which accepts `jakarta.enterprise.inject.spi.EventContext` to invoke the method.
2 changes: 1 addition & 1 deletion spec/src/main/asciidoc/core/implementation.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The container provides built-in support for injection and contextual lifecycle m

All containers must support managed beans, producer methods and producer fields.

A portable extension, as well as a build compatible extension, may provide other kinds of beans.
Portable extensions and build compatible extensions may provide other kinds of beans.

[[managed_beans]]

Expand Down
5 changes: 2 additions & 3 deletions spec/src/main/asciidoc/core/injectionandresolution.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ The container is not required to support circular chains of dependencies where e

Beans and their clients may be deployed in _modules_ in a module architecture.
In a module architecture, certain modules are considered _bean archives_.
The library may be an explicit bean archive or an implicit bean archive, as defined in <<bean_archive>>.
In {cdi_lite}, libraries that are bean archives are always implicit bean archives.
// TODO this all depends on how we define packaging and deployment for Lite, so this paragraph must be revisited!
In {cdi_lite}, a library that is a bean archive is always an implicit bean archive, as defined in <<bean_archive>>.
Other kinds of bean archives exist in {cdi_full}.

A bean packaged in a certain module is available for injection, lookup and name resolution to classes packaged in some other module if and only if the bean class of the bean is required to be _accessible_ to the other module by the class accessibility requirements of the module architecture.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

In addition to rules defined in <<selection>>, the following rules apply.

A library may be an explicit bean archive or an implicit bean archive, as defined in <<bean_archive_full>>.

An alternative is not available for injection, lookup or name resolution to classes in a module unless the module is a bean archive and the alternative is explicitly _selected_ for the bean archive or the application.

[[declaring_selected_alternatives_full]]
Expand Down
11 changes: 1 addition & 10 deletions spec/src/main/asciidoc/core/interceptors.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,6 @@ If a managed bean has a class-level or method-level interceptor binding, the man

=== Interceptor resolution

This specification extends the Jakarta Interceptors specification and defines:

* the effect of applying `@Nonbinding` to an interceptor binding member, and
* how the interceptor bindings of a custom implementation of the `Interceptor` interface are determined.
This specification extends the Jakarta Interceptors specification and defines the effect of applying `@Nonbinding` to an interceptor binding member.

If any interceptor binding has a member annotated `@jakarta.enterprise.util.Nonbinding`, the member is ignored when performing interceptor resolution, and the method does not need to have the same annotation member value.

For a custom implementation of the `Interceptor` interface defined in <<interceptor>>, the container calls `getInterceptorBindings()` to determine the interceptor bindings of the interceptor and `intercepts()` to determine if the interceptor intercepts a given kind of lifecycle callback or business method.
// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions?

A custom implementation of the `Interceptor` interface may implement the <<prioritized, `Prioritized` interface>> to be enabled for the entire application with a priority value.
// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions?
12 changes: 12 additions & 0 deletions spec/src/main/asciidoc/core/interceptors_full.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,15 @@ Interceptors enabled using `@Priority` are called before interceptors enabled us
An interceptor is said to be *enabled* if it is enabled in at least one bean archive or is listed in the final list of interceptors for the application, as defined in <<after_type_discovery>>.

If an interceptor is enabled for the application and for the bean archive, then the enablement from the bean archive is ignored by the container. The interceptor will only be executed once based on the `@Priority` annotation's invocation chain.

[[interceptor_resolution_full]]

=== Interceptor resolution in {cdi_full}

In addition to rules defined in <<interceptor_resolution>>, the following rules apply.

This specification extends the Jakarta Interceptors specification and defines how the interceptor bindings of a custom implementation of the `Interceptor` interface are determined.

For a custom implementation of the `Interceptor` interface defined in <<interceptor>>, the container calls `getInterceptorBindings()` to determine the interceptor bindings of the interceptor and `intercepts()` to determine if the interceptor intercepts a given kind of lifecycle callback or business method.

A custom implementation of the `Interceptor` interface may implement the <<prioritized, `Prioritized` interface>> to be enabled for the entire application with a priority value.
Loading