From 58177d9d574d1e57036324464b98775b06c76832 Mon Sep 17 00:00:00 2001 From: antoinesd Date: Thu, 18 Mar 2021 12:21:55 +0100 Subject: [PATCH 01/11] cdi-468 Split Spec doc to introduce CDI Lite Signed-off-by: antoinesd --- spec/src/main/asciidoc/cdi-spec.asciidoc | 23 +++++++++-- .../main/asciidoc/core/definition.asciidoc | 27 ++++++------ .../asciidoc/core/definition_full.asciidoc | 41 +++++++++++++++++++ spec/src/main/asciidoc/core/events.asciidoc | 5 +++ .../asciidoc/core/implementation.asciidoc | 15 ++++--- .../asciidoc/core/implementation_full.adoc | 3 ++ .../core/injectionandresolution.asciidoc | 5 +++ .../asciidoc/core/scopescontexts.asciidoc | 8 ++++ spec/src/main/asciidoc/core/spi_lite.asciidoc | 8 ++++ spec/src/main/asciidoc/preface.asciidoc | 15 ++++++- 10 files changed, 124 insertions(+), 26 deletions(-) create mode 100644 spec/src/main/asciidoc/core/definition_full.asciidoc create mode 100644 spec/src/main/asciidoc/core/implementation_full.adoc create mode 100644 spec/src/main/asciidoc/core/spi_lite.asciidoc diff --git a/spec/src/main/asciidoc/cdi-spec.asciidoc b/spec/src/main/asciidoc/cdi-spec.asciidoc index e5a0a6ce0..febcaa03a 100644 --- a/spec/src/main/asciidoc/cdi-spec.asciidoc +++ b/spec/src/main/asciidoc/cdi-spec.asciidoc @@ -16,6 +16,8 @@ ifdef::backend-pdf[] :pagenums: endif::[] +:cdi_lite: CDI Lite +:cdi_full: CDI Full @@ -31,28 +33,41 @@ include::architecture.asciidoc[] [[part_1]] = Part I - Core CDI +== {cdi_lite} + +:leveloffset: +1 + include::core/definition.asciidoc[] include::core/implementation.asciidoc[] -include::core/inheritance.asciidoc[] - include::core/injectionandresolution.asciidoc[] include::core/scopescontexts.asciidoc[] include::core/lifecycle.asciidoc[] -include::core/decorators.asciidoc[] - include::core/interceptors.asciidoc[] include::core/events.asciidoc[] +include::core/spi_lite.asciidoc[] + +:leveloffset: -1 + +== {cdi_full} + +:leveloffset: +1 + +include::core/inheritance.asciidoc[] + +include::core/decorators.asciidoc[] + include::core/spi.asciidoc[] include::core/packagingdeployment.asciidoc[] +:leveloffset: -1 [[part_2]] = Part II - CDI in Java SE diff --git a/spec/src/main/asciidoc/core/definition.asciidoc b/spec/src/main/asciidoc/core/definition.asciidoc index 0b41e9827..dafdfd518 100644 --- a/spec/src/main/asciidoc/core/definition.asciidoc +++ b/spec/src/main/asciidoc/core/definition.asciidoc @@ -2,6 +2,11 @@ == Concepts +[NOTE] +==== +This part still contains references to decorators and a few comments that should be moved to the CDI Full "concept" section to add specific features to full +==== + A bean is a source of contextual objects which define application state and/or logic. These objects are called _contextual instances of the bean_. The container creates and destroys these instances and associates them with the appropriate context. @@ -40,7 +45,7 @@ A bean is provided by the container with the following capabilities: * transparent creation and destruction and scoping to a particular context, specified in <> and <>, * scoped resolution by bean type and qualifier annotation type when injected into a Java-based client, as defined by <>, * lifecycle callbacks and automatic injection of other bean instances, specified in <> and <>, -* method interception, callback interception, and decoration, as defined in <> and <>, and +* method interception, callback interception, as defined in <>, and * event notification, as defined in <>. @@ -207,7 +212,7 @@ The container inspects the qualifier annotations and type of the injected attrib An injection point may even specify multiple qualifiers. -Qualifier types are also used as event selectors by event consumers, as defined in <>, and to bind decorators to beans, as specified in <>. +Qualifier types are also used as event selectors by event consumers, as defined in <>. [[builtin_qualifiers]] @@ -464,14 +469,6 @@ For example, an object that represents the current user is represented by a sess @Produces @SessionScoped User getCurrentUser() { ... } ---- -An object that represents an order is represented by a conversation scoped object: - -[source, java] ----- -@ConversationScoped -public class Order { ... } ----- - A list that contains the results of a search screen might be represented by a request scoped object: [source, java] @@ -486,15 +483,14 @@ The set of scope types is extensible. ==== Built-in scope types -There are five standard scope types defined by this specification, all defined in the package `jakarta.enterprise.context`. +There are four standard scope types defined in {cdi_lite}, all defined in the package `jakarta.enterprise.context`. * The container must provide an implementation of the @RequestScoped, @ApplicationScoped and @SessionScoped annotations defined in <>. Note that these standard scopes can be extended by third-party extensions as defined in <> -* The `@ConversationScoped` annotation represents the conversation scope defined in <>. * Finally, there is a `@Dependent` pseudo-scope for dependent objects, as defined in <>. -If an interceptor or decorator has any scope other than `@Dependent`, non-portable behavior results. +If an interceptor has any scope other than `@Dependent`, non-portable behavior results. [[defining_new_scope_type]] @@ -591,7 +587,8 @@ The set of bean defining annotations contains: * `@ApplicationScoped`, `@SessionScoped`, `@ConversationScoped` and `@RequestScoped` annotations, * all other normal scope types, -* `@Interceptor` and `@Decorator` annotations, +//* `@Interceptor` and `@Decorator` annotations, +* `@Interceptor` annotation, * all stereotype annotations (i.e. annotations annotated with `@Stereotype`), * and the `@Dependent` scope annotation. @@ -885,7 +882,7 @@ The built-in stereotype `@jakarta.enterprise.inject.Model` is intended for use w public @interface Model {} ---- -In addition, the special-purpose `@Interceptor` and `@Decorator` stereotypes are defined in <> and <>. +In addition, the special-purpose `@Interceptor` stereotype is defined in <>. [[exceptions]] diff --git a/spec/src/main/asciidoc/core/definition_full.asciidoc b/spec/src/main/asciidoc/core/definition_full.asciidoc new file mode 100644 index 000000000..ee8dbf5f8 --- /dev/null +++ b/spec/src/main/asciidoc/core/definition_full.asciidoc @@ -0,0 +1,41 @@ +[[concepts_full]] + +== Extended Concepts for {cdi_full} + +[[capabilities_full]] + +=== Functionality provided by the container to the bean in {cdi_full} + +When running in {cdi_full}, the container must extend the capabilities defined in <>, by providing the additional capability: + +* method decoration, as defined in <> + +[[qualifiers_full]] + +=== Qualifiers in {cdi_full} + +In {cdi_full} qualifier types are also used to bind decorators to beans, as specified in <>. + +[[scopes_full]] + +=== Scopes in {cdi_full} + +[[builtin_scopes_full]] + +==== Built-in scope types in {cdi_full} + +{cdi_full} adds a new standard scope to those defined in <> + +* The `@ConversationScoped` annotation represents the conversation scope defined in <>. + +If a decorator has any scope other than `@Dependent`, non-portable behavior results. + +[[stereotypes_full]] + +=== Stereotypes in {cdi_full} + +[[builtin_stereotypes_full]] + +==== Built-in stereotypes in {cdi_full} + +In addition to built-in stereotypes defined in <>, {cdi_full} provides the special-purpose `@Decorator` stereotype, defined in <>. diff --git a/spec/src/main/asciidoc/core/events.asciidoc b/spec/src/main/asciidoc/core/events.asciidoc index 18112b7f9..da13a037e 100644 --- a/spec/src/main/asciidoc/core/events.asciidoc +++ b/spec/src/main/asciidoc/core/events.asciidoc @@ -2,6 +2,11 @@ == Events +[NOTE] +==== +This section has reference to extension. They should be moved in a specific "event" section in full section +==== + Beans may produce and consume events. This facility allows beans to interact in a completely decoupled fashion, with no compile-time dependency between the interacting beans. Most importantly, it allows stateful beans in one architectural tier of the application to synchronize their internal state with state changes that occur in a different tier. diff --git a/spec/src/main/asciidoc/core/implementation.asciidoc b/spec/src/main/asciidoc/core/implementation.asciidoc index 09a54a119..bdd0639a0 100644 --- a/spec/src/main/asciidoc/core/implementation.asciidoc +++ b/spec/src/main/asciidoc/core/implementation.asciidoc @@ -2,6 +2,11 @@ == Programming model +[NOTE] +==== +this section contains part about specialization. It should be moved in a dedicated section in CDI Full. +==== + The container provides built-in support for injection and contextual lifecycle management of the following kinds of bean: * Managed beans @@ -236,17 +241,17 @@ If the method is static or does not directly override another producer method, t public class MockShop extends Shop { @Override @Specializes - @Produces - PaymentProcessor getPaymentProcessor() { - return new MockPaymentProcessor(); + @Produces + PaymentProcessor getPaymentProcessor() { + return new MockPaymentProcessor(); } @Override @Specializes - @Produces + @Produces List getProducts() { return PRODUCTS; } - + ... } diff --git a/spec/src/main/asciidoc/core/implementation_full.adoc b/spec/src/main/asciidoc/core/implementation_full.adoc new file mode 100644 index 000000000..a069649ba --- /dev/null +++ b/spec/src/main/asciidoc/core/implementation_full.adoc @@ -0,0 +1,3 @@ +[[implementation_full]] + +== Programming model in {cdi_full} \ No newline at end of file diff --git a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc index 7c90a2cfc..6eebe68f5 100644 --- a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc +++ b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc @@ -2,6 +2,11 @@ == Dependency injection and lookup +[NOTE] +==== +This section contains parts about modulartity, specialization and bean archive config. It should be moved to a CDI full section +==== + The container injects references to contextual instances to the following kinds of _injection point_: * Any injected field of a bean class diff --git a/spec/src/main/asciidoc/core/scopescontexts.asciidoc b/spec/src/main/asciidoc/core/scopescontexts.asciidoc index 9f9fbd8d1..87a86f023 100644 --- a/spec/src/main/asciidoc/core/scopescontexts.asciidoc +++ b/spec/src/main/asciidoc/core/scopescontexts.asciidoc @@ -2,6 +2,14 @@ == Scopes and contexts +[NOTE] +==== + +This section makes reference to passivation multiple time. These mention should be moved in a dedicated section in CDI Full +Conversation Context should be moved to CDI full as well + +==== + Associated with every scope type is a _context object_. The context object determines the lifecycle and visibility of instances of all beans with that scope. In particular, the context object defines: diff --git a/spec/src/main/asciidoc/core/spi_lite.asciidoc b/spec/src/main/asciidoc/core/spi_lite.asciidoc new file mode 100644 index 000000000..747983bd4 --- /dev/null +++ b/spec/src/main/asciidoc/core/spi_lite.asciidoc @@ -0,0 +1,8 @@ +[[spi_lite]] + +== Build time extensions + +[NOTE] +==== +TBD +==== diff --git a/spec/src/main/asciidoc/preface.asciidoc b/spec/src/main/asciidoc/preface.asciidoc index 9c57b4351..ab4d54f35 100644 --- a/spec/src/main/asciidoc/preface.asciidoc +++ b/spec/src/main/asciidoc/preface.asciidoc @@ -3,6 +3,12 @@ == Preface +[NOTE] +==== +This part has to be rewritten to present a consitent history of the spec +==== + + === Evaluation license include::license-{license}.asciidoc[] @@ -11,6 +17,10 @@ include::license-{license}.asciidoc[] Jakarta Contexts and Dependency Injection 3.0 (link:https://jakarta.ee/specifications/cdi/3.0/[CDI 3.0]) is an update to Jakarta Contexts and Dependency Injection 2.0 (link:https://jakarta.ee/specifications/cdi/3.0/[CDI 2.0]). +Contexts and Dependency Injection 4.0 introduce a new feature with the CDI Lite specification. + +CDI Lite is a subset of CDI that doesn't require a CDI container at runtime and thus is a good candidate to develop cloud native or resources constraint applications. + Starting with version 2.0 CDI targets Java SE and Jakarta EE platforms. CDI in Java SE and CDI in a Jakarta EE container share the features defined in core CDI. @@ -22,6 +32,8 @@ This document is organized in 4 parts: * An introduction (this part), which is not part of the specification but introduces CDI concepts and give examples. * The core CDI specification: <>. +** The CDI Lite specification which contains CDI features that contains features that could be implemented at build time +** The CDI Full specification that add all advanced CDI features to CDI Lite to make the standard CDI platform * Specific CDI features for Java SE: <>. * Specific CDI features for Jakarta EE: <>. @@ -36,5 +48,4 @@ There is a new beans.xml 3.0 schema file has been added and the namespace of the beans_3_0.xsd schema file has changed from xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee" to xmlns:jakartaee="https://jakarta.ee/xml/ns/jakartaee". -:numbered: -<<< \ No newline at end of file +:numbered: \ No newline at end of file From 0aec646de25e13417e497c222405b173f013ca5c Mon Sep 17 00:00:00 2001 From: antoinesd Date: Mon, 26 Apr 2021 23:55:32 +0200 Subject: [PATCH 02/11] cdi-468 Split Spec doc to introduce CDI Lite additional split Signed-off-by: antoinesd --- spec/src/main/asciidoc/cdi-spec.asciidoc | 12 +- .../main/asciidoc/core/definition.asciidoc | 20 +-- .../asciidoc/core/definition_full.asciidoc | 39 ++++++ .../asciidoc/core/implementation.asciidoc | 21 +-- .../asciidoc/core/implementation_full.adoc | 67 ++++++++- .../main/asciidoc/core/inheritance.asciidoc | 2 +- .../asciidoc/core/inheritance_full.asciidoc | 16 +++ .../core/injectionandresolution.asciidoc | 76 ++--------- .../core/injectionandresolution_full.asciidoc | 128 ++++++++++++++++++ .../asciidoc/core/scopescontexts.asciidoc | 17 +-- .../core/scopescontexts_full.asciidoc | 92 +++++++++++++ 11 files changed, 378 insertions(+), 112 deletions(-) create mode 100644 spec/src/main/asciidoc/core/inheritance_full.asciidoc create mode 100644 spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc create mode 100644 spec/src/main/asciidoc/core/scopescontexts_full.asciidoc diff --git a/spec/src/main/asciidoc/cdi-spec.asciidoc b/spec/src/main/asciidoc/cdi-spec.asciidoc index febcaa03a..756d06171 100644 --- a/spec/src/main/asciidoc/cdi-spec.asciidoc +++ b/spec/src/main/asciidoc/cdi-spec.asciidoc @@ -41,6 +41,8 @@ include::core/definition.asciidoc[] include::core/implementation.asciidoc[] +include::core/inheritance.asciidoc[] + include::core/injectionandresolution.asciidoc[] include::core/scopescontexts.asciidoc[] @@ -59,7 +61,15 @@ include::core/spi_lite.asciidoc[] :leveloffset: +1 -include::core/inheritance.asciidoc[] +include::core/definition_full.asciidoc[] + +include::core/implementation_full.adoc[] + +include::core/inheritance_full.asciidoc[] + +include::core/injectionandresolution_full.asciidoc[] + +include::core/scopescontexts_full.asciidoc[] include::core/decorators.asciidoc[] diff --git a/spec/src/main/asciidoc/core/definition.asciidoc b/spec/src/main/asciidoc/core/definition.asciidoc index dafdfd518..b1ea95b6d 100644 --- a/spec/src/main/asciidoc/core/definition.asciidoc +++ b/spec/src/main/asciidoc/core/definition.asciidoc @@ -2,11 +2,6 @@ == Concepts -[NOTE] -==== -This part still contains references to decorators and a few comments that should be moved to the CDI Full "concept" section to add specific features to full -==== - A bean is a source of contextual objects which define application state and/or logic. These objects are called _contextual instances of the bean_. The container creates and destroys these instances and associates them with the appropriate context. @@ -30,11 +25,9 @@ The developer then defines the remaining attributes by explicitly annotating the The bean types and qualifiers of a bean determine where its instances will be injected by the container, as defined in <>. -The bean developer may also create interceptors and/or decorators or reuse existing interceptors and/or decorators. +The bean developer may also create interceptors or reuse existing interceptors. The interceptor bindings of a bean determine which interceptors will be applied at runtime. -The bean types and qualifiers of a bean determine which decorators will be applied at runtime. -Interceptors are defined by Java interceptors specification, and interceptor bindings are specified in <>. -Decorators are defined in <>. +Interceptors are defined by Jakarta EE interceptors specification, and interceptor bindings are specified in <>. [[capabilities]] @@ -381,7 +374,7 @@ For example, when the container encounters the following producer method, an ins [source, java] ---- @Produces -PaymentProcessor getPaymentProcessor(@Synchronous PaymentProcessor sync, +PaymentProcessor getPaymentProcessor(@Synchronous PaymentProcessor sync, @Asynchronous PaymentProcessor async) { return isSynchronous() ? sync : async; } @@ -585,9 +578,8 @@ A bean class with a _bean defining annotation_ is said to be an _implicit bean_. The set of bean defining annotations contains: -* `@ApplicationScoped`, `@SessionScoped`, `@ConversationScoped` and `@RequestScoped` annotations, +* `@ApplicationScoped`, `@SessionScoped` and `@RequestScoped` annotations, * all other normal scope types, -//* `@Interceptor` and `@Decorator` annotations, * `@Interceptor` annotation, * all stereotype annotations (i.e. annotations annotated with `@Stereotype`), * and the `@Dependent` scope annotation. @@ -672,7 +664,7 @@ The rules for determining the default name for a bean are defined in <>, by providing these additional capabilities: + +The bean developer may also create decorators or reuse existing decorators. +The bean types and qualifiers of a bean determine which decorators will be applied at runtime. +Decorators are defined in <>. + [[capabilities_full]] === Functionality provided by the container to the bean in {cdi_full} @@ -30,6 +36,39 @@ In {cdi_full} qualifier types are also used to bind decorators to beans, as spec If a decorator has any scope other than `@Dependent`, non-portable behavior results. +[[bean_defining_annotations_full]] + +==== Bean defining annotations in {cdi_full} + +{cdi_full} adds the following annotations to the set of bean defining annotations : + +* `@ConversationScoped` annotation, +* `@Decorator` annotation. + +[[names_full]] + +=== Bean names in {cdi_full} + +[[beans_with_no_name_full]] + +==== Beans with no name in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full} bean names have also the following restriction: + +If a decorator has a name, non-portable behavior results. + +[[alternatives_full]] + +=== Alternatives in {cdi_full} + +[[declaring_alternative_full]] + +==== Declaring an alternative in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full} alternative have also the following restriction: + +If a decorator is an alternative, non-portable behavior results. + [[stereotypes_full]] === Stereotypes in {cdi_full} diff --git a/spec/src/main/asciidoc/core/implementation.asciidoc b/spec/src/main/asciidoc/core/implementation.asciidoc index bdd0639a0..a88fa71ea 100644 --- a/spec/src/main/asciidoc/core/implementation.asciidoc +++ b/spec/src/main/asciidoc/core/implementation.asciidoc @@ -2,11 +2,6 @@ == Programming model -[NOTE] -==== -this section contains part about specialization. It should be moved in a dedicated section in CDI Full. -==== - The container provides built-in support for injection and contextual lifecycle management of the following kinds of bean: * Managed beans @@ -25,7 +20,6 @@ A _managed bean_ is a bean that is implemented by a Java class. This class is called the _bean class_ of the managed bean. The basic lifecycle and semantics of managed beans are defined by the Managed Beans specification. -If the bean class of a managed bean is annotated with both `@Interceptor` and `@Decorator`, the container automatically detects the problem and treats it as a definition error. If a managed bean has a non-static public field, it must have scope `@Dependent`. If a managed bean with a non-static public field declares any scope other than `@Dependent`, the container automatically detects the problem and treats it as a definition error. @@ -38,7 +32,7 @@ If the managed bean class is a generic type, it must have scope `@Dependent`. If A Java class is a managed bean if it meets all of the following conditions: * It is not an inner class. -* It is a non-abstract class, or is annotated `@Decorator`. +* It is a non-abstract class, * It does not implement `jakarta.enterprise.inject.spi.Extension`. * It is not annotated `@Vetoed` or in a package annotated `@Vetoed`. * It has an appropriate constructor - either: @@ -207,8 +201,8 @@ public class Shop { If a producer method is annotated `@Inject`, has a parameter annotated `@Disposes`, has a parameter annotated `@Observes`, or has a parameter annotated `@ObservesAsync`, the container automatically detects the problem and treats it as a definition error. -Interceptors and decorators may not declare producer methods. -If an interceptor or decorator has a method annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. +Interceptors may not declare producer methods. +If an interceptor has a method annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. A producer method may have any number of parameters. All producer method parameters are injection points. @@ -345,8 +339,8 @@ public class Shop { If a producer field is annotated `@Inject`, the container automatically detects the problem and treats it as a definition error. -Interceptors and decorators may not declare producer fields. -If an interceptor or decorator has a field annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. +Interceptors may not declare producer fields. +If an interceptor has a field annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. [[producer_field_name]] @@ -433,8 +427,8 @@ If a method has more than one parameter annotated `@Disposes`, the container aut If a disposer method is annotated `@Produces` or `@Inject` has a parameter annotated `@Observes` or has a parameter annotated `@ObservesAsync`, the container automatically detects the problem and treats it as a definition error. -Interceptors and decorators may not declare disposer methods. -If an interceptor or decorator has a method annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. +Interceptors may not declare disposer methods. +If an interceptor has a method annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. In addition to the disposed parameter, a disposer method may declare additional parameters, which may also specify qualifiers. These additional parameters are injection points. @@ -719,7 +713,6 @@ Certain legal bean types cannot be proxied by the container: A bean type must be proxyable if an injection point resolves to a bean: * that requires a client proxy, or -* that has an associated decorator, or * that has a bound interceptor. diff --git a/spec/src/main/asciidoc/core/implementation_full.adoc b/spec/src/main/asciidoc/core/implementation_full.adoc index a069649ba..beb179292 100644 --- a/spec/src/main/asciidoc/core/implementation_full.adoc +++ b/spec/src/main/asciidoc/core/implementation_full.adoc @@ -1,3 +1,68 @@ [[implementation_full]] -== Programming model in {cdi_full} \ No newline at end of file +== Programming model in {cdi_full} + +[[managed_beans_full]] + +=== Managed beans in {cdi_full} + +In addition to rules defined in <>, the following applies when running in {cdi_full}: + +If the bean class of a managed bean is annotated with both `@Interceptor` and `@Decorator`, the container automatically detects the problem and treats it as a definition error. + +[[what_classes_are_beans_full]] + +==== Which Java classes are managed beans in {cdi_full}? + +When running in {cdi_full}, a Java class may also be a manged bean if it meets all conditions defined in <> and the following: + +* It is a non-abstract class, or is annotated `@Decorator`. + +[[producer_method_full]] + +=== Producer methods in {cdi_full} + +[[declaring_producer_method_full]] + +==== Declaring a producer method in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following applies: + +Decorators may not declare producer methods. +If a decorator has a method annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. + +[[producer_field_full]] + +=== Producer fields in {cdi_full} + +[[declaring_producer_field_full]] + +==== Declaring a producer field in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following applies: + +Decorators may not declare producer fields. +If a decorator has a field annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. + +[[disposer_method_full]] + +=== Disposer methods in {cdi_full} + +[[declaring_disposer_method_full]] + +==== Declaring a disposer method in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following applies: + +Decorators may not declare disposer methods. +If a decorator has a method annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. + +[[unproxyable_full]] + +=== Unproxyable bean types in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following applies: + +A bean type must be proxyable if an injection point resolves to a bean: + +* that has an associated decorator. \ No newline at end of file diff --git a/spec/src/main/asciidoc/core/inheritance.asciidoc b/spec/src/main/asciidoc/core/inheritance.asciidoc index be16f82ee..eb4fc410c 100644 --- a/spec/src/main/asciidoc/core/inheritance.asciidoc +++ b/spec/src/main/asciidoc/core/inheritance.asciidoc @@ -216,5 +216,5 @@ public class AsynchronousService implements Service{ Then the bean name would also automatically be inherited by `MockAsynchronousService`. -If an interceptor or decorator is annotated `@Specializes`, non-portable behavior results. +If an interceptor is annotated `@Specializes`, non-portable behavior results. diff --git a/spec/src/main/asciidoc/core/inheritance_full.asciidoc b/spec/src/main/asciidoc/core/inheritance_full.asciidoc new file mode 100644 index 000000000..484e39aa9 --- /dev/null +++ b/spec/src/main/asciidoc/core/inheritance_full.asciidoc @@ -0,0 +1,16 @@ +[[inheritance_full]] + +== Inheritance and specialization in {cdi_full} + +[[specialization_full]] + +=== Specialization in {cdi_full} + +[[direct_and_indirect_specialization_full]] + +==== Direct and indirect specialization in {cdi_full} + +In addition to rules defined in <>, the following apply when running in {cdi_full}: + +If decorator is annotated `@Specializes`, non-portable behavior results. + diff --git a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc index 6eebe68f5..dedf25fd4 100644 --- a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc +++ b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc @@ -2,10 +2,6 @@ == Dependency injection and lookup -[NOTE] -==== -This section contains parts about modulartity, specialization and bean archive config. It should be moved to a CDI full section -==== The container injects references to contextual instances to the following kinds of _injection point_: @@ -39,10 +35,6 @@ An alternative is not available for injection, lookup or name resolution to clas ==== Declaring selected alternatives -This specification defines two methods of selecting alternatives. -From Contexts and Dependency Injection 1.1 onwards the `@Priority` annotation allows an alternative to be selected for an entire application. -Contexts and Dependency Injection 1.0 allowed only for an alternative to be selected for a bean archive. - [[declaring_selected_alternatives_application]] ===== Declaring selected alternatives for an application @@ -55,48 +47,6 @@ An alternative may be given a priority for the application: Custom bean implementations which are also alternatives may implement <> in which case they will be enabled for entire application with given priority. -[[declaring_selected_alternatives_bean_archive]] - -===== Declaring selected alternatives for a bean archive - - -An alternative may be explicitly declared using the `` element of the `beans.xml` file of the bean archive. -The `` element contains a list of bean classes and stereotypes. -An alternative is selected for the bean archive if either: - -* the alternative is a managed bean and the bean class of the bean is listed, -* the alternative is a producer method, field or resource, and the bean class that declares the method or field is listed, or -* any `@Alternative` stereotype of the alternative is listed. - -[source,xml] ----- - - - com.acme.myfwk.InMemoryDatabase - com.acme.myfwk.Mock - com.acme.site.Australian - - ----- - -For each child `` element the container verifies that either: - -* a class with the specified name exists and is annotated with `@Alternative` or an <>, or -* a class with the specified name exists and declares a field or method annotated with `@Produces` and, at the same time, annotated with `@Alternative` or an <>, or -* an alternative bean whose bean class has the specified name exists. - -Otherwise, the container automatically detects the problem and treats it as a deployment problem. - -Each child `` element must specify the name of an `@Alternative` stereotype annotation. -If there is no annotation with the specified name, or the annotation is not an `@Alternative` stereotype, the container automatically detects the problem and treats it as a deployment problem. - -If the same type is listed twice under the `` element, the container automatically detects the problem and treats it as a deployment problem. - -For a custom implementation of the `Bean` interface defined in <>, the container calls `isAlternative()` to determine whether the bean is an alternative, and `getBeanClass()` and `getStereotypes()` to determine whether an alternative is selected in a certain bean archive. - [[enablement]] ==== Enabled and disabled beans @@ -125,7 +75,7 @@ The container automatically detects inconsistent specialization and treats it as A bean is _available for injection_ in a certain module if: -* the bean is not an interceptor or decorator, +* the bean is not an interceptor * the bean is enabled, * the bean is either not an alternative, or the module is a bean archive and the bean is a selected alternative of the bean archive, or the bean is a selected alternative of the application, and * the bean class is required to be accessible to classes in the module, according to the class accessibility requirements of the module architecture. @@ -171,8 +121,6 @@ For a custom implementation of the `Bean` interface defined in <>, the con An _unsatisfied dependency_ exists at an injection point when no bean is eligible for injection to the injection point. An _ambiguous dependency_ exists at an injection point when multiple beans are eligible for injection to the injection point. -Note that an unsatisfied or ambiguous dependency cannot exist for a decorator delegate injection point, defined in <>. - When an ambiguous dependency exists, the container attempts to resolve the ambiguity. The container eliminates all eligible beans that are not alternatives, except for producer methods and fields of beans that are alternatives. If: @@ -227,8 +175,6 @@ public class UserDao extends Dao { ... } A raw bean type is considered assignable to a parameterized required type if the raw types are identical and all type parameters of the required type are either unbounded type variables or java.lang.Object. -Note that a special set of rules, defined in <>, apply if and only if the injection point is a decorator delegate injection point. - [[primitive_types_and_null_values]] ==== Primitive types and null values @@ -528,8 +474,7 @@ If the injection point represents a dynamically obtained instance, the `getType( If the injection point represents a dynamically obtained instance, the `getMember()` method returns the `Field` object representing the field that defines the `Instance` injection point in the case of field injection, the `Method` object representing the method that defines the `Instance` injection point in the case of method parameter injection, or the `Constructor` object representing the constructor that defines the `Instance` injection point in the case of constructor parameter injection. * The `getAnnotated()` method returns an instance of `jakarta.enterprise.inject.spi.AnnotatedField` or `jakarta.enterprise.inject.spi.AnnotatedParameter`, depending upon whether the injection point is an injected field or a constructor/method parameter. If the injection point represents a dynamically obtained instance, then the `getAnnotated()` method returns an instance of `jakarta.enterprise.inject.spi.AnnotatedField` or `jakarta.enterprise.inject.spi.AnnotatedParameter` representing the `Instance` injection point, depending upon whether the injection point is an injected field or a constructor/method parameter. -* The `isDelegate()` method returns `true` if the injection point is a decorator delegate injection point, and `false` otherwise. -If the injection point represents a dynamically obtained instance then `isDelegate()` returns false. +* The `isDelegate()` method always returns `false`. * The `isTransient()` method returns `true` if the injection point is a transient field, and `false` otherwise. If the injection point represents a dynamically obtained instance then the `isTransient()` method returns `true` if the `Instance` injection point is a transient field, and `false` otherwise. If this injection point is declared as transient, after bean's passivation, the value will not be restored. Instance<> injection point is the preferred approach. @@ -558,36 +503,31 @@ If a class supporting injection that is not a bean has an injection point of typ ==== Bean metadata -The interfaces `Bean`, `Interceptor` and `Decorator` provide metadata about a bean. +The interfaces `Bean` and `Interceptor` provide metadata about a bean. -The container must provide beans allowing a bean instance to obtain a `Bean`, `Interceptor` or `Decorator` instance containing its metadata: +The container must provide beans allowing a bean instance to obtain a `Bean` or `Interceptor` instance containing its metadata: * a bean with scope `@Dependent`, qualifier `@Default` and type `Bean` which can be injected into any bean instance * a bean with scope `@Dependent`, qualifier `@Default` and type `Interceptor` which can be injected into any interceptor instance -* a bean with scope `@Dependent`, qualifier `@Default` and type `Decorator` which can be injected into any decorator instance -Additionally, the container must provide beans allowing interceptors and decorators to obtain information about the beans they intercept and decorate: -* a bean with scope `@Dependent`, qualifier `@Intercepted` and type `Bean` which can be injected into any interceptor instance, and -* a bean with scope `@Dependent`, qualifier `@Decorated` and type `Bean` which can be injected into any decorator instance. +Additionally, the container must provide beans allowing interceptors to obtain information about the beans they intercept: + +* a bean with scope `@Dependent`, qualifier `@Intercepted` and type `Bean` which can be injected into any interceptor instance. These beans are passivation capable dependencies, as defined in <>. If an `Interceptor` instance is injected into a bean instance other than an interceptor instance, the container automatically detects the problem and treats it as a definition error. -If a `Decorator` instance is injected into a bean instance other than a decorator instance, the container automatically detects the problem and treats it as a definition error. - If a `Bean` instance with qualifier `@Intercepted` is injected into a bean instance other than an interceptor instance, the container automatically detects the problem and treats it as a definition error. -If a `Bean` instance with qualifier `@Decorated` is injected into a bean instance other than a decorator instance, the container automatically detects the problem and treats it as a definition error. The injection of bean metadata is restricted. If: -* the injection point is a field, an initializer method parameter or a bean constructor, with qualifier `@Default`, then the type parameter of the injected `Bean`, `Interceptor` or `Decorator` must be the same as the type declaring the injection point, or +* the injection point is a field, an initializer method parameter or a bean constructor, with qualifier `@Default`, then the type parameter of the injected `Bean`, or `Interceptor` must be the same as the type declaring the injection point, or * the injection point is a field, an initializer method parameter or a bean constructor of an interceptor, with qualifier `@Intercepted`, then the type parameter of the injected `Bean` must be an unbounded wildcard, or -* the injection point is a field, an initializer method parameter or a bean constructor of a decorator, with qualifier `@Decorated`, then the type parameter of the injected `Bean` must be the same as the delegate type, or * the injection point is a producer method parameter then the type parameter of the injected `Bean` must be the same as the producer method return type, or * the injection point is a parameter of a disposer method then the container automatically detects the problem and treats it as a definition error. diff --git a/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc new file mode 100644 index 000000000..ff9650a53 --- /dev/null +++ b/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc @@ -0,0 +1,128 @@ +[[injection_and_resolution_full]] + +== Dependency injection and lookup in {cdi_full} + + +[[selection_full]] + +=== Modularity in {cdi_full} + +[[declaring_selected_alternatives_full]] + +==== Declaring selected alternatives in {cdi_full} + +{cdi_full} provides an additional way to declare alternatives to the one defined in <>: + +[[declaring_selected_alternatives_bean_archive]] + +===== Declaring selected alternatives for a bean archive + +An alternative may be explicitly declared using the `` element of the `beans.xml` file of the bean archive. +The `` element contains a list of bean classes and stereotypes. +An alternative is selected for the bean archive if either: + +* the alternative is a managed bean and the bean class of the bean is listed, +* the alternative is a producer method, field or resource, and the bean class that declares the method or field is listed, or +* any `@Alternative` stereotype of the alternative is listed. + +[source,xml] +---- + + + com.acme.myfwk.InMemoryDatabase + com.acme.myfwk.Mock + com.acme.site.Australian + + +---- + +For each child `` element the container verifies that either: + +* a class with the specified name exists and is annotated with `@Alternative` or an <>, or +* a class with the specified name exists and declares a field or method annotated with `@Produces` and, at the same time, annotated with `@Alternative` or an <>, or +* an alternative bean whose bean class has the specified name exists. + +Otherwise, the container automatically detects the problem and treats it as a deployment problem. + +Each child `` element must specify the name of an `@Alternative` stereotype annotation. +If there is no annotation with the specified name, or the annotation is not an `@Alternative` stereotype, the container automatically detects the problem and treats it as a deployment problem. + +If the same type is listed twice under the `` element, the container automatically detects the problem and treats it as a deployment problem. + +For a custom implementation of the `Bean` interface defined in <>, the container calls `isAlternative()` to determine whether the bean is an alternative, and `getBeanClass()` and `getStereotypes()` to determine whether an alternative is selected in a certain bean archive. + + + +[[inter_module_injection_full]] + +==== Inter-module injection in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following apply: + +A bean is also _available for injection_ in a certain module if: + +* the bean is not a decorator + +[[typesafe_resolution_full]] + +=== Typesafe resolution in {cdi_full} + +[[unsatisfied_and_ambig_dependencies_full]] + +==== Unsatisfied and ambiguous dependencies in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following apply: + +An unsatisfied or ambiguous dependency cannot exist for a decorator delegate injection point, defined in <>. + + +[[assignable_parameters_full]] + +==== Assignability of raw and parameterized types in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following apply: + +A special set of rules, defined in <>, apply if and only if the injection point is a decorator delegate injection point. + +[[injection_point_full]] + +==== Injection point metadata in {cdi_full} + +When running in {cdi_full}, the behaviour of `InjectionPoint` metadata is overrided as follow: + +* The `isDelegate()` method returns `true` if the injection point is a decorator delegate injection point, and `false` otherwise. +If the injection point represents a dynamically obtained instance then `isDelegate()` returns false. + +[[bean_metadata_full]] + +==== Bean metadata in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following apply: + +The interfaces `Decorator` also provide metadata about a bean. + +The container must provide beans allowing a bean instance to obtain a `Decorator` instance containing its metadata: + +* a bean with scope `@Dependent`, qualifier `@Default` and type `Decorator` which can be injected into any decorator instance + +Additionally, the container must provide beans allowing decorators to obtain information about the beans they decorate: + +* a bean with scope `@Dependent`, qualifier `@Decorated` and type `Bean` which can be injected into any decorator instance. + + +These beans are passivation capable dependencies, as defined in <>. + + +If a `Decorator` instance is injected into a bean instance other than a decorator instance, the container automatically detects the problem and treats it as a definition error. + +If a `Bean` instance with qualifier `@Decorated` is injected into a bean instance other than a decorator instance, the container automatically detects the problem and treats it as a definition error. + +If: + +* the injection point is a field, an initializer method parameter or a bean constructor, with qualifier `@Default`, then the type parameter of the injected `Decorator` must be the same as the type declaring the injection point, or +* the injection point is a field, an initializer method parameter or a bean constructor of a decorator, with qualifier `@Decorated`, then the type parameter of the injected `Bean` must be the same as the delegate type. + +Otherwise, the container automatically detects the problem and treats it as a definition error. \ No newline at end of file diff --git a/spec/src/main/asciidoc/core/scopescontexts.asciidoc b/spec/src/main/asciidoc/core/scopescontexts.asciidoc index 87a86f023..7ca34df47 100644 --- a/spec/src/main/asciidoc/core/scopescontexts.asciidoc +++ b/spec/src/main/asciidoc/core/scopescontexts.asciidoc @@ -2,14 +2,6 @@ == Scopes and contexts -[NOTE] -==== - -This section makes reference to passivation multiple time. These mention should be moved in a dedicated section in CDI Full -Conversation Context should be moved to CDI full as well - -==== - Associated with every scope type is a _context object_. The context object determines the lifecycle and visibility of instances of all beans with that scope. In particular, the context object defines: @@ -195,7 +187,6 @@ The `@Dependent` scope is always active. Many instances of beans with scope `@Dependent` belong to some other bean and are called _dependent objects_. -* Instances of decorators and interceptors are dependent objects of the bean instance they decorate. * An instance of a bean with scope `@Dependent` injected into a field, bean constructor or initializer method is a dependent object of the bean into which it was injected. * An instance of a bean with scope `@Dependent` injected into a producer method is a dependent object of the producer method bean instance that is being produced. * An instance of a bean with scope `@Dependent` obtained by direct invocation of an `Instance` is a dependent object of the instance of `Instance`. @@ -373,7 +364,7 @@ The transfer of the passivated state back into memory is called _activation_. A bean is called _passivation capable_ if the container is able to temporarily transfer the state of any idle instance to secondary storage. -* A managed bean is passivation capable if and only if the bean class is serializable and all interceptors and decorators of the bean are passivation capable. +* A managed bean is passivation capable if and only if the bean class is serializable and all interceptors of the bean are passivation capable. * A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime. * A producer field is passivation capable if and only if it never refers to a value which is not passivation capable at runtime. @@ -442,8 +433,8 @@ If a managed bean which declares a passivating scope, or a built-in bean: * is not passivation capable, * has an injection point that is not passivation capable, -* has an interceptor or decorator that is not passivation capable -* has an interceptor or decorator with an injection point that is not passivation capable +* has an interceptor that is not passivation capable +* has an interceptor with an injection point that is not passivation capable then the container automatically detects the problem and treats it as a deployment problem. @@ -464,7 +455,7 @@ If a producer method or field of scope `@Dependent` returns an unserializable ob For a custom implementation of `Bean`, the container calls `getInjectionPoints()` to determine the injection points, and `InjectionPoint.isTransient()` to determine whether the injection point is a transient field. -If a managed bean which declares a passivating scope type, has a decorator or interceptor which is not a passivation capable dependency, the container automatically detects the problem and treats it as a deployment problem. +If a managed bean which declares a passivating scope type, has an interceptor which is not a passivation capable dependency, the container automatically detects the problem and treats it as a deployment problem. [[builtin_contexts]] diff --git a/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc b/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc new file mode 100644 index 000000000..1a03ef8e2 --- /dev/null +++ b/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc @@ -0,0 +1,92 @@ +[[contexts_full]] + +== Scopes and contexts in {cdi_full} + + +[[dependent_context_full]] + +=== Dependent pseudo-scope in {cdi_full} + + +[[dependent_objects_full]] + +==== Dependent objects in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following apply: + +* Instances of decorators and interceptors are dependent objects of the bean instance they decorate. + + +[[passivating_scope_full]] + +=== Passivation and passivating scopes in {cdi_full} + + +[[passivation_capable_full]] + +==== Passivation capable beans + +In addition to rules defined in <>, when running in {cdi_full}, the following apply: + + +* A managed bean is passivation capable if and only if the bean class is serializable and all interceptors and decorators of the bean are passivation capable. + + +[[passivation_validation_full]] + +==== Validation of passivation capable beans and dependencies in {cdi_full} + +In addition to rules defined in <>, when running in {cdi_full}, the following apply: +If a managed bean which declares a passivating scope, or a built-in bean: + +* has a decorator that is not passivation capable +* has a decorator with an injection point that is not passivation capable + + +If a managed bean which declares a passivating scope type, has a decorator which is not a passivation capable dependency, the container automatically detects the problem and treats it as a deployment problem. + +[[builtin_contexts_full]] + +=== Context management for built-in scopes in {cdi_full} + +[[conversation_context]] + +==== Conversation context lifecycle + +The _conversation context_ is provided by a built-in context object for the built-in passivating scope type `@ConversationScoped`. + +[[conversation]] + +==== The `Conversation` interface + +The container provides a built-in bean with bean type `Conversation`, scope `@RequestScoped`, and qualifier `@Default`, named `jakarta.enterprise.context.conversation`. + +[source, java] +---- +public interface Conversation { + public void begin(); + public void begin(String id); + public void end(); + public String getId(); + public long getTimeout(); + public void setTimeout(long milliseconds); + public boolean isTransient(); +} +---- + +* `begin()` marks the current transient conversation long-running. A conversation identifier may, optionally, be specified. +If no conversation identifier is specified, an identifier is generated by the container. +* `end()` marks the current long-running conversation transient. +* `getId()` returns the identifier of the current long-running conversation, or a null value if the current conversation is transient. +* `getTimeout()` returns the timeout, in milliseconds, of the current conversation. +* `setTimeout()` sets the timeout of the current conversation. +* `isTransient()` returns `true` if the conversation is marked transient, or `false` if it is marked long-running. + + +If any method of `Conversation` is called when the conversation scope is not active, a `ContextNotActiveException` is thrown. + +If `end()` is called, and the current conversation is marked transient, an `IllegalStateException` is thrown. + +If `begin()` is called, and the current conversation is already marked long-running, an `IllegalStateException` is thrown. + +If `begin()` is called with an explicit conversation identifier, and a long-running conversation with that identifier already exists, an `IllegalArgumentException` is thrown. From 893141bd104850f66517935a995f74108a206c58 Mon Sep 17 00:00:00 2001 From: Matej Novotny Date: Tue, 27 Apr 2021 12:31:31 +0200 Subject: [PATCH 03/11] Contributing suggested changes. --- spec/src/main/asciidoc/cdi-spec.asciidoc | 2 ++ .../asciidoc/core/definition_full.asciidoc | 6 ++-- .../core/injectionandresolution.asciidoc | 1 - .../core/packagingdeployment_lite.asciidoc | 8 ++++++ .../core/scopescontexts_full.asciidoc | 4 +-- spec/src/main/asciidoc/preface.asciidoc | 28 ++++++++----------- 6 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 spec/src/main/asciidoc/core/packagingdeployment_lite.asciidoc diff --git a/spec/src/main/asciidoc/cdi-spec.asciidoc b/spec/src/main/asciidoc/cdi-spec.asciidoc index 756d06171..490a623ad 100644 --- a/spec/src/main/asciidoc/cdi-spec.asciidoc +++ b/spec/src/main/asciidoc/cdi-spec.asciidoc @@ -55,6 +55,8 @@ include::core/events.asciidoc[] include::core/spi_lite.asciidoc[] +include::core/packagingdeployment_lite.asciidoc[] + :leveloffset: -1 == {cdi_full} diff --git a/spec/src/main/asciidoc/core/definition_full.asciidoc b/spec/src/main/asciidoc/core/definition_full.asciidoc index 23c63fa1e..7599afb1e 100644 --- a/spec/src/main/asciidoc/core/definition_full.asciidoc +++ b/spec/src/main/asciidoc/core/definition_full.asciidoc @@ -1,5 +1,7 @@ [[concepts_full]] +CDI Full contains all the functionality defined in {cdi_lite} and adds some more features such as decorators or conversation scope which are described in following paragraphs. + == Extended Concepts for {cdi_full} When running in {cdi_full}, beans must extend their capabilities defined in <>, by providing these additional capabilities: @@ -12,7 +14,7 @@ Decorators are defined in <>. === Functionality provided by the container to the bean in {cdi_full} -When running in {cdi_full}, the container must extend the capabilities defined in <>, by providing the additional capability: +When running in {cdi_full}, the container must extend the capabilities defined in <>, by providing an additional capability: * method decoration, as defined in <> @@ -34,8 +36,6 @@ In {cdi_full} qualifier types are also used to bind decorators to beans, as spec * The `@ConversationScoped` annotation represents the conversation scope defined in <>. -If a decorator has any scope other than `@Dependent`, non-portable behavior results. - [[bean_defining_annotations_full]] ==== Bean defining annotations in {cdi_full} diff --git a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc index dedf25fd4..3d85a3e97 100644 --- a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc +++ b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc @@ -2,7 +2,6 @@ == Dependency injection and lookup - The container injects references to contextual instances to the following kinds of _injection point_: * Any injected field of a bean class diff --git a/spec/src/main/asciidoc/core/packagingdeployment_lite.asciidoc b/spec/src/main/asciidoc/core/packagingdeployment_lite.asciidoc new file mode 100644 index 000000000..ad8dbd394 --- /dev/null +++ b/spec/src/main/asciidoc/core/packagingdeployment_lite.asciidoc @@ -0,0 +1,8 @@ +[[packaging_deployment_lite]] + +== Packaging and deployment + +[NOTE] +==== +TBD based on what approach we choose +==== diff --git a/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc b/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc index 1a03ef8e2..33b62addc 100644 --- a/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc +++ b/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc @@ -49,13 +49,13 @@ If a managed bean which declares a passivating scope type, has a decorator which === Context management for built-in scopes in {cdi_full} -[[conversation_context]] +[[conversation_context_full]] ==== Conversation context lifecycle The _conversation context_ is provided by a built-in context object for the built-in passivating scope type `@ConversationScoped`. -[[conversation]] +[[conversation_full]] ==== The `Conversation` interface diff --git a/spec/src/main/asciidoc/preface.asciidoc b/spec/src/main/asciidoc/preface.asciidoc index ab4d54f35..f5d12ae3c 100644 --- a/spec/src/main/asciidoc/preface.asciidoc +++ b/spec/src/main/asciidoc/preface.asciidoc @@ -13,34 +13,27 @@ This part has to be rewritten to present a consitent history of the spec include::license-{license}.asciidoc[] -=== Foreword - -Jakarta Contexts and Dependency Injection 3.0 (link:https://jakarta.ee/specifications/cdi/3.0/[CDI 3.0]) is an update to Jakarta Contexts and Dependency Injection 2.0 (link:https://jakarta.ee/specifications/cdi/3.0/[CDI 2.0]). - -Contexts and Dependency Injection 4.0 introduce a new feature with the CDI Lite specification. - -CDI Lite is a subset of CDI that doesn't require a CDI container at runtime and thus is a good candidate to develop cloud native or resources constraint applications. - -Starting with version 2.0 CDI targets Java SE and Jakarta EE platforms. -CDI in Java SE and CDI in a Jakarta EE container share the features defined in core CDI. - [[doc_organisation]] === Organisation of this document This document is organized in 4 parts: -* An introduction (this part), which is not part of the specification but introduces CDI concepts and give examples. -* The core CDI specification: <>. -** The CDI Lite specification which contains CDI features that contains features that could be implemented at build time -** The CDI Full specification that add all advanced CDI features to CDI Lite to make the standard CDI platform +* An introduction (this part), which is not part of the specification but introduces CDI concepts and gives examples. +* Core CDI specification: <>. +** CDI Lite specification which contains a subset of CDI features a which can be implemented in more restricted environments +** CDI Full specification that builds on top of Lite and adds all advanced CDI features; this is the standard Jakarta EE CDI platform * Specific CDI features for Java SE: <>. * Specific CDI features for Jakarta EE: <>. === Major changes -This CDI 3.0 includes a change in the base namespace used by the APIs from +CDI 4.0 splits the core CDI into Lite and Full. Lite contains a subset of original features which are designed to work under more restricted environments. CDI Full contains everything that is in Lite plus all other features that were formerly in core CDI and are not in Lite. + +Jakarta Contexts and Dependency Injection 3.0 (link:https://jakarta.ee/specifications/cdi/3.0/[CDI 3.0]) is an update to Jakarta Contexts and Dependency Injection 2.0 (link:https://jakarta.ee/specifications/cdi/3.0/[CDI 2.0]). + +CDI 3.0 includes a change in the base namespace used by the APIs from javax to jakarta. For example, the `BeanManager` interface has moved from `javax.enterprise.inject.spi.BeanManager` to `jakarta.enterprise.inject.spi.BeanManager`. @@ -48,4 +41,7 @@ There is a new beans.xml 3.0 schema file has been added and the namespace of the beans_3_0.xsd schema file has changed from xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee" to xmlns:jakartaee="https://jakarta.ee/xml/ns/jakartaee". +Starting with version 2.0 CDI targets Java SE and Jakarta EE platforms. +CDI in Java SE and CDI in a Jakarta EE container share the features defined in core CDI. + :numbered: \ No newline at end of file From a45fbe3375224db6b8cf9988717bed8ee7f32128 Mon Sep 17 00:00:00 2001 From: Matej Novotny Date: Thu, 29 Apr 2021 11:02:49 +0200 Subject: [PATCH 04/11] Incorporate additional changes - move specialization to Full; change Modularity paragraph. --- .../main/asciidoc/core/inheritance.asciidoc | 124 +----------------- .../asciidoc/core/inheritance_full.asciidoc | 119 ++++++++++++++++- .../core/injectionandresolution.asciidoc | 12 +- .../core/injectionandresolution_full.asciidoc | 10 ++ .../asciidoc/core/scopescontexts.asciidoc | 1 + .../core/scopescontexts_full.asciidoc | 2 +- 6 files changed, 128 insertions(+), 140 deletions(-) diff --git a/spec/src/main/asciidoc/core/inheritance.asciidoc b/spec/src/main/asciidoc/core/inheritance.asciidoc index eb4fc410c..4341fc447 100644 --- a/spec/src/main/asciidoc/core/inheritance.asciidoc +++ b/spec/src/main/asciidoc/core/inheritance.asciidoc @@ -1,6 +1,6 @@ [[inheritance]] -== Inheritance and specialization +== Inheritance A bean may inherit type-level metadata and members from its superclasses. @@ -97,124 +97,4 @@ This injection point is inherited by `UserDaoClient`, but the type of the inheri ---- public class UserDaoClient extends DaoClient { ... } ----- - -[[specialization]] - -=== Specialization - -If two beans both support a certain bean type, and share at least one qualifier, then they are both eligible for injection to any injection point with that declared type and qualifier. - -Consider the following beans: - -[source, java] ----- -@Default @Asynchronous -public class AsynchronousService implements Service { - ... -} ----- - -[source, java] ----- -@Alternative -public class MockAsynchronousService extends AsynchronousService { - ... -} ----- - -Suppose that the `MockAsynchronousService` alternative is selected, as defined in <>: - -[source, java] ----- -@Alternative @Priority(jakarta.interceptor.Interceptor.Priority.APPLICATION+100) -public class MockAsynchronousService extends AsynchronousService { - ... -} ----- - -Then, according to the rules of <>, the following ambiguous dependency is resolvable, and so the attribute will receive an instance of `MockAsynchronousService`: - -[source, java] ----- -@Inject Service service; ----- - -However, the following attribute will receive an instance of `AsynchronousService`, even though `MockAsynchronousService` is a selected alternative, because `MockAsynchronousService` does not have the qualifier `@Asynchronous`: - -[source, java] ----- -@Inject @Asynchronous Service service; ----- - -This is a useful behavior in some circumstances, however, it is not always what is intended by the developer. - -The only way one bean can completely override a second bean at all injection points is if it implements all the bean types and declares all the qualifiers of the second bean. -However, if the second bean declares a producer method or observer method, then even this is not enough to ensure that the second bean is never called! - -To help prevent developer error, the first bean may: - -* directly extend the bean class of the second bean, or -* directly override the producer method, in the case that the second bean is a producer method, and then - - -explicitly declare that it _specializes_ the second bean. - -[source, java] ----- -@Specializes -public class MockAsynchronousService extends AsynchronousService { - ... -} ----- - -When an enabled bean, as defined in <>, specializes a second bean, we can be certain that the second bean is never instantiated or called by the container. -Even if the second bean defines a producer or observer method, the method will never be called. - -[[direct_and_indirect_specialization]] - -==== Direct and indirect specialization - -The annotation `@jakarta.enterprise.inject.Specializes` is used to indicate that one bean _directly specializes_ another bean, as defined in <> and <>. - -Formally, a bean X is said to _specialize_ another bean Y if there is either: - -* direct specialization, where X directly specializes Y, or -* transitive specialization, where a bean Z exists, such that X directly specializes Z and Z specializes Y. - - -Then X will inherit the qualifiers and bean name of Y: - -* the qualifiers of X include all qualifiers of Y, together with all qualifiers declared explicitly by X, and -* if Y has a bean name, the bean name of X is the same as the bean name of Y. - - -Furthermore, X must have all the bean types of Y. -If X does not have some bean type of Y, the container automatically detects the problem and treats it as a definition error. - -If Y has a bean name and X declares a bean name explicitly the container automatically detects the problem and treats it as a definition error. - -For example, the following bean would have the inherited qualifiers `@Default` and `@Asynchronous`: - -[source, java] ----- -@Mock @Specializes -public class MockAsynchronousService extends AsynchronousService { - ... -} ----- - -If `AsynchronousService` declared a bean name: - -[source, java] ----- -@Default @Asynchronous @Named("asyncService") -public class AsynchronousService implements Service{ - ... -} ----- - -Then the bean name would also automatically be inherited by `MockAsynchronousService`. - -If an interceptor is annotated `@Specializes`, non-portable behavior results. - +---- \ No newline at end of file diff --git a/spec/src/main/asciidoc/core/inheritance_full.asciidoc b/spec/src/main/asciidoc/core/inheritance_full.asciidoc index 484e39aa9..19d01a084 100644 --- a/spec/src/main/asciidoc/core/inheritance_full.asciidoc +++ b/spec/src/main/asciidoc/core/inheritance_full.asciidoc @@ -2,15 +2,122 @@ == Inheritance and specialization in {cdi_full} -[[specialization_full]] +[[specialization]] -=== Specialization in {cdi_full} +=== Specialization -[[direct_and_indirect_specialization_full]] +If two beans both support a certain bean type, and share at least one qualifier, then they are both eligible for injection to any injection point with that declared type and qualifier. -==== Direct and indirect specialization in {cdi_full} +Consider the following beans: -In addition to rules defined in <>, the following apply when running in {cdi_full}: +[source, java] +---- +@Default @Asynchronous +public class AsynchronousService implements Service { + ... +} +---- -If decorator is annotated `@Specializes`, non-portable behavior results. +[source, java] +---- +@Alternative +public class MockAsynchronousService extends AsynchronousService { + ... +} +---- + +Suppose that the `MockAsynchronousService` alternative is selected, as defined in <>: + +[source, java] +---- +@Alternative @Priority(jakarta.interceptor.Interceptor.Priority.APPLICATION+100) +public class MockAsynchronousService extends AsynchronousService { + ... +} +---- + +Then, according to the rules of <>, the following ambiguous dependency is resolvable, and so the attribute will receive an instance of `MockAsynchronousService`: + +[source, java] +---- +@Inject Service service; +---- + +However, the following attribute will receive an instance of `AsynchronousService`, even though `MockAsynchronousService` is a selected alternative, because `MockAsynchronousService` does not have the qualifier `@Asynchronous`: + +[source, java] +---- +@Inject @Asynchronous Service service; +---- + +This is a useful behavior in some circumstances, however, it is not always what is intended by the developer. + +The only way one bean can completely override a second bean at all injection points is if it implements all the bean types and declares all the qualifiers of the second bean. +However, if the second bean declares a producer method or observer method, then even this is not enough to ensure that the second bean is never called! + +To help prevent developer error, the first bean may: + +* directly extend the bean class of the second bean, or +* directly override the producer method, in the case that the second bean is a producer method, and then + + +explicitly declare that it _specializes_ the second bean. + +[source, java] +---- +@Specializes +public class MockAsynchronousService extends AsynchronousService { + ... +} +---- + +When an enabled bean, as defined in <>, specializes a second bean, we can be certain that the second bean is never instantiated or called by the container. +Even if the second bean defines a producer or observer method, the method will never be called. + +[[direct_and_indirect_specialization]] + +==== Direct and indirect specialization + +The annotation `@jakarta.enterprise.inject.Specializes` is used to indicate that one bean _directly specializes_ another bean, as defined in <> and <>. + +Formally, a bean X is said to _specialize_ another bean Y if there is either: + +* direct specialization, where X directly specializes Y, or +* transitive specialization, where a bean Z exists, such that X directly specializes Z and Z specializes Y. + + +Then X will inherit the qualifiers and bean name of Y: + +* the qualifiers of X include all qualifiers of Y, together with all qualifiers declared explicitly by X, and +* if Y has a bean name, the bean name of X is the same as the bean name of Y. + + +Furthermore, X must have all the bean types of Y. +If X does not have some bean type of Y, the container automatically detects the problem and treats it as a definition error. + +If Y has a bean name and X declares a bean name explicitly the container automatically detects the problem and treats it as a definition error. + +For example, the following bean would have the inherited qualifiers `@Default` and `@Asynchronous`: + +[source, java] +---- +@Mock @Specializes +public class MockAsynchronousService extends AsynchronousService { + ... +} +---- + +If `AsynchronousService` declared a bean name: + +[source, java] +---- +@Default @Asynchronous @Named("asyncService") +public class AsynchronousService implements Service{ + ... +} +---- + +Then the bean name would also automatically be inherited by `MockAsynchronousService`. + +If an interceptor or decorator is annotated `@Specializes`, non-portable behavior results. diff --git a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc index 3d85a3e97..15730ba47 100644 --- a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc +++ b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc @@ -24,12 +24,10 @@ 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 <>. +In CDI Lite, libraries that are bean archives are always implicit bean archives. 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. -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]] ==== Declaring selected alternatives @@ -60,14 +58,6 @@ A bean is said to be _enabled_ if: Otherwise, the bean is said to be disabled. -[[inconsistent_specialization]] - -==== Inconsistent specialization - -Suppose an enabled bean X specializes a second bean Y. -If there is another enabled bean that specializes Y we say that _inconsistent specialization_ exists. -The container automatically detects inconsistent specialization and treats it as a deployment problem. - [[inter_module_injection]] ==== Inter-module injection diff --git a/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc index ff9650a53..0ba09a576 100644 --- a/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc +++ b/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc @@ -7,6 +7,10 @@ === Modularity in {cdi_full} +In module architecture, a library may be an explicit bean archive or an implicit bean archive, as defined in <>. + +Additionally, 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]] ==== Declaring selected alternatives in {cdi_full} @@ -54,7 +58,13 @@ If the same type is listed twice under the `` element, the contain For a custom implementation of the `Bean` interface defined in <>, the container calls `isAlternative()` to determine whether the bean is an alternative, and `getBeanClass()` and `getStereotypes()` to determine whether an alternative is selected in a certain bean archive. +[[inconsistent_specialization]] + +==== Inconsistent specialization +Suppose an enabled bean X specializes a second bean Y. +If there is another enabled bean that specializes Y we say that _inconsistent specialization_ exists. +The container automatically detects inconsistent specialization and treats it as a deployment problem. [[inter_module_injection_full]] diff --git a/spec/src/main/asciidoc/core/scopescontexts.asciidoc b/spec/src/main/asciidoc/core/scopescontexts.asciidoc index 7ca34df47..b54f24c25 100644 --- a/spec/src/main/asciidoc/core/scopescontexts.asciidoc +++ b/spec/src/main/asciidoc/core/scopescontexts.asciidoc @@ -187,6 +187,7 @@ The `@Dependent` scope is always active. Many instances of beans with scope `@Dependent` belong to some other bean and are called _dependent objects_. +* Instances interceptors are dependent objects of the bean instance they decorate. * An instance of a bean with scope `@Dependent` injected into a field, bean constructor or initializer method is a dependent object of the bean into which it was injected. * An instance of a bean with scope `@Dependent` injected into a producer method is a dependent object of the producer method bean instance that is being produced. * An instance of a bean with scope `@Dependent` obtained by direct invocation of an `Instance` is a dependent object of the instance of `Instance`. diff --git a/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc b/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc index 33b62addc..a80fddec7 100644 --- a/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc +++ b/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc @@ -14,7 +14,7 @@ In addition to rules defined in <>, when running in {cdi_full}, the following apply: -* Instances of decorators and interceptors are dependent objects of the bean instance they decorate. +* Instances of decorators are dependent objects of the bean instance they decorate. [[passivating_scope_full]] From af8fc822768c0bad15e773deee9d9ef083477df8 Mon Sep 17 00:00:00 2001 From: Matej Novotny Date: Thu, 29 Apr 2021 15:17:38 +0200 Subject: [PATCH 05/11] Attempt to make the Full part more readable - merge decorator limitations into one chapter. Add multiple notions of Full - specific rules cak to original chapters and note that this behaviour is not in Lite. --- spec/src/main/asciidoc/cdi-spec.asciidoc | 2 - .../main/asciidoc/core/decorators.asciidoc | 27 ++++++++ .../main/asciidoc/core/definition.asciidoc | 8 +++ .../asciidoc/core/definition_full.asciidoc | 65 ++---------------- .../asciidoc/core/implementation.asciidoc | 8 +++ .../asciidoc/core/implementation_full.adoc | 68 ------------------- .../asciidoc/core/scopescontexts.asciidoc | 2 +- 7 files changed, 49 insertions(+), 131 deletions(-) delete mode 100644 spec/src/main/asciidoc/core/implementation_full.adoc diff --git a/spec/src/main/asciidoc/cdi-spec.asciidoc b/spec/src/main/asciidoc/cdi-spec.asciidoc index 490a623ad..4f25a58c6 100644 --- a/spec/src/main/asciidoc/cdi-spec.asciidoc +++ b/spec/src/main/asciidoc/cdi-spec.asciidoc @@ -65,8 +65,6 @@ include::core/packagingdeployment_lite.asciidoc[] include::core/definition_full.asciidoc[] -include::core/implementation_full.adoc[] - include::core/inheritance_full.asciidoc[] include::core/injectionandresolution_full.asciidoc[] diff --git a/spec/src/main/asciidoc/core/decorators.asciidoc b/spec/src/main/asciidoc/core/decorators.asciidoc index 1deff44a4..354c26714 100644 --- a/spec/src/main/asciidoc/core/decorators.asciidoc +++ b/spec/src/main/asciidoc/core/decorators.asciidoc @@ -29,6 +29,7 @@ If a decorator declares any scope other than `@Dependent`, the container automat ==== Declaring a decorator A decorator is declared by annotating the bean class with the `@jakarta.decorator.Decorator` stereotype. +{cdi_full} provides this stereotype as a built-in stereotype in addition to other stereotypes defined in <>. [source, java] ---- @@ -228,3 +229,29 @@ The container intercepts the delegate invocation and searches for the first deco If no such decorator exists, the container invokes the business method of the intercepted instance. Otherwise, the container calls the method of the decorator. +[[decorator_additional_rules]] + +=== Additional decorator rules + +This chapter congregates various rules and limitations that apply to decorators in regard to other chapters of the specification. + +==== Bean names + +In addition to rules defined in <>, if a decorator has a name, non-portable behavior results. + +==== Declaring alternatives + +In addition to rules defined in <>, if a decorator is an alternative, non-portable behavior results. + +=== Managed beans + +In addition to rules defined in <>, if the bean class of a managed bean is annotated with both `@Interceptor` and `@Decorator`, the container automatically detects the problem and treats it as a definition error. + +=== Producer and disposer methods + +Decorators may not declare producer methods or fields. +If a decorator has a method or a field annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. + +Decorators may not declare disposer methods. +If a decorator has a method annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. + diff --git a/spec/src/main/asciidoc/core/definition.asciidoc b/spec/src/main/asciidoc/core/definition.asciidoc index b1ea95b6d..8a09edde1 100644 --- a/spec/src/main/asciidoc/core/definition.asciidoc +++ b/spec/src/main/asciidoc/core/definition.asciidoc @@ -29,6 +29,8 @@ The bean developer may also create interceptors or reuse existing interceptors. The interceptor bindings of a bean determine which interceptors will be applied at runtime. Interceptors are defined by Jakarta EE interceptors specification, and interceptor bindings are specified in <>. +When running in {cdi_full}, the bean developer may also create decorators or reuse existing decorators as defined in <>. + [[capabilities]] === Functionality provided by the container to the bean @@ -41,6 +43,10 @@ A bean is provided by the container with the following capabilities: * method interception, callback interception, as defined in <>, and * event notification, as defined in <>. +When running {cdi_full}, the container has to also provide the following capabilities: + +* method decoration, as defined in <> + [[bean_types]] @@ -207,6 +213,8 @@ An injection point may even specify multiple qualifiers. Qualifier types are also used as event selectors by event consumers, as defined in <>. +In {cdi_full} qualifier types are also used to bind decorators to beans, as specified in <>. + [[builtin_qualifiers]] ==== Built-in qualifier types diff --git a/spec/src/main/asciidoc/core/definition_full.asciidoc b/spec/src/main/asciidoc/core/definition_full.asciidoc index 7599afb1e..dc84917f5 100644 --- a/spec/src/main/asciidoc/core/definition_full.asciidoc +++ b/spec/src/main/asciidoc/core/definition_full.asciidoc @@ -1,36 +1,15 @@ [[concepts_full]] -CDI Full contains all the functionality defined in {cdi_lite} and adds some more features such as decorators or conversation scope which are described in following paragraphs. - -== Extended Concepts for {cdi_full} - -When running in {cdi_full}, beans must extend their capabilities defined in <>, by providing these additional capabilities: - -The bean developer may also create decorators or reuse existing decorators. -The bean types and qualifiers of a bean determine which decorators will be applied at runtime. -Decorators are defined in <>. - -[[capabilities_full]] - -=== Functionality provided by the container to the bean in {cdi_full} - -When running in {cdi_full}, the container must extend the capabilities defined in <>, by providing an additional capability: - -* method decoration, as defined in <> - -[[qualifiers_full]] - -=== Qualifiers in {cdi_full} - -In {cdi_full} qualifier types are also used to bind decorators to beans, as specified in <>. +CDI Full contains all the functionality defined in {cdi_lite} and adds some additional features such as decorators or conversation scope. +Some of these concepts were briefly mentioned in the previous {cdi_lite} chapter and this section of specification defines them in depth. [[scopes_full]] -=== Scopes in {cdi_full} +== Scopes in {cdi_full} [[builtin_scopes_full]] -==== Built-in scope types in {cdi_full} +=== Built-in scope types in {cdi_full} {cdi_full} adds a new standard scope to those defined in <> @@ -38,43 +17,9 @@ In {cdi_full} qualifier types are also used to bind decorators to beans, as spec [[bean_defining_annotations_full]] -==== Bean defining annotations in {cdi_full} +=== Bean defining annotations in {cdi_full} {cdi_full} adds the following annotations to the set of bean defining annotations : * `@ConversationScoped` annotation, * `@Decorator` annotation. - -[[names_full]] - -=== Bean names in {cdi_full} - -[[beans_with_no_name_full]] - -==== Beans with no name in {cdi_full} - -In addition to rules defined in <>, when running in {cdi_full} bean names have also the following restriction: - -If a decorator has a name, non-portable behavior results. - -[[alternatives_full]] - -=== Alternatives in {cdi_full} - -[[declaring_alternative_full]] - -==== Declaring an alternative in {cdi_full} - -In addition to rules defined in <>, when running in {cdi_full} alternative have also the following restriction: - -If a decorator is an alternative, non-portable behavior results. - -[[stereotypes_full]] - -=== Stereotypes in {cdi_full} - -[[builtin_stereotypes_full]] - -==== Built-in stereotypes in {cdi_full} - -In addition to built-in stereotypes defined in <>, {cdi_full} provides the special-purpose `@Decorator` stereotype, defined in <>. diff --git a/spec/src/main/asciidoc/core/implementation.asciidoc b/spec/src/main/asciidoc/core/implementation.asciidoc index a88fa71ea..eb6245532 100644 --- a/spec/src/main/asciidoc/core/implementation.asciidoc +++ b/spec/src/main/asciidoc/core/implementation.asciidoc @@ -39,6 +39,10 @@ A Java class is a managed bean if it meets all of the following conditions: ** the class has a constructor with no parameters, or ** the class declares a constructor annotated `@Inject`. +In {cdi_full}, a Java class is a managed bean if: + +* It is a non-abstract class, or is annotated `@Decorator`. + All Java classes that meet these conditions are managed beans and thus no special declaration is required to define a managed bean. If packages annotated `@Vetoed` are split across classpath entries, non-portable behavior results. @@ -715,6 +719,10 @@ A bean type must be proxyable if an injection point resolves to a bean: * that requires a client proxy, or * that has a bound interceptor. +In {cdi_full}, a bean be proxyable if an injection point resolves to a bean: + +* that has an associated decorator. + Otherwise, the container automatically detects the problem, and treats it as a deployment problem. diff --git a/spec/src/main/asciidoc/core/implementation_full.adoc b/spec/src/main/asciidoc/core/implementation_full.adoc deleted file mode 100644 index beb179292..000000000 --- a/spec/src/main/asciidoc/core/implementation_full.adoc +++ /dev/null @@ -1,68 +0,0 @@ -[[implementation_full]] - -== Programming model in {cdi_full} - -[[managed_beans_full]] - -=== Managed beans in {cdi_full} - -In addition to rules defined in <>, the following applies when running in {cdi_full}: - -If the bean class of a managed bean is annotated with both `@Interceptor` and `@Decorator`, the container automatically detects the problem and treats it as a definition error. - -[[what_classes_are_beans_full]] - -==== Which Java classes are managed beans in {cdi_full}? - -When running in {cdi_full}, a Java class may also be a manged bean if it meets all conditions defined in <> and the following: - -* It is a non-abstract class, or is annotated `@Decorator`. - -[[producer_method_full]] - -=== Producer methods in {cdi_full} - -[[declaring_producer_method_full]] - -==== Declaring a producer method in {cdi_full} - -In addition to rules defined in <>, when running in {cdi_full}, the following applies: - -Decorators may not declare producer methods. -If a decorator has a method annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. - -[[producer_field_full]] - -=== Producer fields in {cdi_full} - -[[declaring_producer_field_full]] - -==== Declaring a producer field in {cdi_full} - -In addition to rules defined in <>, when running in {cdi_full}, the following applies: - -Decorators may not declare producer fields. -If a decorator has a field annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. - -[[disposer_method_full]] - -=== Disposer methods in {cdi_full} - -[[declaring_disposer_method_full]] - -==== Declaring a disposer method in {cdi_full} - -In addition to rules defined in <>, when running in {cdi_full}, the following applies: - -Decorators may not declare disposer methods. -If a decorator has a method annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. - -[[unproxyable_full]] - -=== Unproxyable bean types in {cdi_full} - -In addition to rules defined in <>, when running in {cdi_full}, the following applies: - -A bean type must be proxyable if an injection point resolves to a bean: - -* that has an associated decorator. \ No newline at end of file diff --git a/spec/src/main/asciidoc/core/scopescontexts.asciidoc b/spec/src/main/asciidoc/core/scopescontexts.asciidoc index b54f24c25..f1ee16332 100644 --- a/spec/src/main/asciidoc/core/scopescontexts.asciidoc +++ b/spec/src/main/asciidoc/core/scopescontexts.asciidoc @@ -187,7 +187,7 @@ The `@Dependent` scope is always active. Many instances of beans with scope `@Dependent` belong to some other bean and are called _dependent objects_. -* Instances interceptors are dependent objects of the bean instance they decorate. +* Instances of interceptors are dependent objects of the bean instance they decorate. * An instance of a bean with scope `@Dependent` injected into a field, bean constructor or initializer method is a dependent object of the bean into which it was injected. * An instance of a bean with scope `@Dependent` injected into a producer method is a dependent object of the producer method bean instance that is being produced. * An instance of a bean with scope `@Dependent` obtained by direct invocation of an `Instance` is a dependent object of the instance of `Instance`. From 2717c299f32a3b6c2e81d26039b23f52b0ac74b4 Mon Sep 17 00:00:00 2001 From: Matej Novotny Date: Mon, 3 May 2021 10:40:29 +0200 Subject: [PATCH 06/11] Split interceptors chapter into Lite and Full, state that Lite only support inteception declaring with bindings. --- spec/src/main/asciidoc/cdi-spec.asciidoc | 2 + .../main/asciidoc/core/interceptors.asciidoc | 48 ++--------------- .../asciidoc/core/interceptors_full.asciidoc | 52 +++++++++++++++++++ 3 files changed, 58 insertions(+), 44 deletions(-) create mode 100644 spec/src/main/asciidoc/core/interceptors_full.asciidoc diff --git a/spec/src/main/asciidoc/cdi-spec.asciidoc b/spec/src/main/asciidoc/cdi-spec.asciidoc index 4f25a58c6..cff814156 100644 --- a/spec/src/main/asciidoc/cdi-spec.asciidoc +++ b/spec/src/main/asciidoc/cdi-spec.asciidoc @@ -71,6 +71,8 @@ include::core/injectionandresolution_full.asciidoc[] include::core/scopescontexts_full.asciidoc[] +include::core/interceptors_full.asciidoc[] + include::core/decorators.asciidoc[] include::core/spi.asciidoc[] diff --git a/spec/src/main/asciidoc/core/interceptors.asciidoc b/spec/src/main/asciidoc/core/interceptors.asciidoc index ce93aa2b4..e127cf86d 100644 --- a/spec/src/main/asciidoc/core/interceptors.asciidoc +++ b/spec/src/main/asciidoc/core/interceptors.asciidoc @@ -5,7 +5,9 @@ Managed beans support interception. _Interceptors_ are used to separate cross-cutting concerns from business logic. The Java Interceptors specification defines the basic programming model and semantics, and how to associate interceptors with target classes. -This specification defines various extensions to the Java Interceptors specification, including how to override the interceptor order defined by the `@Priority` annotation. +This specification defines various extensions to the Java Interceptors specification, including non-binding annotation values in interceptor resolution. + +In CDI Lite environment, the only portable way to bind an interceptor to a bean is via interceptor bindings. `@Interceptors` annotation is not supported. [[interceptor_bindings]] @@ -40,6 +42,7 @@ If a stereotype declares interceptor bindings, it must be defined as `@Target(TY This specification extends the Java Interceptors specification and defines how the container must behave if a definition error is encountered. +If an interceptor declares any scope other than `@Dependent`, the container automatically detects the problem and treats it as a definition error. [[binding_interceptor_to_bean]] @@ -51,56 +54,13 @@ This specification extends the Java Interceptors specification and defines: * how the container must behave if a definition error is encountered, and * how interceptors are bound using stereotypes. -Interceptor bindings may be used to associate interceptors with any managed bean that is not a decorator. - The set of interceptor bindings for a method declared at class level includes those declared on stereotypes. An interceptor binding declared on a bean class replaces an interceptor binding of the same type declared by a stereotype that is applied to the bean class. The set of interceptor bindings for a producer method is not used to associate interceptors with the return value of the producer method. -Since CDI 2.0 it is possible to apply interceptors programmatically to the return value of a producer method, with the `InterceptionFactory` interface as defined in <>. - If a managed bean has a class-level or method-level interceptor binding, the managed bean must be a proxyable bean type, as defined in <>. -[[enabled_interceptors]] - -=== Interceptor enablement and ordering - -This specification extends the Java Interceptors specification and defines: - -* support for enabling interceptors only for a bean archive, as defined by Contexts and Dependency Injection 1.0, and -* the ability to override the interceptor order using the portable extension SPI, defined in <>. - -An interceptor may be explicitly enabled for a bean archive by listing its class under the `` element of the `beans.xml` file of the bean archive. - -[source,xml] ----- - - - com.acme.myfwk.TransactionInterceptor - com.acme.myfwk.LoggingInterceptor - - ----- - -The order of the interceptor declarations determines the interceptor ordering. Interceptors which occur earlier in the list are called first. - -Each child `` element must specify the name of an interceptor class. -If there is no class with the specified name, or if the class with the specified name is not an interceptor class, the container automatically detects the problem and treats it as a deployment problem. - -If the same class is listed twice under the `` element, the container automatically detects the problem and treats it as a deployment problem. - -Interceptors enabled using `@Priority` are called before interceptors enabled using `beans.xml`. - -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 <>. - -If an interceptor declares any scope other than `@Dependent`, the container automatically detects the problem and treats it as a definition error. - -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]] === Interceptor resolution diff --git a/spec/src/main/asciidoc/core/interceptors_full.asciidoc b/spec/src/main/asciidoc/core/interceptors_full.asciidoc new file mode 100644 index 000000000..85bd5a3de --- /dev/null +++ b/spec/src/main/asciidoc/core/interceptors_full.asciidoc @@ -0,0 +1,52 @@ +[[interceptors_full]] + +== Interceptors in CDI Full + +In CDI Full environment, interceptors are supported to the extent defined in Java Interceptors specification. That includes, for instance, `@Interceptors` annotation. + +There is also few more features available in CDI Full environment including the ability to override interceptor order defined by `@Priority` annotation. + +[[binding_interceptor_to_bean_full]] + +=== Binding an interceptor to a bean in CDI Full + +Interceptor bindings may be used to associate interceptors with any managed bean that is not a decorator. + +It is possible to apply interceptors programmatically to the return value of a producer method, with the `InterceptionFactory` interface as defined in <>. + +[[enabled_interceptors_full]] + +=== Interceptor enablement and ordering in CDI Full + +This specification extends the Java Interceptors specification and defines: + +* support for enabling interceptors only for a bean archive, as defined by Contexts and Dependency Injection 1.0, and +* the ability to override the interceptor order using the portable extension SPI, defined in <>. + +An interceptor may be explicitly enabled for a bean archive by listing its class under the `` element of the `beans.xml` file of the bean archive. + +[source,xml] +---- + + + com.acme.myfwk.TransactionInterceptor + com.acme.myfwk.LoggingInterceptor + + +---- + +The order of the interceptor declarations determines the interceptor ordering. Interceptors which occur earlier in the list are called first. + +Each child `` element must specify the name of an interceptor class. +If there is no class with the specified name, or if the class with the specified name is not an interceptor class, the container automatically detects the problem and treats it as a deployment problem. + +If the same class is listed twice under the `` element, the container automatically detects the problem and treats it as a deployment problem. + +Interceptors enabled using `@Priority` are called before interceptors enabled using `beans.xml`. + +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 <>. + +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. \ No newline at end of file From ac06dcd3ab1b663ed07548a0763fdf9c5b6dce30 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Tue, 4 May 2021 13:38:11 +0200 Subject: [PATCH 07/11] comprehensive review and various Lite/Full split changes --- spec/src/main/asciidoc/architecture.asciidoc | 21 +- spec/src/main/asciidoc/cdi-spec.asciidoc | 6 + .../asciidoc/core/beanmanager_lite.asciidoc | 268 ++++++++++++++++++ .../main/asciidoc/core/decorators.asciidoc | 43 ++- .../main/asciidoc/core/definition.asciidoc | 35 ++- .../asciidoc/core/definition_full.asciidoc | 20 +- spec/src/main/asciidoc/core/events.asciidoc | 25 +- .../main/asciidoc/core/events_full.asciidoc | 22 ++ .../asciidoc/core/implementation.asciidoc | 75 +---- .../main/asciidoc/core/inheritance.asciidoc | 2 + .../asciidoc/core/inheritance_full.asciidoc | 57 ++++ .../core/injectionandresolution.asciidoc | 44 ++- .../core/injectionandresolution_full.asciidoc | 67 ++++- .../main/asciidoc/core/interceptors.asciidoc | 19 +- .../asciidoc/core/interceptors_full.asciidoc | 16 +- .../src/main/asciidoc/core/lifecycle.asciidoc | 9 +- .../core/packagingdeployment_lite.asciidoc | 1 + .../asciidoc/core/scopescontexts.asciidoc | 164 +---------- .../core/scopescontexts_full.asciidoc | 114 ++++++-- spec/src/main/asciidoc/core/spi.asciidoc | 231 +++------------ spec/src/main/asciidoc/core/spi_lite.asciidoc | 4 + .../asciidoc/javaee/definition_ee.asciidoc | 2 +- .../main/asciidoc/javaee/events_ee.asciidoc | 2 +- .../javaee/implementation_ee.asciidoc | 2 +- .../javaee/injectionandresolution_ee.asciidoc | 6 +- .../javaee/javaeeintegration.asciidoc | 4 +- .../javaee/packagingdeployment_ee.asciidoc | 4 +- spec/src/main/asciidoc/javaee/spi_ee.asciidoc | 8 +- .../asciidoc/javase/bootstrap_se.asciidoc | 6 +- spec/src/main/asciidoc/javase/javase.asciidoc | 1 + .../javase/packagingdeployment_se.asciidoc | 2 +- spec/src/main/asciidoc/preface.asciidoc | 19 +- 32 files changed, 754 insertions(+), 545 deletions(-) create mode 100644 spec/src/main/asciidoc/core/beanmanager_lite.asciidoc create mode 100644 spec/src/main/asciidoc/core/events_full.asciidoc diff --git a/spec/src/main/asciidoc/architecture.asciidoc b/spec/src/main/asciidoc/architecture.asciidoc index 17a41db07..558418300 100644 --- a/spec/src/main/asciidoc/architecture.asciidoc +++ b/spec/src/main/asciidoc/architecture.asciidoc @@ -7,10 +7,10 @@ This specification defines a powerful set of complementary services that help to * A sophisticated, typesafe _dependency injection_ mechanism, including the ability to select dependencies at either development or deployment time, without verbose configuration * Support for Jakarta EE modularity and the Jakarta EE component architecture - the modular structure of a Jakarta EE application is taken into account when resolving dependencies between Jakarta EE components * Integration with the Jakarta Unified Expression Language (EL), allowing any contextual object to be used directly within a Jakarta Server Faces or JSP page -* The ability to _decorate_ injected objects +* The ability to _decorate_ injected objects (only in {cdi_full} environment) * The ability to associate interceptors to objects via typesafe _interceptor bindings_ * An _event notification_ model -* A web _conversation context_ in addition to the three standard web contexts defined by the Jakarta Servlets specification +* A web _conversation context_ in addition to the three standard web contexts defined by the Jakarta Servlets specification (only in {cdi_full} environment) * An SPI allowing _portable extensions_ to integrate cleanly with the container @@ -27,7 +27,7 @@ In particular, Jakarta Enterprise Bean components may be used as Jakarta Server It's even possible to integrate with third-party frameworks. A portable extension may provide objects to be injected or obtain contextual instances using the dependency injection service. The framework may even raise and observe events using the event notification service. -An application that takes advantage of these services may be designed to execute in either the Jakarta EE environment or the Java SE environment. +An application that takes advantage of these services may be designed to execute in the Jakarta EE environment, the Java SE environment, or in other environments that implement {cdi_lite}. If the application uses Jakarta EE services such as transaction management and persistence in the Java SE environment, the services are usually restricted to, at most, the subset defined for embedded usage by the Jakarta Enterprise Bean specification. === Contracts @@ -41,13 +41,15 @@ This specification defines the responsibilities of: This runtime environment is called the _container_. For example, the container might be a Jakarta EE container or an embeddable Jakarta Enterprise Bean container. -<>, <>, <>, <>, <> and <> define the programming model for Jakarta EE components that take advantage of the services defined by this specification, the responsibilities of the component developer, and the annotations used by the component developer to specify metadata. +<>, <>, <>, <> and <> define the programming model for application components that take advantage of the services defined by this specification, the responsibilities of the component developer, and the annotations used by the component developer to specify metadata. +{cdi_full} adds <> and <>. -<>, <>, <>, <>, <> and <> 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. +<>, <>, <>, <> and <> 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 <>. -<> defines how Jakarta EE 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. +<> and <> 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. -<>, <> and <> define an SPI that allows portable extensions to integrate with the container. +<>, <>, <> and <> define an SPI that allows portable extensions to integrate with the container. === Relationship to other specifications @@ -550,6 +552,11 @@ The invocation will proceed to the `DocumentEditor` class only if the authorizat ==== Decorator example +[NOTE] +==== +Decorators are only available in {cdi_full}. +==== + _Decorators_ are similar to interceptors, but apply only to beans of a particular Java interface. Like interceptors, decorators may be easily enabled or disabled at deployment time. Unlike interceptors, decorators are aware of the semantics of the intercepted method. For example, the `DataAccess` interface might be implemented by many beans: diff --git a/spec/src/main/asciidoc/cdi-spec.asciidoc b/spec/src/main/asciidoc/cdi-spec.asciidoc index cff814156..721f02268 100644 --- a/spec/src/main/asciidoc/cdi-spec.asciidoc +++ b/spec/src/main/asciidoc/cdi-spec.asciidoc @@ -53,6 +53,8 @@ include::core/interceptors.asciidoc[] include::core/events.asciidoc[] +include::core/beanmanager_lite.asciidoc + include::core/spi_lite.asciidoc[] include::core/packagingdeployment_lite.asciidoc[] @@ -75,6 +77,10 @@ include::core/interceptors_full.asciidoc[] include::core/decorators.asciidoc[] +include::core/interceptors_full.asciidoc[] + +include::core/events_full.asciidoc[] + include::core/spi.asciidoc[] include::core/packagingdeployment.asciidoc[] diff --git a/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc b/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc new file mode 100644 index 000000000..f8715090e --- /dev/null +++ b/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc @@ -0,0 +1,268 @@ +[[programmatic_access]] + +== Programmatic access to container + +CDI 3.0 used to provide a single `BeanManager` object, which allows access to many useful operations. +In CDI 4.0, this is split into `BeanManagerLite` and `BeanManager`. + +`BeanManagerLite` provides access to a subset of `BeanManager` features which can be implemented in more restricted environments; +It is available in {cdi_lite} environments. + +`BeanManager` extends `BeanManagerLite` and provides the remaining features. +It is available in {cdi_full} environments. + +In {cdi_lite} environment, attempting to obtain a `BeanManager` or invoking methods on it results in non-portable behavior. + +[[beanmanager]] + +=== The `BeanManagerLite` object + +The interface `jakarta.enterprise.inject.spi.BeanManagerLite` provides operations for obtaining contextual references for beans, along with many other operations of use to applications. + +The container provides a built-in bean with bean type `BeanManagerLite`, scope `@Dependent` and qualifier `@Default`. +Thus, any bean may obtain an instance of `BeanManagerLite` by injecting it: + +[source, java] +---- +@Inject BeanManagerLite manager; +---- + +The operations of `BeanManagerLite` may be called at any time during the execution of the application. + +[[provider]] + +==== Obtaining a reference to the CDI container + +Application objects sometimes interact directly with the container via programmatic API call. +The abstract class `jakarta.enterprise.inject.spi.CDI` provides access to the `BeanManagerLite` as well providing lookup of bean instances. + +[source, java] +---- +public abstract class CDI implements Instance { + public static CDI current() { ... } + public static void setCDIProvider(CDIProvider provider); + public abstract BeanManagerLite getBeanManagerLite(); + public abstract BeanManager getBeanManager(); +} +---- + +An object may obtain a reference to the current container by calling `CDI.current()`. +`CDI.getBeanManagerLite()`, as well as other methods on `CDI`, may be called after the application initialization is completed until the application shutdown starts. +If methods on `CDI` are called at any other time, non-portable behavior results. + +`CDI` implements `jakarta.enterprise.inject.Instance` and therefore might be used to perform programmatic lookup as defined in <>. +If no qualifier is passed to `CDI.select()` method, the `@Default` qualifier is assumed. + +When `CDI.current()` is called, `getCDI()` method is called on `jakarta.enterprise.inject.spi.CDIProvider`. + +The `CDIProvider` to use may be set by the application or container using the `setCDIProvider()` method. +If the `setCDIProvider()` has not been called, the service provider with highest priority of the service `jakarta.enterprise.inject.spi.CDIProvider` declared in META-INF/services is used. +The order of more than one `CDIProvider` with the same priority is undefined. +If no provider is available an `IllegalStateException` is thrown. + +[source, java] +---- +public interface CDIProvider extends Prioritized { + CDI getCDI(); + default int getPriority(); +} +---- + +* `getPriority()` method is inherited from <> and returns the priority for the `CDIProvider`. +If this method is not implemented the default priority `0` is assumed. + + +[[bm_obtain_contextual_reference]] + +==== Obtaining a contextual reference for a bean + +The method `BeanManagerLite.getReference()` returns a contextual reference for a given bean and bean type, as defined in <>. + +[source, java] +---- +public Object getReference(Bean bean, Type beanType, CreationalContext ctx); +---- + +The first parameter is the `Bean` object representing the bean. +The second parameter represents a bean type that must be implemented by any client proxy that is returned. +The third parameter is an instance of `CreationalContext` that may be used to destroy any object with scope `@Dependent` that is created. + +If the given type is not a bean type of the given bean, an `IllegalArgumentException` is thrown. + +[[bm_obtain_injectable_reference]] + +==== Obtaining an injectable reference + +The method `BeanManagerLite.getInjectableReference()` returns an injectable reference for a given injection point, as defined in <>. + +[source, java] +---- +public Object getInjectableReference(InjectionPoint ij, CreationalContext ctx); +---- + +The first parameter represents the target injection point. +The second parameter is an instance of `CreationalContext` that may be used to destroy any object with scope `@Dependent` that is created. + +If typesafe resolution results in an unsatisfied dependency, the container must throw an `UnsatisfiedResolutionException`. If typesafe resolution results in an unresolvable ambiguous dependency, the container must throw an `AmbiguousResolutionException`. + +Implementations of `Bean` usually maintain a reference to an instance of `BeanManagerLite`. When the `Bean` implementation performs dependency injection, it must obtain the contextual instances to inject by calling `BeanManagerLite.getInjectableReference()`, passing an instance of `InjectionPoint` that represents the injection point and the instance of `CreationalContext` that was passed to `Bean.create()`. + +[[bm_obtain_creationalcontext]] + +==== Obtaining a `CreationalContext` + +An instance of `CreationalContext` for a certain instance of `Contextual` may be obtained by calling `BeanManagerLite.createCreationalContext()`. + +[source, java] +---- +public CreationalContext createCreationalContext(Contextual contextual); +---- + +An instance of `CreationalContext` for a non-contextual object may be obtained by passing a null value to `createCreationalContext()`. + +[[bm_obtain_bean_by_type]] + +==== Obtaining a `Bean` by type + +The method `BeanManagerLite.getBeans()` returns the set of beans which have the given required type and qualifiers and are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules for candidates of typesafe resolution defined in <>. + +[source, java] +---- +public Set> getBeans(Type beanType, Annotation... qualifiers); +---- + +The first parameter is a required bean type. The remaining parameters are required qualifiers. + +If no qualifiers are passed to `getBeans()`, the default qualifier `@Default` is assumed. + +If the given type represents a type variable, an `IllegalArgumentException` is thrown. + +If two instances of the same non repeating qualifier type are given, an `IllegalArgumentException` is thrown. + +If an instance of an annotation that is not a qualifier type is given, an `IllegalArgumentException` is thrown. + +[[bm_obtain_bean_by_name]] + +==== Obtaining a `Bean` by name + +The method `BeanManagerLite.getBeans()` which accepts a string returns the set of beans which have the given bean name and are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules of name resolution defined in <>. + +[source, java] +---- +public Set> getBeans(String name); +---- + +The parameter is a bean name. + +[[bm_resolve_ambiguous_dep]] + +==== Resolving an ambiguous dependency + +The method `BeanManagerLite.resolve()` applies the ambiguous dependency resolution rules defined in <> to a set of `Bean` s. + +[source, java] +---- +public Bean resolve(Set> beans); +---- + +If the ambiguous dependency resolution rules fail (as defined in <>, the container must throw an `AmbiguousResolutionException`. + +`BeanManagerLite.resolve()` must return null if: + +* null is passed to `resolve()`, or +* no beans are passed to `resolve()`. + +[[bm_fire_event]] + +==== Firing an event + +The method `BeanManagerLite.getEvent()` returns an instance of `Event` with specified type `java.lang.Object` and specified qualifier `@Default`. + +[source, java] +---- +Event getEvent(); +---- + +The returned instance can be used like a standard `Event` as described in <>. + +[[bm_observer_method_resolution]] + +==== Observer method resolution + +The method `BeanManagerLite.resolveObserverMethods()` resolves observer methods for an event according to the rules of observer resolution defined in <>. + +[source, java] +---- +public Set> resolveObserverMethods(T event, Annotation... qualifiers); +---- + +The first parameter of `resolveObserverMethods()` is the event object. +The remaining parameters are event qualifiers. + +If the runtime type of the event object contains a type variable, an `IllegalArgumentException` is thrown. + +If two instances of the same non repeating qualifier type are given, an `IllegalArgumentException` is thrown. + +If an instance of an annotation that is not a qualifier type is given, an `IllegalArgumentException` is thrown. + +[[bm_interceptor_resolution]] + +==== Interceptor resolution + +The method `BeanManagerLite.resolveInterceptors()` returns the ordered list of interceptors for a set of interceptor bindings and a type of interception and which are enabled in the module or library containing the class into which the `BeanManagerLite` was injected, as defined in <>. + +[source, java] +---- +List> resolveInterceptors(InterceptionType type, + Annotation... interceptorBindings); +---- + +If two instances of the same non repeating interceptor binding type are given, an `IllegalArgumentException` is thrown. + +If no interceptor binding type instance is given, an `IllegalArgumentException` is thrown. + +If an instance of an annotation that is not an interceptor binding type is given, an `IllegalArgumentException` is thrown. + +[[bm_determining_annotation]] + +==== Determining if an annotation is a qualifier type, scope type, stereotype or interceptor binding type + +An application may test an annotation to determine if it is a qualifier type, scope type, stereotype or interceptor binding type, or determine if a scope type is a normal scope. + +[source, java] +---- +public boolean isScope(Class annotationType); +public boolean isNormalScope(Class scopeType); + +public boolean isQualifier(Class annotationType); +public boolean isInterceptorBinding(Class annotationType); +public boolean isStereotype(Class annotationType); +---- + +[[bm_obtain_active_context]] + +==== Obtaining the active `Context` for a scope + +The method `BeanManagerLite.getContext()` retrieves an active context object associated with the given scope, as defined in <>. + +[source, java] +---- +public Context getContext(Class scopeType); +---- + +[[bm_obtain_instance]] + +==== Obtain an `Instance` + +The method `BeanManagerLite.createInstance()` returns an `Instance` to request bean instances programmatically as described in <>. + +The returned `Instance` object can only access instances of beans that are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules defined in <>. + +[source, java] +---- +Instance createInstance(); +---- + +Instances of dependent scoped beans obtained with this `Instance` object must be explicitly released by calling `Instance.destroy()` method. + +If no qualifier is passed to `Instance.select()` method, the `@Default` qualifier is assumed. diff --git a/spec/src/main/asciidoc/core/decorators.asciidoc b/spec/src/main/asciidoc/core/decorators.asciidoc index 354c26714..3b3f0eb34 100644 --- a/spec/src/main/asciidoc/core/decorators.asciidoc +++ b/spec/src/main/asciidoc/core/decorators.asciidoc @@ -29,7 +29,6 @@ If a decorator declares any scope other than `@Dependent`, the container automat ==== Declaring a decorator A decorator is declared by annotating the bean class with the `@jakarta.decorator.Decorator` stereotype. -{cdi_full} provides this stereotype as a built-in stereotype in addition to other stereotypes defined in <>. [source, java] ---- @@ -237,21 +236,49 @@ This chapter congregates various rules and limitations that apply to decorators ==== Bean names -In addition to rules defined in <>, if a decorator has a name, non-portable behavior results. +In addition to rules defined in <>, the following rules apply. -==== Declaring alternatives +If a decorator has a name, non-portable behavior results. -In addition to rules defined in <>, if a decorator is an alternative, non-portable behavior results. +==== Alternatives + +In addition to rules defined in <>, the following rules apply. + +If a decorator is an alternative, non-portable behavior results. === Managed beans -In addition to rules defined in <>, if the bean class of a managed bean is annotated with both `@Interceptor` and `@Decorator`, the container automatically detects the problem and treats it as a definition error. +In addition to rules defined in <>, the following rules apply. + +If the bean class of a managed bean is annotated with both `@Interceptor` and `@Decorator`, the container automatically detects the problem and treats it as a definition error. + +=== Producer methods + +In addition to rules defined in <>, the following rules apply. + +Decorators may not declare producer methods. +If a decorator has a method annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. + +=== Producer fields -=== Producer and disposer methods +In addition to rules defined in <>, the following rules apply. -Decorators may not declare producer methods or fields. -If a decorator has a method or a field annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. +Decorators may not declare producer fields. +If a decorator has a field annotated `@Produces`, the container automatically detects the problem and treats it as a definition error. + +=== Disposer methods + +In addition to rules defined in <>, the following rules apply. Decorators may not declare disposer methods. If a decorator has a method annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. +=== Unproxyable bean types + +In addition to rules defined in <>, the following rules apply. + +A bean type must be proxyable if an injection point resolves to a bean: + +* that has an associated decorator. + +Otherwise, the container automatically detects the problem, and treats it as a deployment problem. diff --git a/spec/src/main/asciidoc/core/definition.asciidoc b/spec/src/main/asciidoc/core/definition.asciidoc index 8a09edde1..e3eeee155 100644 --- a/spec/src/main/asciidoc/core/definition.asciidoc +++ b/spec/src/main/asciidoc/core/definition.asciidoc @@ -29,7 +29,9 @@ The bean developer may also create interceptors or reuse existing interceptors. The interceptor bindings of a bean determine which interceptors will be applied at runtime. Interceptors are defined by Jakarta EE interceptors specification, and interceptor bindings are specified in <>. -When running in {cdi_full}, the bean developer may also create decorators or reuse existing decorators as defined in <>. +In {cdi_full} environment, the bean developer may also create decorators or reuse existing decorators. +The bean types and qualifiers of a bean determine which decorators will be applied at runtime. +Decorators are defined in <>. [[capabilities]] @@ -43,9 +45,9 @@ A bean is provided by the container with the following capabilities: * method interception, callback interception, as defined in <>, and * event notification, as defined in <>. -When running {cdi_full}, the container has to also provide the following capabilities: +In {cdi_full} environment, the container also provides the following capabilities: -* method decoration, as defined in <> +* decoration, as defined in <>. [[bean_types]] @@ -213,7 +215,7 @@ An injection point may even specify multiple qualifiers. Qualifier types are also used as event selectors by event consumers, as defined in <>. -In {cdi_full} qualifier types are also used to bind decorators to beans, as specified in <>. +In {cdi_full} environment, qualifier types are also used to bind decorators to beans, as specified in <>. [[builtin_qualifiers]] @@ -470,6 +472,19 @@ For example, an object that represents the current user is represented by a sess @Produces @SessionScoped User getCurrentUser() { ... } ---- +An object that represents an order is represented by a conversation scoped object: + +[source, java] +---- +@ConversationScoped +public class Order { ... } +---- + +[NOTE] +==== +Conversations are only available in {cdi_full}. +==== + A list that contains the results of a search screen might be represented by a request scoped object: [source, java] @@ -486,7 +501,7 @@ The set of scope types is extensible. There are four standard scope types defined in {cdi_lite}, all defined in the package `jakarta.enterprise.context`. -* The container must provide an implementation of the @RequestScoped, @ApplicationScoped and @SessionScoped annotations defined in <>. +* The container must provide an implementation of the `@RequestScoped`, `@ApplicationScoped` and `@SessionScoped` annotations defined in <>. Note that these standard scopes can be extended by third-party extensions as defined in <> * Finally, there is a `@Dependent` pseudo-scope for dependent objects, as defined in <>. @@ -500,7 +515,7 @@ If an interceptor has any scope other than `@Dependent`, non-portable behavior r A scope type is a Java annotation defined as `@Retention(RUNTIME)`. Typically a scope type is defined as `@Target({TYPE, METHOD, FIELD})`. All scope types must also specify the `@jakarta.inject.Scope` or `@jakarta.enterprise.context.NormalScope` meta-annotation. A scope type must not have any attributes. -If a scope type has attributes non-portable behavior results. +If a scope type has attributes, non-portable behavior results. For example, the following annotation declares a "business process scope": @@ -515,6 +530,8 @@ public @interface BusinessProcessScoped {} Custom scopes are normally defined by portable extensions, which must also provide a _context object_, as defined in <>, that implements the custom scope. +// TODO mention build compatible extensions, as they require providing a _class_, not an object + [[declaring_bean_scope]] ==== Declaring the bean scope @@ -619,6 +636,8 @@ public class CoffeeShop Note that to ensure compatibility with other Jakarta Dependency Injection implementations, all pseudo-scope annotations except `@Dependent` *are not* bean defining annotations. However, a stereotype annotation including a pseudo-scope annotation *is* a bean defining annotation. +// TODO we might be able to make `@Singleton` a bean defining annotation in Lite? depending on how we decide on the beans.xml thing + [[names]] === Bean names @@ -717,6 +736,8 @@ A stereotype may also specify that: A bean may declare zero, one or multiple stereotypes. +// TODO how about we finally allowed declaring `@Priority` on stereotypes? + [[defining_new_stereotype]] ==== Defining new stereotypes @@ -893,7 +914,7 @@ There are three kinds of problem: * Definition errors - occur when a single bean definition violates the rules of this specification. If a definition error exists, the container must throw a subclass of `jakarta.enterprise.inject.spi.DefinitionException`. -* Deployment problems - occur when there are problems resolving dependencies, or inconsistent specialization, in a particular deployment. +* Deployment problems - occur when there are problems resolving dependencies, or inconsistent specialization (in {cdi_full}), in a particular deployment. If a deployment problem occurs, the container must throw a subclass of `jakarta.enterprise.inject.spi.DeploymentException`. * Exceptions - occur at runtime diff --git a/spec/src/main/asciidoc/core/definition_full.asciidoc b/spec/src/main/asciidoc/core/definition_full.asciidoc index dc84917f5..96b8b697f 100644 --- a/spec/src/main/asciidoc/core/definition_full.asciidoc +++ b/spec/src/main/asciidoc/core/definition_full.asciidoc @@ -1,6 +1,6 @@ [[concepts_full]] -CDI Full contains all the functionality defined in {cdi_lite} and adds some additional features such as decorators or conversation scope. +{cdi_full} contains all the functionality defined in {cdi_lite} and adds some additional features such as specialization, decorators or conversation scope. Some of these concepts were briefly mentioned in the previous {cdi_lite} chapter and this section of specification defines them in depth. [[scopes_full]] @@ -11,15 +11,27 @@ Some of these concepts were briefly mentioned in the previous {cdi_lite} chapter === Built-in scope types in {cdi_full} -{cdi_full} adds a new standard scope to those defined in <> +In addition to built-in scope types defined in <>, the following built-in scope is present: -* The `@ConversationScoped` annotation represents the conversation scope defined in <>. +* The `@ConversationScoped` annotation represents the conversation scope defined in <>. + +In addition to rules defined in <>, the following rules apply. + +If a decorator has any scope other than `@Dependent`, non-portable behavior results. [[bean_defining_annotations_full]] === Bean defining annotations in {cdi_full} -{cdi_full} adds the following annotations to the set of bean defining annotations : +In addition to bean defining annotations defined in <>, the following bean defining annotations are present: * `@ConversationScoped` annotation, * `@Decorator` annotation. + +[[builtin_stereotypes_full]] + +==== Built-in stereotypes in {cdi_full} + +In addition to built-in stereotypes defined in <>, the following built-in stereotype is present. + +The special-purpose `@Decorator` stereotype is defined in <>. diff --git a/spec/src/main/asciidoc/core/events.asciidoc b/spec/src/main/asciidoc/core/events.asciidoc index da13a037e..5361599f2 100644 --- a/spec/src/main/asciidoc/core/events.asciidoc +++ b/spec/src/main/asciidoc/core/events.asciidoc @@ -2,11 +2,6 @@ == Events -[NOTE] -==== -This section has reference to extension. They should be moved in a specific "event" section in full section -==== - Beans may produce and consume events. This facility allows beans to interact in a completely decoupled fashion, with no compile-time dependency between the interacting beans. Most importantly, it allows stateful beans in one architectural tier of the application to synchronize their internal state with state changes that occur in a different tier. @@ -177,7 +172,7 @@ The following elements are container specific: * the default `Executor` used by the container when `fireAsync()` is called without specifying an `Executor`, * the `CompletionStage` returned by `fireAsync` methods, and -* all dependent stages of this initial CompletionStage. +* all dependent stages of this initial `CompletionStage`. If the runtime type of the event object contains an unresolvable type variable, an `IllegalArgumentException` is thrown. @@ -199,6 +194,7 @@ The container must provide a built-in bean with: If an injection point of raw type `Event` is defined, the container automatically detects the problem and treats it as a definition error. The built-in implementation must be a passivation capable dependency, as defined in <>. +// TODO move passivation to Full? [[observer_resolution]] @@ -223,6 +219,7 @@ 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 <>, 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]] @@ -230,7 +227,7 @@ For a custom implementation of the `ObserverMethod` interface defined in <>. +An observer method is a non-abstract method of a managed bean class. An observer method may be either static or non-static. There may be arbitrarily many observer methods with the same event parameter type and qualifiers. -A bean (or extension) may declare multiple observer methods. +A bean may declare multiple observer methods. [[observer_method_event_parameter]] @@ -409,8 +406,8 @@ public void afterLogin(@Observes @Admin LoggedInEvent event) { ... } If an observer method is annotated `@Produces` or `@Inject` or has a parameter annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. -Interceptors and decorators may not declare observer methods. -If an interceptor or decorator has a method with a parameter annotated `@Observes` or `@ObservesAsync`, the container automatically detects the problem and treats it as a definition error. +Interceptors may not declare observer methods. +If an interceptor has a method with a parameter annotated `@Observes` or `@ObservesAsync`, the container automatically detects the problem and treats it as a definition error. In addition to the event parameter, observer methods may declare additional parameters, which may declare qualifiers. These additional parameters are injection points. @@ -438,6 +435,7 @@ public interface EventMetadata { * `getQualifiers()` returns the set of qualifiers with which the event was fired. * `getInjectionPoint()` returns the `InjectionPoint` from which this event payload was fired, or `null` if it was fired from `BeanManager.getEvent()`. +// TODO BeanManagerLite * `getType()` returns the type representing runtime class of the event object with type variables resolved. @@ -544,6 +542,7 @@ If the exception is a checked exception, it is wrapped and rethrown as an (unche For a custom implementation of the `ObserverMethod` interface defined in <>, 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]] @@ -551,7 +550,7 @@ For a custom implementation of the `ObserverMethod` interface defined in <>, the following rules apply. + +An observer method is a non-abstract method of a portable extension, as defined in <>. + +A portable extension may declare multiple observer methods. + +[[observes_full]] + +==== Declaring an observer method in {cdi_full} + +In addition to rules defined in <>, 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. diff --git a/spec/src/main/asciidoc/core/implementation.asciidoc b/spec/src/main/asciidoc/core/implementation.asciidoc index eb6245532..8318aa3a1 100644 --- a/spec/src/main/asciidoc/core/implementation.asciidoc +++ b/spec/src/main/asciidoc/core/implementation.asciidoc @@ -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 may provide other kinds of beans by implementing the interface `Bean` defined in <>. +A portable extension, as well as a build compatible extension, may provide other kinds of beans. [[managed_beans]] @@ -32,16 +32,16 @@ If the managed bean class is a generic type, it must have scope `@Dependent`. If A Java class is a managed bean if it meets all of the following conditions: * It is not an inner class. -* It is a non-abstract class, +* It is a non-abstract class. * It does not implement `jakarta.enterprise.inject.spi.Extension`. * It is not annotated `@Vetoed` or in a package annotated `@Vetoed`. * It has an appropriate constructor - either: ** the class has a constructor with no parameters, or ** the class declares a constructor annotated `@Inject`. -In {cdi_full}, a Java class is a managed bean if: +In {cdi_full} environment, a Java class is a managed bean also if: -* It is a non-abstract class, or is annotated `@Decorator`. +* It is an abstract or non-abstract class annotated `@Decorator`. All Java classes that meet these conditions are managed beans and thus no special declaration is required to define a managed bean. @@ -102,28 +102,6 @@ public class MockLoginAction extends LoginAction { ... } The second bean is a "mock object" that overrides the implementation of `LoginAction` when running in an embedded CDI based integration testing environment. -[[specialize_managed_bean]] - -==== Specializing a managed bean - -If a bean class of a managed bean X is annotated `@Specializes`, then the bean class of X must directly extend the bean class of another managed bean Y. -Then X _directly specializes_ Y, as defined in <>. - -If the bean class of X does not directly extend the bean class of another managed bean, the container automatically detects the problem and treats it as a definition error. - -For example, `MockLoginAction` directly specializes `LoginAction`: - -[source, java] ----- -public class LoginAction { ... } ----- - -[source, java] ----- -@Mock @Specializes -public class MockLoginAction extends LoginAction { ... } ----- - [[managed_bean_name]] ==== Default bean name for a managed bean @@ -156,7 +134,7 @@ If a producer method return type contains a wildcard type parameter or is an arr If the producer method return type is a parameterized type with a type variable, it must have scope `@Dependent`. If a producer method with a parameterized return type with a type variable declares any scope other than `@Dependent`, the container automatically detects the problem and treats it as a definition error. -If a producer method return type is a type variable or an array type whose component type is a type variable the container automatically detects the problem and treats it as a definition error. +If a producer method return type is a type variable or an array type whose component type is a type variable, the container automatically detects the problem and treats it as a definition error. The application may call producer methods directly. However, if the application calls a producer method directly, no parameters will be passed to the producer method by the container; the returned object is not bound to any context; and its lifecycle is not managed by the container. @@ -224,37 +202,6 @@ public class OrderFactory { } ---- -[[specialize_producer_method]] - -==== Specializing a producer method - -If a producer method X is annotated `@Specializes`, then it must be non-static and directly override another producer method Y. -Then X _directly specializes_ Y, as defined in <>. - -If the method is static or does not directly override another producer method, the container automatically detects the problem and treats it as a definition error. - -[source, java] ----- -@Mock -public class MockShop extends Shop { - - @Override @Specializes - @Produces - PaymentProcessor getPaymentProcessor() { - return new MockPaymentProcessor(); - } - - @Override @Specializes - @Produces - List getProducts() { - return PRODUCTS; - } - - ... - -} ----- - [[producer_method_name]] ==== Default bean name for a producer method @@ -295,7 +242,7 @@ If a producer field type contains a wildcard type parameter or is an array type If the producer field type is a parameterized type with a type variable, it must have scope `@Dependent`. If a producer field with a parameterized type with a type variable declares any scope other than `@Dependent`, the container automatically detects the problem and treats it as a definition error. -If a producer field type is a type variable or is an array type whose component type is a type variable the container automatically detects the problem and treats it as a definition error. +If a producer field type is a type variable or is an array type whose component type is a type variable, the container automatically detects the problem and treats it as a definition error. The application may access producer fields directly. However, if the application accesses a producer field directly, the returned object is not bound to any context; and its lifecycle is not managed by the container. @@ -376,7 +323,7 @@ A bean may declare multiple disposer methods. ==== Disposed parameter of a disposer method Each disposer method must have exactly one _disposed parameter_, of the same type as the corresponding producer method return type or producer field type. -When searching for disposer methods for a producer method or producer field the container considers the type and qualifiers of the disposed parameter. +When searching for disposer methods for a producer method or producer field, the container considers the type and qualifiers of the disposed parameter. If a producer method or producer field declared by the same bean class is assignable to the disposed parameter, according to the rules of typesafe resolution defined in <>, the container must call this method when destroying any instance returned by that producer method or producer field. A disposer method may resolve to multiple producer methods or producer fields declared by the bean class, in which case the container must call it when destroying any instance returned by any of these producer methods or producer fields. @@ -429,7 +376,7 @@ public class Resources { If a method has more than one parameter annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. -If a disposer method is annotated `@Produces` or `@Inject` has a parameter annotated `@Observes` or has a parameter annotated `@ObservesAsync`, the container automatically detects the problem and treats it as a definition error. +If a disposer method is annotated `@Produces` or `@Inject`, has a parameter annotated `@Observes` or has a parameter annotated `@ObservesAsync`, the container automatically detects the problem and treats it as a definition error. Interceptors may not declare disposer methods. If an interceptor has a method annotated `@Disposes`, the container automatically detects the problem and treats it as a definition error. @@ -719,10 +666,4 @@ A bean type must be proxyable if an injection point resolves to a bean: * that requires a client proxy, or * that has a bound interceptor. -In {cdi_full}, a bean be proxyable if an injection point resolves to a bean: - -* that has an associated decorator. - - Otherwise, the container automatically detects the problem, and treats it as a deployment problem. - diff --git a/spec/src/main/asciidoc/core/inheritance.asciidoc b/spec/src/main/asciidoc/core/inheritance.asciidoc index 4341fc447..367666297 100644 --- a/spec/src/main/asciidoc/core/inheritance.asciidoc +++ b/spec/src/main/asciidoc/core/inheritance.asciidoc @@ -29,6 +29,8 @@ Then the second bean inherits, and may not override, the qualifiers and bean nam The second bean is able to serve the same role in the system as the first. In a particular deployment, only one of the two beans may fulfill that role. +Specialization is only present in {cdi_full} and is specified therein. + [[type_level_inheritance]] === Inheritance of type-level metadata diff --git a/spec/src/main/asciidoc/core/inheritance_full.asciidoc b/spec/src/main/asciidoc/core/inheritance_full.asciidoc index 19d01a084..dec2836a7 100644 --- a/spec/src/main/asciidoc/core/inheritance_full.asciidoc +++ b/spec/src/main/asciidoc/core/inheritance_full.asciidoc @@ -2,6 +2,63 @@ == Inheritance and specialization in {cdi_full} +[[specialize_managed_bean]] + +=== Specializing a managed bean + +In addition to rules defined in <>, the following rules apply. + +If a bean class of a managed bean X is annotated `@Specializes`, then the bean class of X must directly extend the bean class of another managed bean Y. +Then X _directly specializes_ Y, as defined in <>. + +If the bean class of X does not directly extend the bean class of another managed bean, the container automatically detects the problem and treats it as a definition error. + +For example, `MockLoginAction` directly specializes `LoginAction`: + +[source, java] +---- +public class LoginAction { ... } +---- + +[source, java] +---- +@Mock @Specializes +public class MockLoginAction extends LoginAction { ... } +---- + +[[specialize_producer_method]] + +=== Specializing a producer method + +In addition to rules defined in <>, the following rules apply. + +If a producer method X is annotated `@Specializes`, then it must be non-static and directly override another producer method Y. +Then X _directly specializes_ Y, as defined in <>. + +If the method is static or does not directly override another producer method, the container automatically detects the problem and treats it as a definition error. + +[source, java] +---- +@Mock +public class MockShop extends Shop { + + @Override @Specializes + @Produces + PaymentProcessor getPaymentProcessor() { + return new MockPaymentProcessor(); + } + + @Override @Specializes + @Produces + List getProducts() { + return PRODUCTS; + } + + ... + +} +---- + [[specialization]] === Specialization diff --git a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc index 15730ba47..81783a62a 100644 --- a/spec/src/main/asciidoc/core/injectionandresolution.asciidoc +++ b/spec/src/main/asciidoc/core/injectionandresolution.asciidoc @@ -24,14 +24,21 @@ 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_. -In CDI Lite, libraries that are bean archives are always implicit bean archives. +The library may be an explicit bean archive or an implicit bean archive, as defined in <>. +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! 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. +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 application. + [[declaring_selected_alternatives]] ==== Declaring selected alternatives +{cdi_lite} defines one method of selecting alternatives: the `@Priority` annotation allows an alternative to be selected for an entire application. +{cdi_full} defines an additional method of selecting alternatives, which is specified therein. + [[declaring_selected_alternatives_application]] ===== Declaring selected alternatives for an application @@ -42,7 +49,7 @@ An alternative may be given a priority for the application: * by placing the `@Priority` annotation on the bean class that declares the producer method, field or resource. Custom bean implementations which are also alternatives may implement <> in which case they will be enabled for entire application with given priority. - +// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions? [[enablement]] @@ -51,10 +58,8 @@ Custom bean implementations which are also alternatives may implement <>, and either -* it is not an alternative, or it is a selected alternative of at least one bean archive or the application. - +* it is not a producer method or field of a disabled bean, and either +* it is not an alternative, or it is a selected alternative for the application. Otherwise, the bean is said to be disabled. @@ -66,11 +71,11 @@ A bean is _available for injection_ in a certain module if: * the bean is not an interceptor * the bean is enabled, -* the bean is either not an alternative, or the module is a bean archive and the bean is a selected alternative of the bean archive, or the bean is a selected alternative of the application, and +* the bean is either not an alternative, or the module is a bean archive and the bean is a selected alternative for the application, and * the bean class is required to be accessible to classes in the module, according to the class accessibility requirements of the module architecture. - For a custom implementation of the `Bean` interface defined in <>, the container calls `getBeanClass()` to determine the bean class of the bean and `InjectionPoint.getMember()` and then `Member.getDeclaringClass()` to determine the class that declares an injection point. +// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions? [[typesafe_resolution]] @@ -90,7 +95,7 @@ A bean is _assignable_ to a given injection point if: * The bean has a bean type that matches the required type. For this purpose, primitive types are considered to match their corresponding wrapper types in `java.lang` and array types are considered to match only if their element types are identical. -Parameterized and raw types are considered to match if they are identical or if the bean type is _assignable_ to the required type, as defined in <> or <>. +Parameterized and raw types are considered to match if they are identical or if the bean type is _assignable_ to the required type, as defined in <>. * The bean has all the required qualifiers. If no required qualifiers were explicitly specified, the container assumes the required qualifier `@Default`. A bean has a required qualifier if it has a qualifier with (a) the same type and (b) the same annotation member value for each member which is not annotated `@jakarta.enterprise.util.Nonbinding`. @@ -102,6 +107,7 @@ A bean is eligible for injection to a certain injection point if: For a custom implementation of the `Bean` interface defined in <>, the container calls `getTypes()` and `getQualifiers()` to determine the bean types and qualifiers. +// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions? [[unsatisfied_and_ambig_dependencies]] @@ -112,6 +118,7 @@ An _ambiguous dependency_ exists at an injection point when multiple beans are e When an ambiguous dependency exists, the container attempts to resolve the ambiguity. The container eliminates all eligible beans that are not alternatives, except for producer methods and fields of beans that are alternatives. +// TODO maybe mention that the alternatives must be selected, like we do it in <>? If: * there is exactly one bean remaining, the container will select this bean, and the ambiguous dependency is called resolvable. @@ -122,6 +129,7 @@ The container must validate all injection points of all enabled beans, all obser If an unsatisfied or unresolvable ambiguous dependency exists, the container automatically detects the problem and treats it as a deployment problem. For a custom implementation of the `Bean` interface defined in <>, the container calls `getInjectionPoints()` to determine the set of injection points. +// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions? [[legal_injection_point_types]] @@ -162,7 +170,7 @@ Furthermore, `UserDao` is eligible for injection to any injection point of type public class UserDao extends Dao { ... } ---- -A raw bean type is considered assignable to a parameterized required type if the raw types are identical and all type parameters of the required type are either unbounded type variables or java.lang.Object. +A raw bean type is considered assignable to a parameterized required type if the raw types are identical and all type parameters of the required type are either unbounded type variables or `java.lang.Object`. [[primitive_types_and_null_values]] @@ -272,7 +280,7 @@ For a custom implementation of the `Bean` interface defined in <>, the con An _ambiguous name_ exists when a name resolves to multiple beans. When an ambiguous name exists, the container attempts to resolve the ambiguity. -The container eliminates all eligible beans that are not alternatives selected for the bean archive or selected for the application, except for producer methods and fields of beans that are alternatives. +The container eliminates all eligible beans that are not alternatives selected for the application, except for producer methods and fields of beans that are alternatives. If: * there is exactly one bean remaining, the container will select this bean, and the ambiguous dependency is called _resolvable_. @@ -308,6 +316,7 @@ This is only necessary when the circular dependencies are initialized via a mana * Finally, client proxies may be passivated, even when the bean itself may not be. Therefore the container must use a client proxy whenever a bean with normal scope is injected into a bean with a passivating scope, as defined in <>. (On the other hand, beans with scope `@Dependent` must be serialized along with their client.) +// TODO move passivation to Full? Client proxies are never required for a bean whose scope is a pseudo-scope such as `@Dependent`. @@ -461,12 +470,13 @@ If the injection point represents a dynamically obtained instance, the `getBean( If the injection point represents a dynamically obtained instance, the `getType()` and `getQualifiers()` methods should return the required type (as defined by `Instance.select()`), and required qualifiers of the injection point including any additional required qualifiers (as defined by `Instance.select()`). * The `getMember()` method returns the `Field` object in the case of field injection, the `Method` object in the case of method parameter injection, or the `Constructor` object in the case of constructor parameter injection. If the injection point represents a dynamically obtained instance, the `getMember()` method returns the `Field` object representing the field that defines the `Instance` injection point in the case of field injection, the `Method` object representing the method that defines the `Instance` injection point in the case of method parameter injection, or the `Constructor` object representing the constructor that defines the `Instance` injection point in the case of constructor parameter injection. -* The `getAnnotated()` method returns an instance of `jakarta.enterprise.inject.spi.AnnotatedField` or `jakarta.enterprise.inject.spi.AnnotatedParameter`, depending upon whether the injection point is an injected field or a constructor/method parameter. -If the injection point represents a dynamically obtained instance, then the `getAnnotated()` method returns an instance of `jakarta.enterprise.inject.spi.AnnotatedField` or `jakarta.enterprise.inject.spi.AnnotatedParameter` representing the `Instance` injection point, depending upon whether the injection point is an injected field or a constructor/method parameter. -* The `isDelegate()` method always returns `false`. +* The `getAnnotated()` method may, in {cdi_lite} environment, always return `null`. +Behavior of this method in {cdi_full} is specified therein. +* The `isDelegate()` method may, in {cdi_lite} environment, always return `false`. +Behavior of this method in {cdi_full} is specified therein. * The `isTransient()` method returns `true` if the injection point is a transient field, and `false` otherwise. If the injection point represents a dynamically obtained instance then the `isTransient()` method returns `true` if the `Instance` injection point is a transient field, and `false` otherwise. If this injection point is declared as transient, after bean's passivation, the value will not be restored. Instance<> injection point is the preferred approach. - +// TODO move passivation to Full? Occasionally, a bean with scope `@Dependent` needs to access metadata relating to the object into which it is injected. For example, the following producer method creates injectable `Logger` s. @@ -481,6 +491,7 @@ The log category of a `Logger` depends upon the class of the object into which i The container must provide a bean with scope `@Dependent`, bean type `InjectionPoint` and qualifier `@Default`, allowing dependent objects, as defined in <>, to obtain information about the injection point to which they belong. The built-in implementation must be a passivation capable dependency, as defined in <>. +// TODO move passivation to Full? If a bean that declares any scope other than `@Dependent` has an injection point of type `InjectionPoint` and qualifier `@Default`, the container automatically detects the problem and treats it as a definition error. @@ -690,6 +701,7 @@ The container must provide a built-in bean that: * has an implementation provided automatically by the container. The built-in implementation must be a passivation capable dependency, as defined in <>. +// TODO move passivation to Full? [[annotationliteral_typeliteral]] @@ -732,6 +744,7 @@ The following built-in annotations define a `Literal` static nested class to sup * `jakarta.enterprise.inject.Any` * `jakarta.enterprise.inject.Default` * `jakarta.enterprise.inject.Specializes` +// TODO move to Full? * `jakarta.enterprise.inject.Vetoed` * `jakarta.enterprise.util.Nonbinding` * `jakarta.enterprise.context.Initialized` @@ -741,6 +754,7 @@ The following built-in annotations define a `Literal` static nested class to sup * `jakarta.enterprise.context.ApplicationScoped` * `jakarta.enterprise.context.Dependent` * `jakarta.enterprise.context.ConversationScoped` +// TODO move to Full? * `jakarta.enterprise.inject.Alternative` * `jakarta.enterprise.inject.Typed` diff --git a/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc index 0ba09a576..7569b123d 100644 --- a/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc +++ b/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc @@ -7,15 +7,15 @@ === Modularity in {cdi_full} -In module architecture, a library may be an explicit bean archive or an implicit bean archive, as defined in <>. +In addition to rules defined in <>, the following rules apply. -Additionally, 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. +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]] ==== Declaring selected alternatives in {cdi_full} -{cdi_full} provides an additional way to declare alternatives to the one defined in <>: +{cdi_full} provides an additional way to select alternatives to the one defined in <>: [[declaring_selected_alternatives_bean_archive]] @@ -43,7 +43,7 @@ An alternative is selected for the bean archive if either: ---- -For each child `` element the container verifies that either: +For each child `` element, the container verifies that either: * a class with the specified name exists and is annotated with `@Alternative` or an <>, or * a class with the specified name exists and declares a field or method annotated with `@Produces` and, at the same time, annotated with `@Alternative` or an <>, or @@ -57,6 +57,24 @@ If there is no annotation with the specified name, or the annotation is not an ` If the same type is listed twice under the `` element, the container automatically detects the problem and treats it as a deployment problem. For a custom implementation of the `Bean` interface defined in <>, the container calls `isAlternative()` to determine whether the bean is an alternative, and `getBeanClass()` and `getStereotypes()` to determine whether an alternative is selected in a certain bean archive. +// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions? + +[[enablement_full]] + +==== Enabled and disabled beans in {cdi_full} + +The rules defined in <> are overridden as follows. + +A bean is said to be _enabled_ if: + +* it is deployed in a bean archive, and +* it is not a producer method or field of a disabled bean, and +* it is not specialized by any other enabled bean, as defined in <>, and either +* it is not an alternative, or it is a selected alternative of at least one bean archive or the application. + + +Otherwise, the bean is said to be disabled. + [[inconsistent_specialization]] @@ -70,39 +88,60 @@ The container automatically detects inconsistent specialization and treats it as ==== Inter-module injection in {cdi_full} -In addition to rules defined in <>, when running in {cdi_full}, the following apply: +In addition to rules defined in <>, the following rules apply. A bean is also _available for injection_ in a certain module if: -* the bean is not a decorator +* the bean is not a decorator, +* the bean is either not an alternative, or the module is a bean archive and the bean is a selected alternative of the bean archive. + +// TODO here, maybe we shouldn't do "in addition to", but "is overridden" and spell out the full rules again [[typesafe_resolution_full]] === Typesafe resolution in {cdi_full} +[[performing_typesafe_resolution_full]] + +==== Performing typesafe resolution in {cdi_full} + +In addition to rules defined in <>, the following rules apply. + +* Parameterized and raw types are considered to match if they are identical or if the bean type is _assignable_ to the required type, as defined in <> or <>. + [[unsatisfied_and_ambig_dependencies_full]] ==== Unsatisfied and ambiguous dependencies in {cdi_full} -In addition to rules defined in <>, when running in {cdi_full}, the following apply: +In addition to rules defined in <>, the following rules apply. An unsatisfied or ambiguous dependency cannot exist for a decorator delegate injection point, defined in <>. - [[assignable_parameters_full]] ==== Assignability of raw and parameterized types in {cdi_full} -In addition to rules defined in <>, when running in {cdi_full}, the following apply: +In addition to rules defined in <>, the following rules apply. A special set of rules, defined in <>, apply if and only if the injection point is a decorator delegate injection point. [[injection_point_full]] +[[ambig_names_full]] + +==== Ambiguous names in {cdi_full} + +In addition to rules defined in <>, the following rules apply. + +When an ambiguous name exists, the container attempts to resolve the ambiguity. +The container eliminates all eligible beans that are not alternatives selected for the bean archive or selected for the application, except for producer methods and fields of beans that are alternatives. + ==== Injection point metadata in {cdi_full} -When running in {cdi_full}, the behaviour of `InjectionPoint` metadata is overrided as follow: +The behavior of `InjectionPoint` metadata is overridden as follows: +* The `getAnnotated()` method returns an instance of `jakarta.enterprise.inject.spi.AnnotatedField` or `jakarta.enterprise.inject.spi.AnnotatedParameter`, depending upon whether the injection point is an injected field or a constructor/method parameter. +If the injection point represents a dynamically obtained instance, then the `getAnnotated()` method returns an instance of `jakarta.enterprise.inject.spi.AnnotatedField` or `jakarta.enterprise.inject.spi.AnnotatedParameter` representing the `Instance` injection point, depending upon whether the injection point is an injected field or a constructor/method parameter. * The `isDelegate()` method returns `true` if the injection point is a decorator delegate injection point, and `false` otherwise. If the injection point represents a dynamically obtained instance then `isDelegate()` returns false. @@ -110,9 +149,9 @@ If the injection point represents a dynamically obtained instance then `isDelega ==== Bean metadata in {cdi_full} -In addition to rules defined in <>, when running in {cdi_full}, the following apply: +In addition to rules defined in <>, the following rules apply. -The interfaces `Decorator` also provide metadata about a bean. +The interfaces `Decorator` also provides metadata about a bean. The container must provide beans allowing a bean instance to obtain a `Decorator` instance containing its metadata: @@ -122,10 +161,8 @@ Additionally, the container must provide beans allowing decorators to obtain inf * a bean with scope `@Dependent`, qualifier `@Decorated` and type `Bean` which can be injected into any decorator instance. - These beans are passivation capable dependencies, as defined in <>. - If a `Decorator` instance is injected into a bean instance other than a decorator instance, the container automatically detects the problem and treats it as a definition error. If a `Bean` instance with qualifier `@Decorated` is injected into a bean instance other than a decorator instance, the container automatically detects the problem and treats it as a definition error. @@ -135,4 +172,4 @@ If: * the injection point is a field, an initializer method parameter or a bean constructor, with qualifier `@Default`, then the type parameter of the injected `Decorator` must be the same as the type declaring the injection point, or * the injection point is a field, an initializer method parameter or a bean constructor of a decorator, with qualifier `@Decorated`, then the type parameter of the injected `Bean` must be the same as the delegate type. -Otherwise, the container automatically detects the problem and treats it as a definition error. \ No newline at end of file +Otherwise, the container automatically detects the problem and treats it as a definition error. diff --git a/spec/src/main/asciidoc/core/interceptors.asciidoc b/spec/src/main/asciidoc/core/interceptors.asciidoc index e127cf86d..8a800949c 100644 --- a/spec/src/main/asciidoc/core/interceptors.asciidoc +++ b/spec/src/main/asciidoc/core/interceptors.asciidoc @@ -4,16 +4,17 @@ Managed beans support interception. _Interceptors_ are used to separate cross-cutting concerns from business logic. -The Java Interceptors specification defines the basic programming model and semantics, and how to associate interceptors with target classes. +The Jakarta Interceptors specification defines the basic programming model and semantics, and how to associate interceptors with target classes. This specification defines various extensions to the Java Interceptors specification, including non-binding annotation values in interceptor resolution. -In CDI Lite environment, the only portable way to bind an interceptor to a bean is via interceptor bindings. `@Interceptors` annotation is not supported. +{cdi_lite} implementations are not required to support associating interceptors with classes and methods using the `@jakarta.interceptor.Interceptors` annotation. +They are required to support interceptor binding annotations. [[interceptor_bindings]] === Interceptor binding types -This specification extends the Java Interceptors specification and allows interceptor bindings to be applied to CDI stereotypes. +This specification extends the Jakarta Interceptors specification and allows interceptor bindings to be applied to CDI stereotypes. [[stereotype_interceptor_bindings]] @@ -40,7 +41,7 @@ If a stereotype declares interceptor bindings, it must be defined as `@Target(TY === Declaring the interceptor bindings of an interceptor -This specification extends the Java Interceptors specification and defines how the container must behave if a definition error is encountered. +This specification extends the Jakarta Interceptors specification and defines how the container must behave if a definition error is encountered. If an interceptor declares any scope other than `@Dependent`, the container automatically detects the problem and treats it as a definition error. @@ -48,12 +49,14 @@ If an interceptor declares any scope other than `@Dependent`, the container auto === Binding an interceptor to a bean -This specification extends the Java Interceptors specification and defines: +This specification extends the Jakarta Interceptors specification and defines: * additional restrictions about the type of bean to which an interceptor can be bound, and * how the container must behave if a definition error is encountered, and * how interceptors are bound using stereotypes. +Interceptor bindings may be used to associate interceptors with any managed bean. + The set of interceptor bindings for a method declared at class level includes those declared on stereotypes. An interceptor binding declared on a bean class replaces an interceptor binding of the same type declared by a stereotype that is applied to the bean class. @@ -65,7 +68,7 @@ If a managed bean has a class-level or method-level interceptor binding, the man === Interceptor resolution -This specification extends the Java Interceptors specification and defines: +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. @@ -73,7 +76,7 @@ This specification extends the Java Interceptors specification and defines: 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 <>, 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 <> 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? diff --git a/spec/src/main/asciidoc/core/interceptors_full.asciidoc b/spec/src/main/asciidoc/core/interceptors_full.asciidoc index 85bd5a3de..4472aedb2 100644 --- a/spec/src/main/asciidoc/core/interceptors_full.asciidoc +++ b/spec/src/main/asciidoc/core/interceptors_full.asciidoc @@ -1,14 +1,16 @@ [[interceptors_full]] -== Interceptors in CDI Full +== Interceptor bindings in {cdi_full} -In CDI Full environment, interceptors are supported to the extent defined in Java Interceptors specification. That includes, for instance, `@Interceptors` annotation. +This specification defines various extensions to the Jakarta Interceptors specification, including how to override the interceptor order defined by the `@Priority` annotation. -There is also few more features available in CDI Full environment including the ability to override interceptor order defined by `@Priority` annotation. +{cdi_full} implementations are required to support the entire Jakarta Interceptors specification, including associating interceptors with classes and methods using the `@jakarta.interceptor.Interceptors` annotation. [[binding_interceptor_to_bean_full]] -=== Binding an interceptor to a bean in CDI Full +=== Binding an interceptor to a bean in {cdi_full} + +In addition to rules defined in <>, the following rules apply. Interceptor bindings may be used to associate interceptors with any managed bean that is not a decorator. @@ -16,9 +18,9 @@ It is possible to apply interceptors programmatically to the return value of a p [[enabled_interceptors_full]] -=== Interceptor enablement and ordering in CDI Full +=== Interceptor enablement and ordering in {cdi_full} -This specification extends the Java Interceptors specification and defines: +This specification extends the Jakarta Interceptors specification and defines: * support for enabling interceptors only for a bean archive, as defined by Contexts and Dependency Injection 1.0, and * the ability to override the interceptor order using the portable extension SPI, defined in <>. @@ -49,4 +51,4 @@ 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 <>. -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. \ No newline at end of file +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. diff --git a/spec/src/main/asciidoc/core/lifecycle.asciidoc b/spec/src/main/asciidoc/core/lifecycle.asciidoc index ea77897fd..21631623a 100644 --- a/spec/src/main/asciidoc/core/lifecycle.asciidoc +++ b/spec/src/main/asciidoc/core/lifecycle.asciidoc @@ -77,7 +77,7 @@ public class PaymentStrategyProducer implements Serializable { } ---- -In this case, any object returned by the producer method will not have any dependencies injected by the container, receives no lifecycle callbacks or event notifications and does not have interceptors or decorators. +In this case, any object returned by the producer method will not have any dependencies injected by the container, receives no lifecycle callbacks or event notifications and does not have interceptors or, in {cdi_full}, decorators. [[biz_method]] @@ -87,7 +87,9 @@ When the application invokes: * a method of a bean via a contextual reference to the bean, as defined in <>, * a method of a bean via a non-contextual reference to the bean, if the instance was created by the container (e.g. using `InjectionTarget.produce()` or `UnmanagedInstance.produce()`), or +// TODO mentions Full-only concepts * a method of a bean via a non-contextual reference to the bean, if the instance was enhanced with the `InterceptionFactory` interface as defined in <>, +// TODO mentions Full-only concepts the invocation is treated as a _business method invocation_. @@ -95,11 +97,14 @@ When the container invokes a method of a bean, the invocation may or may not be * Invocations of initializer methods by the container are not business method invocations. * Invocations of producer, disposer and observer methods by the container are business method invocations and are intercepted by method interceptors and decorators. +// TODO mentions decorators * Invocation of lifecycle callbacks by the container are not business method invocations, but are intercepted by interceptors for lifecycle callbacks. * Invocations of interceptors and decorator methods during method or lifecycle callback interception are not business method invocations, and therefore no recursive interception occurs. -* Invocations of methods declared by java.lang.Object are not business method invocations. +// TODO mentions decorators +* Invocations of methods declared by `java.lang.Object` are not business method invocations. A method invocation passes through method interceptors and decorators if, and only if, it is a business method invocation. +// TODO mentions decorators Otherwise, the invocation is treated as a normal Java method call and is not intercepted by the container. diff --git a/spec/src/main/asciidoc/core/packagingdeployment_lite.asciidoc b/spec/src/main/asciidoc/core/packagingdeployment_lite.asciidoc index ad8dbd394..82ebb3a1e 100644 --- a/spec/src/main/asciidoc/core/packagingdeployment_lite.asciidoc +++ b/spec/src/main/asciidoc/core/packagingdeployment_lite.asciidoc @@ -2,6 +2,7 @@ == Packaging and deployment +// TODO [NOTE] ==== TBD based on what approach we choose diff --git a/spec/src/main/asciidoc/core/scopescontexts.asciidoc b/spec/src/main/asciidoc/core/scopescontexts.asciidoc index f1ee16332..a9dc2457a 100644 --- a/spec/src/main/asciidoc/core/scopescontexts.asciidoc +++ b/spec/src/main/asciidoc/core/scopescontexts.asciidoc @@ -39,6 +39,7 @@ If an exception occurs while destroying an instance, the exception must be caugh If the application invokes a contextual instance after it has been destroyed, the behavior is undefined. The container and portable extensions may define implementations of the `Contextual` interface that do not extend `Bean`, but it is not recommended that applications directly implement `Contextual`. +// TODO move the mention of Portable Extensions to full? mention Build Compatible Extensions? [[creational_context]] @@ -76,6 +77,7 @@ The `jakarta.enterprise.context.spi.Context` interface provides an operation for The context object is responsible for creating and destroying contextual instances by calling operations of the `Contextual` interface. The `Context` interface is called by the container and may be called by portable extensions. +// TODO move the mention of Portable Extensions to full? mention Build Compatible Extensions? It should not be called directly by the application. [source, java] @@ -98,6 +100,7 @@ public interface AlterableContext extends Context { The method `getScope()` returns the scope type of the context object. A context object may be defined for any of the built-in scopes and registered with the container using the `AfterBeanDiscovery` event as described in <>. +// TODO move the mention of Portable Extensions to full? mention Build Compatible Extensions? At a particular point in the execution of the program a context object may be _active_ with respect to the current thread. When a context object is active the `isActive()` method returns `true`. Otherwise, we say that the context object is _inactive_ and the `isActive()` method returns `false`. @@ -121,6 +124,7 @@ Extensions providing context implementations for normal scopes should implement If the context object is inactive, the `get()` and `destroy()` methods must throw a `ContextNotActiveException`. When the container calls `get()` or `destroy()` for a context that is associated with a passivating scope it must ensure that the given instance of `Contextual` and the instance of `CreationalContext`, if given, are serializable. +// TODO move passivation to Full? The context object is responsible for destroying any contextual instance it creates by passing the instance to the `destroy()` method of the `Contextual` object representing the contextual type. A destroyed instance must not subsequently be returned by the `get()` method. @@ -187,7 +191,7 @@ The `@Dependent` scope is always active. Many instances of beans with scope `@Dependent` belong to some other bean and are called _dependent objects_. -* Instances of interceptors are dependent objects of the bean instance they decorate. +* Instances of interceptors are dependent objects of the bean instance they intercept. * An instance of a bean with scope `@Dependent` injected into a field, bean constructor or initializer method is a dependent object of the bean into which it was injected. * An instance of a bean with scope `@Dependent` injected into a producer method is a dependent object of the producer method bean instance that is being produced. * An instance of a bean with scope `@Dependent` obtained by direct invocation of an `Instance` is a dependent object of the instance of `Instance`. @@ -244,12 +248,13 @@ Request contexts can be managed either programmatically or via interceptor. To programmatically manage request contexts, the container provides a built in bean that is `@Dependent` scoped and of type `RequestContextController` that allows you to activate and deactivate a request context on the current thread. The object should be considered stateful, invoking the same instance on different threads may not work properly, non-portable behavior may occur. -``` +[source, java] +---- public interface RequestContextController { boolean activate(); void deactivate() throws ContextNotActiveException; } -``` +---- When the `activate()` method is called, if the request context is not already active on the current thread then it will be activated and the method returns `true`. Otherwise, the method returns `false`. @@ -283,6 +288,7 @@ A contextual instance of any of the built-in kinds of bean defined in <>, the container calls `getScope()` to determine the bean scope. +// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions? [[contextual_reference]] @@ -352,112 +358,6 @@ Injectable references to a bean must respect the rules of contextual reference v The application should not invoke a method of an invalid injected reference. If the application invokes a method of an invalid injected reference, the behavior is undefined. -[[passivating_scope]] - -=== Passivation and passivating scopes - -The temporary transfer of the state of an idle object held in memory to some form of secondary storage is called _passivation_. -The transfer of the passivated state back into memory is called _activation_. - -[[passivation_capable]] - -==== Passivation capable beans - -A bean is called _passivation capable_ if the container is able to temporarily transfer the state of any idle instance to secondary storage. - -* A managed bean is passivation capable if and only if the bean class is serializable and all interceptors of the bean are passivation capable. -* A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime. -* A producer field is passivation capable if and only if it never refers to a value which is not passivation capable at runtime. - - -A custom implementation of `Bean` is passivation capable if it implements the interface `PassivationCapable`. An implementation of `Contextual` that is not a bean is passivation capable if it implements both `PassivationCapable` and `Serializable`. - -[source, java] ----- -public interface PassivationCapable { - public String getId(); -} ----- - -The `getId()` method must return a value that uniquely identifies the instance of `Bean` or `Contextual`. It is recommended that the string contain the package name of the class that implements `Bean` or `Contextual`. - -[[passivation_capable_injection_points]] - -==== Passivation capable injection points - -We call an injection point of a bean _passivation capable_ if the injection point is: - -* a transient field, or -* a non-transient field which resolves to a bean that is a passivation capable dependency, or -* a bean constructor parameter which is annotated with `@TransientReference`, or -* a bean constructor parameter which resolves to a bean that is a passivation capable dependency, or -* a method parameter which is annotated with `@TransientReference`, or -* a method parameter which resolves to a bean that is a passivation capable dependency. - -[[passivation_capable_dependency]] - -==== Passivation capable dependencies - -A bean is called a _passivation capable dependency_ if any contextual reference for that bean is preserved when the object holding the reference is passivated and then activated. - -The container must guarantee that: - -* all beans with normal scope are passivation capable dependencies, -* all passivation capable beans with scope `@Dependent` are passivation capable dependencies, -* the built-in beans of type `Instance`, `Event`, `InjectionPoint` and `BeanManager` are passivation capable dependencies. - - -A custom implementation of `Bean` is a passivation capable dependency if it implements `PassivationCapable`. - -[[passivating_scopes]] - -==== Passivating scopes - -A _passivating scope_ requires that: - -* beans with the scope are passivation capable, and -* implementations of `Contextual` passed to any context object for the scope are passivation capable. - - -Passivating scopes must be explicitly declared `@NormalScope(passivating=true)`. - -For example, the built-in session and conversation scopes defined in <> are passivating scopes. -No other built-in scopes are passivating scopes. - -[[passivation_validation]] - -==== Validation of passivation capable beans and dependencies - -For every bean which declares a passivating scope, the container must validate that the bean truly is passivation capable and that, in addition, its dependencies are passivation capable. - -If a managed bean which declares a passivating scope, or a built-in bean: - -* is not passivation capable, -* has an injection point that is not passivation capable, -* has an interceptor that is not passivation capable -* has an interceptor with an injection point that is not passivation capable - -then the container automatically detects the problem and treats it as a deployment problem. - -If a producer method declares a passivating scope and: - -* has a return type that is declared final and does not implement or extend `Serializable`, or, -* has an injection point that is not passivation capable - -then the container automatically detects the problem and treats it as a deployment problem. - -If a producer method declares a passivating scope and doesn't only return `Serializable` types at runtime, then the container must throw an `IllegalProductException`. - -If a producer field declares a passivating scope and has a type that is declared final and does not implement or extend `Serializable` then the container automatically detects the problem and treats it as a deployment problem. - -If a producer field declares a passivating scope and doesn't only contain `Serializable` values at runtime then the container must throw an `IllegalProductException`. - -If a producer method or field of scope `@Dependent` returns an unserializable object for injection into an injection point that requires a passivation capable dependency, the container must throw an `IllegalProductException` - -For a custom implementation of `Bean`, the container calls `getInjectionPoints()` to determine the injection points, and `InjectionPoint.isTransient()` to determine whether the injection point is a transient field. - -If a managed bean which declares a passivating scope type, has an interceptor which is not a passivation capable dependency, the container automatically detects the problem and treats it as a deployment problem. - [[builtin_contexts]] === Context management for built-in scopes @@ -467,11 +367,13 @@ These implementations depend on the platform the container is running. A portable extension may define a custom context object for any or all of the built-in scopes. For example, a remoting framework might provide a request context object for the built-in request scope. +// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions? The context associated with a built-in normal scope propagates across local, synchronous Java method calls. The context does not propagate across remote method invocations or to asynchronous processes. Portable extensions are encouraged to synchronously fire: +// TODO this refers to Portable Extensions, maybe move to Full? maybe mention Build Compatible Extensions? * an event with qualifier `@Initialized(X.class)` when a custom context is initialized, i.e. ready for use, * an event with qualifier `@BeforeDestroyed(X.class)` when a custom context is about to be destroyed, i.e. before the actual destruction, @@ -505,7 +407,7 @@ The request context is destroyed: ==== Session context lifecycle -The _session context_ is provided by a built-in context object for the built-in passivating scope type `@SessionScoped`. +The _session context_ is provided by a built-in context object for the built-in scope type `@SessionScoped`. [[application_context]] @@ -516,45 +418,3 @@ The _application context_ is provided by a built-in context object for the built An event with qualifier `@Initialized(ApplicationScoped.class)` is synchronously fired when the application context is initialized. An event with qualifier `@BeforeDestroyed(ApplicationScoped.class)` is synchronously fired when the application context is about to be destroyed, i.e. before the actual destruction. An event with qualifier `@Destroyed(ApplicationScoped.class)` is synchronously fired when the application context is destroyed, i.e. after the actual destruction. - -[[conversation_context]] - -==== Conversation context lifecycle - -The _conversation context_ is provided by a built-in context object for the built-in passivating scope type `@ConversationScoped`. - -[[conversation]] - -==== The `Conversation` interface - -The container provides a built-in bean with bean type `Conversation`, scope `@RequestScoped`, and qualifier `@Default`, named `jakarta.enterprise.context.conversation`. - -[source, java] ----- -public interface Conversation { - public void begin(); - public void begin(String id); - public void end(); - public String getId(); - public long getTimeout(); - public void setTimeout(long milliseconds); - public boolean isTransient(); -} ----- - -* `begin()` marks the current transient conversation long-running. A conversation identifier may, optionally, be specified. -If no conversation identifier is specified, an identifier is generated by the container. -* `end()` marks the current long-running conversation transient. -* `getId()` returns the identifier of the current long-running conversation, or a null value if the current conversation is transient. -* `getTimeout()` returns the timeout, in milliseconds, of the current conversation. -* `setTimeout()` sets the timeout of the current conversation. -* `isTransient()` returns `true` if the conversation is marked transient, or `false` if it is marked long-running. - - -If any method of `Conversation` is called when the conversation scope is not active, a `ContextNotActiveException` is thrown. - -If `end()` is called, and the current conversation is marked transient, an `IllegalStateException` is thrown. - -If `begin()` is called, and the current conversation is already marked long-running, an `IllegalStateException` is thrown. - -If `begin()` is called with an explicit conversation identifier, and a long-running conversation with that identifier already exists, an `IllegalArgumentException` is thrown. diff --git a/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc b/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc index a80fddec7..45c630bf3 100644 --- a/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc +++ b/spec/src/main/asciidoc/core/scopescontexts_full.asciidoc @@ -2,53 +2,136 @@ == Scopes and contexts in {cdi_full} - [[dependent_context_full]] === Dependent pseudo-scope in {cdi_full} - [[dependent_objects_full]] ==== Dependent objects in {cdi_full} -In addition to rules defined in <>, when running in {cdi_full}, the following apply: +In addition to rules defined in <>, the following rules apply. * Instances of decorators are dependent objects of the bean instance they decorate. +[[passivating_scope]] -[[passivating_scope_full]] - -=== Passivation and passivating scopes in {cdi_full} +=== Passivation and passivating scopes +The temporary transfer of the state of an idle object held in memory to some form of secondary storage is called _passivation_. +The transfer of the passivated state back into memory is called _activation_. -[[passivation_capable_full]] +[[passivation_capable]] ==== Passivation capable beans -In addition to rules defined in <>, when running in {cdi_full}, the following apply: - +A bean is called _passivation capable_ if the container is able to temporarily transfer the state of any idle instance to secondary storage. * A managed bean is passivation capable if and only if the bean class is serializable and all interceptors and decorators of the bean are passivation capable. +* A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime. +* A producer field is passivation capable if and only if it never refers to a value which is not passivation capable at runtime. + + +A custom implementation of `Bean` is passivation capable if it implements the interface `PassivationCapable`. An implementation of `Contextual` that is not a bean is passivation capable if it implements both `PassivationCapable` and `Serializable`. + +[source, java] +---- +public interface PassivationCapable { + public String getId(); +} +---- + +The `getId()` method must return a value that uniquely identifies the instance of `Bean` or `Contextual`. It is recommended that the string contain the package name of the class that implements `Bean` or `Contextual`. + +[[passivation_capable_injection_points]] + +==== Passivation capable injection points + +We call an injection point of a bean _passivation capable_ if the injection point is: + +* a transient field, or +* a non-transient field which resolves to a bean that is a passivation capable dependency, or +* a bean constructor parameter which is annotated with `@TransientReference`, or +* a bean constructor parameter which resolves to a bean that is a passivation capable dependency, or +* a method parameter which is annotated with `@TransientReference`, or +* a method parameter which resolves to a bean that is a passivation capable dependency. + +[[passivation_capable_dependency]] + +==== Passivation capable dependencies + +A bean is called a _passivation capable dependency_ if any contextual reference for that bean is preserved when the object holding the reference is passivated and then activated. + +The container must guarantee that: + +* all beans with normal scope are passivation capable dependencies, +* all passivation capable beans with scope `@Dependent` are passivation capable dependencies, +* the built-in beans of type `Instance`, `Event`, `InjectionPoint` and `BeanManager` are passivation capable dependencies. + +A custom implementation of `Bean` is a passivation capable dependency if it implements `PassivationCapable`. -[[passivation_validation_full]] +[[passivating_scopes]] -==== Validation of passivation capable beans and dependencies in {cdi_full} +==== Passivating scopes + +A _passivating scope_ requires that: + +* beans with the scope are passivation capable, and +* implementations of `Contextual` passed to any context object for the scope are passivation capable. + + +Passivating scopes must be explicitly declared `@NormalScope(passivating=true)`. + +For example, the built-in session and conversation scopes defined in <> are passivating scopes. +No other built-in scopes are passivating scopes. + +[[passivation_validation]] + +==== Validation of passivation capable beans and dependencies + +For every bean which declares a passivating scope, the container must validate that the bean truly is passivation capable and that, in addition, its dependencies are passivation capable. -In addition to rules defined in <>, when running in {cdi_full}, the following apply: If a managed bean which declares a passivating scope, or a built-in bean: -* has a decorator that is not passivation capable -* has a decorator with an injection point that is not passivation capable +* is not passivation capable, +* has an injection point that is not passivation capable, +* has an interceptor or decorator that is not passivation capable, +* has an interceptor or decorator with an injection point that is not passivation capable, + +then the container automatically detects the problem and treats it as a deployment problem. + +If a producer method declares a passivating scope and: + +* has a return type that is declared final and does not implement or extend `Serializable`, or, +* has an injection point that is not passivation capable +then the container automatically detects the problem and treats it as a deployment problem. -If a managed bean which declares a passivating scope type, has a decorator which is not a passivation capable dependency, the container automatically detects the problem and treats it as a deployment problem. +If a producer method declares a passivating scope and doesn't only return `Serializable` types at runtime, then the container must throw an `IllegalProductException`. + +If a producer field declares a passivating scope and has a type that is declared final and does not implement or extend `Serializable` then the container automatically detects the problem and treats it as a deployment problem. + +If a producer field declares a passivating scope and doesn't only contain `Serializable` values at runtime then the container must throw an `IllegalProductException`. + +If a producer method or field of scope `@Dependent` returns an unserializable object for injection into an injection point that requires a passivation capable dependency, the container must throw an `IllegalProductException` + +For a custom implementation of `Bean`, the container calls `getInjectionPoints()` to determine the injection points, and `InjectionPoint.isTransient()` to determine whether the injection point is a transient field. + +If a managed bean which declares a passivating scope type, has a decorator or interceptor which is not a passivation capable dependency, the container automatically detects the problem and treats it as a deployment problem. [[builtin_contexts_full]] === Context management for built-in scopes in {cdi_full} +[[session_context_full]] + +==== Session context lifecycle in {cdi_full} + +The rules defined in <> are overridden as follows. + +The _session context_ is provided by a built-in context object for the built-in passivating scope type `@SessionScoped`. + [[conversation_context_full]] ==== Conversation context lifecycle @@ -82,7 +165,6 @@ If no conversation identifier is specified, an identifier is generated by the co * `setTimeout()` sets the timeout of the current conversation. * `isTransient()` returns `true` if the conversation is marked transient, or `false` if it is marked long-running. - If any method of `Conversation` is called when the conversation scope is not active, a `ContextNotActiveException` is thrown. If `end()` is called, and the current conversation is marked transient, an `IllegalStateException` is thrown. diff --git a/spec/src/main/asciidoc/core/spi.asciidoc b/spec/src/main/asciidoc/core/spi.asciidoc index d5b6b40ff..7c3e8117c 100644 --- a/spec/src/main/asciidoc/core/spi.asciidoc +++ b/spec/src/main/asciidoc/core/spi.asciidoc @@ -202,11 +202,16 @@ The container sets the value of all injected fields, and calls all initializer m Implementations of `Producer` and `InjectionTarget` must ensure that the set of injection points returned by `getInjectionPoints()` are injected by `produce()` or `inject()`. -[[beanmanager]] +[[beanmanager_full]] === The `BeanManager` object -The interface `jakarta.enterprise.inject.spi.BeanManager` provides operations for obtaining contextual references for beans, along with many other operations of use to portable extensions. +In addition to rules defined in <>, the following rules apply. + +The interface `jakarta.enterprise.inject.spi.BeanManager` provides operations for obtaining contextual references for beans, along with many other operations of use to applications and portable extensions. + +The interface `jakarta.enterprise.inject.spi.BeanManager` extends `jakarta.enterprise.inject.spi.BeanManagerLite`. +In {cdi_full} environment, `BeanManagerLite` is subject to the same rules as `BeanManager`. The container provides a built-in bean with bean type `BeanManager`, scope `@Dependent` and qualifier `@Default`. The built-in implementation must be a passivation capable dependency, as defined in <>. Thus, any bean may obtain an instance of `BeanManager` by injecting it: @@ -234,88 +239,29 @@ and if the following operations are called before the `AfterDeploymentValidation * `getReference(Bean, Type, CreationalContext)`, * `getInjectableReference(InjectionPoint, CreationalContext)`. -All other operations of BeanManager may be called at any time during the execution of the application. +All other operations of `BeanManager` may be called at any time during the execution of the application. -[[provider]] +[[provider_full]] -==== Obtaining a reference to the CDI container +==== Obtaining a reference to the CDI container in {cdi_full} + +In addition to rules defined in <>, the following rules apply. Portable extensions and other objects sometimes interact directly with the container via programmatic API call. The abstract `jakarta.enterprise.inject.spi.CDI` provides access to the `BeanManager` as well providing lookup of bean instances. -[source, java] ----- -public abstract class CDI implements Instance { - public static CDI current() { ... } - public static void setCDIProvider(CDIProvider provider); - public abstract BeanManager getBeanManager(); -} ----- - A portable extension or other object may obtain a reference to the current container by calling `CDI.current()`. -`CDI.getBeanManager()` may be called at any time after the container fires the `BeforeBeanDiscovery` container lifecycle event until the container fires the `BeforeShutdown` container lifecycle event. -Other methods on `CDI` may be called after the application initialization is completed until the application shutdown starts. +`CDI.getBeanManager()` and `CDI.getBeanManagerLite()` may be called at any time after the container fires the `BeforeBeanDiscovery` container lifecycle event until the container fires the `BeforeShutdown` container lifecycle event. If methods on `CDI` are called at any other time, non-portable behavior results. -CDI implements `jakarta.enterprise.inject.Instance` and therefore might be used to perform programmatic lookup as defined in <>. -If no qualifier is passed to `CDI.select()` method, the `@Default` qualifier is assumed. - -When `CDI.current()` is called, `getCDI()` method is called on `jakarta.enterprise.inject.spi.CDIProvider`. - -The `CDIProvider` to use may be set by the application or container using the `setCDIProvider()` method. -If the `setCDIProvider()` has not been called, the service provider with highest priority of the service `jakarta.enterprise.inject.spi.CDIProvider` declared in META-INF/services is used. -The order of more than one `CDIProvider` with the same priority is undefined. -If no provider is available an `IllegalStateException` is thrown. - -[source, java] ----- -public interface CDIProvider extends Prioritized { - CDI getCDI(); - default int getPriority(); -} ----- - -* `getPriority()` method is inherited from <> and returns the priority for the `CDIProvider`. -If this method is not implemented the default priority `0` is assumed. - - -[[bm_obtain_contextual_reference]] - -==== Obtaining a contextual reference for a bean - -The method `BeanManager.getReference()` returns a contextual reference for a given bean and bean type, as defined in <>. - -[source, java] ----- -public Object getReference(Bean bean, Type beanType, CreationalContext ctx); ----- - -The first parameter is the `Bean` object representing the bean. -The second parameter represents a bean type that must be implemented by any client proxy that is returned. -The third parameter is an instance of `CreationalContext` that may be used to destroy any object with scope `@Dependent` that is created. - -If the given type is not a bean type of the given bean, an `IllegalArgumentException` is thrown. - -[[bm_obtain_injectable_reference]] +[[bm_obtain_injectable_reference_full]] -==== Obtaining an injectable reference +==== Obtaining an injectable reference in {cdi_full} -The method `BeanManager.getInjectableReference()` returns an injectable reference for a given injection point, as defined in <>. - -[source, java] ----- -public Object getInjectableReference(InjectionPoint ij, CreationalContext ctx); ----- - -The first parameter represents the target injection point. -The second parameter is an instance of `CreationalContext` that may be used to destroy any object with scope `@Dependent` that is created. +In addition to rules defined in <>, the following rules apply. If the `InjectionPoint` represents a decorator delegate injection point, `getInjectableReference()` returns a delegate, as defined in <>. -If typesafe resolution results in an unsatisfied dependency, the container must throw an `UnsatisfiedResolutionException`. If typesafe resolution results in an unresolvable ambiguous dependency, the container must throw an `AmbiguousResolutionException`. - -Implementations of `Bean` usually maintain a reference to an instance of `BeanManager`. When the `Bean` implementation performs dependency injection, it must obtain the contextual instances to inject by calling `BeanManager.getInjectableReference()`, passing an instance of `InjectionPoint` that represents the injection point and the instance of `CreationalContext` that was passed to `Bean.create()`. - [[bm_obtain_unmanaged_instance]] ==== Obtaining non-contextual instance @@ -334,53 +280,22 @@ Foo foo = fooInstance.produce().inject().postConstruct().get(); fooInstance.preDestroy().dispose(); ---- -[[bm_obtain_creationalcontext]] - -==== Obtaining a `CreationalContext` - -An instance of `CreationalContext` for a certain instance of `Contextual` may be obtained by calling `BeanManager.createCreationalContext()`. - -[source, java] ----- -public CreationalContext createCreationalContext(Contextual contextual); ----- - -An instance of `CreationalContext` for a non-contextual object may be obtained by passing a null value to `createCreationalContext()`. +[[bm_obtain_bean_by_type_full]] -[[bm_obtain_bean_by_type]] +==== Obtaining a `Bean` by type in {cdi_full} -==== Obtaining a `Bean` by type +In addition to rules defined in <>, the following rules apply. The method `BeanManager.getBeans()` returns the set of beans which have the given required type and qualifiers and are available for injection in the module or library containing the class into which the `BeanManager` was injected or the class from whose JNDI environment namespace the `BeanManager` was obtained, according to the rules for candidates of typesafe resolution defined in <>. -[source, java] ----- -public Set> getBeans(Type beanType, Annotation... qualifiers); ----- - -The first parameter is a required bean type. The remaining parameters are required qualifiers. +[[bm_obtain_bean_by_name_full]] -If no qualifiers are passed to `getBeans()`, the default qualifier `@Default` is assumed. +==== Obtaining a `Bean` by name in {cdi_full} -If the given type represents a type variable, an `IllegalArgumentException` is thrown. - -If two instances of the same non repeating qualifier type are given, an `IllegalArgumentException` is thrown. - -If an instance of an annotation that is not a qualifier type is given, an `IllegalArgumentException` is thrown. - -[[bm_obtain_bean_by_name]] - -==== Obtaining a `Bean` by name +In addition to rules defined in <>, the following rules apply. The method `BeanManager.getBeans()` which accepts a string returns the set of beans which have the given bean name and are available for injection in the module or library containing the class into which the `BeanManager` was injected or the class from whose JNDI environment namespace the `BeanManager` was obtained, according to the rules of name resolution defined in <>. -[source, java] ----- -public Set> getBeans(String name); ----- - -The parameter is a bean name. - [[bm_obtain_passivation_capable_bean]] ==== Obtaining a passivation capable bean by identifier @@ -392,24 +307,6 @@ The method `BeanManager.getPassivationCapableBean()` returns the `PassivationCap public Bean getPassivationCapableBean(String id); ---- -[[bm_resolve_ambiguous_dep]] - -==== Resolving an ambiguous dependency - -The method `BeanManager.resolve()` applies the ambiguous dependency resolution rules defined in <> to a set of `Bean` s. - -[source, java] ----- -public Bean resolve(Set> beans); ----- - -If the ambiguous dependency resolution rules fail (as defined in <>, the container must throw an `AmbiguousResolutionException`. - -`BeanManager.resolve()` must return null if: - -* null is passed to `resolve()`, or -* no beans are passed to `resolve()`. - [[bm_validate_ip]] ==== Validating an injection point @@ -421,39 +318,6 @@ The `BeanManager.validate()` operation validates an injection point and throws a public void validate(InjectionPoint injectionPoint); ---- -[[bm_fire_event]] - -==== Firing an event - -The method `BeanManager.getEvent()` returns an instance of `Event` with specified type `java.lang.Object` and specified qualifier `@Default`. - -[source, java] ----- -Event getEvent(); ----- - -The returned instance can be used like a standard `Event` as described in <>. - -[[bm_observer_method_resolution]] - -==== Observer method resolution - -The method `BeanManager.resolveObserverMethods()` resolves observer methods for an event according to the rules of observer resolution defined in <>. - -[source, java] ----- -public Set> resolveObserverMethods(T event, Annotation... qualifiers); ----- - -The first parameter of `resolveObserverMethods()` is the event object. -The remaining parameters are event qualifiers. - -If the runtime type of the event object contains a type variable, an `IllegalArgumentException` is thrown. - -If two instances of the same non repeating qualifier type are given, an `IllegalArgumentException` is thrown. - -If an instance of an annotation that is not a qualifier type is given, an `IllegalArgumentException` is thrown. - [[bm_decorator_resolution]] ==== Decorator resolution @@ -474,27 +338,19 @@ If an instance of an annotation that is not a qualifier type is given, an `Illeg If the set of bean types is empty, an `IllegalArgumentException` is thrown. -[[bm_interceptor_resolution]] - -==== Interceptor resolution +[[bm_interceptor_resolution_full]] -The method `BeanManager.resolveInterceptors()` returns the ordered list of interceptors for a set of interceptor bindings and a type of interception and which are enabled in the module or library containing the class into which the `BeanManager` was injected or the class from whose JNDI environment namespace the `BeanManager` was obtained, as defined in <>. +==== Interceptor resolution in {cdi_full} -[source, java] ----- -List> resolveInterceptors(InterceptionType type, - Annotation... interceptorBindings); ----- +In addition to rules defined in <>, the following rules apply. -If two instances of the same non repeating interceptor binding type are given, an `IllegalArgumentException` is thrown. - -If no interceptor binding type instance is given, an `IllegalArgumentException` is thrown. +The method `BeanManager.resolveInterceptors()` returns the ordered list of interceptors for a set of interceptor bindings and a type of interception and which are enabled in the module or library containing the class into which the `BeanManager` was injected or the class from whose JNDI environment namespace the `BeanManager` was obtained, as defined in <>. -If an instance of an annotation that is not an interceptor binding type is given, an `IllegalArgumentException` is thrown. +[[bm_determining_annotation_full]] -[[bm_determining_annotation]] +==== Determining if an annotation is a qualifier type, scope type, stereotype or interceptor binding type in {cdi_full} -==== Determining if an annotation is a qualifier type, scope type, stereotype or interceptor binding type +In addition to rules defined in <>, the following rules apply. A portable extension may test an annotation to determine if it is a qualifier type, scope type, stereotype or interceptor binding type, obtain the set of meta-annotations declared by a stereotype or interceptor binding type, or determine if a scope type is a normal or passivating scope. @@ -531,17 +387,6 @@ public int getQualifierHashCode(Annotation qualifier); public int getInterceptorBindingHashCode(Annotation interceptorBinding); ---- -[[bm_obtain_active_context]] - -==== Obtaining the active `Context` for a scope - -The method `BeanManager.getContext()` retrieves an active context object associated with the given scope, as defined in <>. - -[source, java] ----- -public Context getContext(Class scopeType); ----- - [[bm_obtain_elresolver]] ==== Obtaining the `ELResolver` @@ -694,24 +539,14 @@ The method `BeanManager.getInterceptionFactory()` returns an `InterceptionFactor If the actual type parameter of the method is not a Java class, non-portable behavior results. -[[bm_obtain_instance]] +[[bm_obtain_instance_full]] -==== Obtain an `Instance` +==== Obtain an `Instance` in {cdi_full} -The method `BeanManager.createInstance()` returns an `Instance` to request bean instances programmatically as described in <>. +In addition to rules defined in <>, the following rules apply. The returned `Instance` object can only access instances of beans that are available for injection in the module or library containing the class into which the `BeanManager` was injected or the Jakarta EE component from whose JNDI environment namespace the `BeanManager` was obtained, according to the rules defined in <>. -[source, java] ----- -Instance createInstance(); ----- - -Instances of dependent scoped beans obtained with this `Instance` object must be explicitly released by calling `Instance.destroy()` method. - -If no qualifier is passed to `Instance.select()` method, the `@Default` qualifier is assumed. - - [[alternative_metadata_sources]] === Alternative metadata sources @@ -1030,7 +865,7 @@ void beforeBeanDiscovery(@Observes @Priority(jakarta.interceptor.Interceptor.Pri For each service provider, the container must provide a bean of scope `@ApplicationScoped` and qualifier `@Default`, supporting injection of a reference to the service provider instance. The bean types of this bean include the class of the service provider and all superclasses and interfaces. -Lifecycle events described below can be grouped in to two categories: +Lifecycle events described below can be grouped into two categories: * Application lifecycle events, that are fired once: ** BeforeBeanDiscovery diff --git a/spec/src/main/asciidoc/core/spi_lite.asciidoc b/spec/src/main/asciidoc/core/spi_lite.asciidoc index 747983bd4..03dda92f2 100644 --- a/spec/src/main/asciidoc/core/spi_lite.asciidoc +++ b/spec/src/main/asciidoc/core/spi_lite.asciidoc @@ -2,7 +2,11 @@ == Build time extensions +// TODO [NOTE] ==== TBD ==== + +// Must mention that Build Compatible Extensions do not have access to the CDI container, +// as there may not be one running! Calling `CDI.current()` inside them results in non-portable behavior. diff --git a/spec/src/main/asciidoc/javaee/definition_ee.asciidoc b/spec/src/main/asciidoc/javaee/definition_ee.asciidoc index 8d33a945e..74e615ba9 100644 --- a/spec/src/main/asciidoc/javaee/definition_ee.asciidoc +++ b/spec/src/main/asciidoc/javaee/definition_ee.asciidoc @@ -52,7 +52,7 @@ CDI scopes add to Jakarta EE these missing well-defined lifecycle context as def ==== Built-in scope types in Jakarta EE -When running in Jakarta EE, the implementations of the @RequestScoped, @ApplicationScoped and @SessionScoped annotations provided by the container, represent the standard scopes defined by the Java Servlets specification. +When running in Jakarta EE, the implementations of the `@RequestScoped`, `@ApplicationScoped` and `@SessionScoped` annotations provided by the container, represent the standard scopes defined by the Java Servlets specification. [[default_bean_discovery_ee]] diff --git a/spec/src/main/asciidoc/javaee/events_ee.asciidoc b/spec/src/main/asciidoc/javaee/events_ee.asciidoc index 67f514f51..5e857f665 100644 --- a/spec/src/main/asciidoc/javaee/events_ee.asciidoc +++ b/spec/src/main/asciidoc/javaee/events_ee.asciidoc @@ -19,6 +19,6 @@ If a non-static method of a session bean class has a parameter annotated `@Obser ==== Observer method invocation context in Jakarta EE -When Running in Jakarta EE, the container must extend the rules defined in <> and must also ensure that all kinds of observers are called in the same client security context as the invocation of `Event.fire()` or `Event.fireAsync()`. +When running in Jakarta EE, the container must extend the rules defined in <> and must also ensure that all kinds of observers are called in the same client security context as the invocation of `Event.fire()` or `Event.fireAsync()`. The transaction and security contexts for a business method exposed by a local business interface of an EJB session bean also depend upon the transaction attribute and `@RunAs` descriptor, if any. diff --git a/spec/src/main/asciidoc/javaee/implementation_ee.asciidoc b/spec/src/main/asciidoc/javaee/implementation_ee.asciidoc index 20c066e68..7e5d1524d 100644 --- a/spec/src/main/asciidoc/javaee/implementation_ee.asciidoc +++ b/spec/src/main/asciidoc/javaee/implementation_ee.asciidoc @@ -18,7 +18,7 @@ Other containers are not required to provide support for injection or lifecycle ==== Which Java classes are managed beans in Jakarta EE? -When running in Jakarta EE, A top-level Java class is a managed bean if it meets requirements described in <> or if it is defined to be a managed bean by any other Jakarta EE specification and if +When running in Jakarta EE, a top-level Java class is a managed bean if it meets requirements described in <> or if it is defined to be a managed bean by any other Jakarta EE specification and if * It is not annotated with an EJB component-defining annotation or declared as an EJB bean class in `ejb-jar.xml`. diff --git a/spec/src/main/asciidoc/javaee/injectionandresolution_ee.asciidoc b/spec/src/main/asciidoc/javaee/injectionandresolution_ee.asciidoc index ded3af689..82649eff3 100644 --- a/spec/src/main/asciidoc/javaee/injectionandresolution_ee.asciidoc +++ b/spec/src/main/asciidoc/javaee/injectionandresolution_ee.asciidoc @@ -85,9 +85,9 @@ When running in Jakarta EE, the container must extend the rules defined for mana The container is also required to ensure that: --* Initializer methods declared by a class X in the type hierarchy of the bean are called after all Jakarta EE component environment resource dependencies declared by X or by superclasses of X have been injected. --* Any `@PostConstruct` callback declared by a class X in the type hierarchy of the bean is called after all Jakarta EE component environment resource dependencies declared by X or by superclasses of X have been injected. --* Any servlet `init()` method is called after all initializer methods have been called, all injected fields have been initialized and all Jakarta EE component environment resource dependencies have been injected. +* Initializer methods declared by a class X in the type hierarchy of the bean are called after all Jakarta EE component environment resource dependencies declared by X or by superclasses of X have been injected. +* Any `@PostConstruct` callback declared by a class X in the type hierarchy of the bean is called after all Jakarta EE component environment resource dependencies declared by X or by superclasses of X have been injected. +* Any servlet `init()` method is called after all initializer methods have been called, all injected fields have been initialized and all Jakarta EE component environment resource dependencies have been injected. [[dependent_objects_destruction_ee]] diff --git a/spec/src/main/asciidoc/javaee/javaeeintegration.asciidoc b/spec/src/main/asciidoc/javaee/javaeeintegration.asciidoc index 7dd2226e9..e05509ba1 100644 --- a/spec/src/main/asciidoc/javaee/javaeeintegration.asciidoc +++ b/spec/src/main/asciidoc/javaee/javaeeintegration.asciidoc @@ -1,7 +1,9 @@ [partintro] -- -This part of the document, specifies additional rules or features when using CDI in a Jakarta EE container. +This part of the document specifies additional rules or features when using CDI in a Jakarta EE container. All content defined in <> applies to this part. + +CDI implementations in Jakarta EE containers are required to support {cdi_full}. -- include::definition_ee.asciidoc[] diff --git a/spec/src/main/asciidoc/javaee/packagingdeployment_ee.asciidoc b/spec/src/main/asciidoc/javaee/packagingdeployment_ee.asciidoc index 93525384a..118a68ad0 100644 --- a/spec/src/main/asciidoc/javaee/packagingdeployment_ee.asciidoc +++ b/spec/src/main/asciidoc/javaee/packagingdeployment_ee.asciidoc @@ -9,7 +9,7 @@ When running in Jakarta EE, the container must extend the rules defined in <> with: * An _implicit bean archive_ may also contain EJB session beans, and -* EJB session bean should be considered as bean class with bean defining annotation when determining if and archive is an _implicit bean archive_. +* EJB session bean should be considered as bean class with bean defining annotation when determining if an archive is an _implicit bean archive_. When determining which archives are bean archives, the container must also consider: @@ -49,7 +49,7 @@ In Jakarta EE, the container automatically discovers EJB session beans and other ==== Bean discovery in Jakarta EE -When running in Jakarta EE, the container must extend the rules defined in <> and must also discover each EJB session beans. +When running in Jakarta EE, the container must extend the rules defined in <> and must also discover each EJB session bean. [[trimmed_bean_archive_ee]] diff --git a/spec/src/main/asciidoc/javaee/spi_ee.asciidoc b/spec/src/main/asciidoc/javaee/spi_ee.asciidoc index 1c6c69874..199020983 100644 --- a/spec/src/main/asciidoc/javaee/spi_ee.asciidoc +++ b/spec/src/main/asciidoc/javaee/spi_ee.asciidoc @@ -6,13 +6,13 @@ === The `Bean` interface in Jakarta EE -When Running in Jakarta EE, the container must extend the rules defined in <> for managed bean to EJB session bean. +When running in Jakarta EE, the container must extend the rules defined in <> for managed bean to EJB session bean. [[interceptor_ee]] ==== The `Interceptor` interface in Jakarta EE -When Running in Jakarta EE, the container must extend the rules defined in <> and must also ensure that +When running in Jakarta EE, the container must extend the rules defined in <> and must also ensure that `PRE_PASSIVATE`, `POST_ACTIVATE` and `AROUND_TIMEOUT` InterceptorType values are linked to EJB lifecycle callback or timeout method. @@ -23,7 +23,7 @@ When Running in Jakarta EE, the container must extend the rules defined in <> and must also ensure that: -* when `inject()` is called, The container performs Jakarta EE component environment injection, according to the semantics required by the Jakarta EE platform specification, sets the value of all injected fields, and calls all initializer methods, as defined in <>. +* when `inject()` is called, the container performs Jakarta EE component environment injection, according to the semantics required by the Jakarta EE platform specification, sets the value of all injected fields, and calls all initializer methods, as defined in <>. * `@PostConstruct` callback is called according to the semantics required by the Jakarta EE platform specification. * `@PreDestroy` callback is called according to the semantics required by the Jakarta EE platform specification. @@ -110,7 +110,7 @@ In addition to definition given in <> the following apply: Resources are considered to be producer fields. -When running in Jakarta EE, the interface `jakarta.enterprise.inject.spi.ProcessBean` is also a supertype of `jakarta.enterprise.inject.spi.ProcessSession` : +When running in Jakarta EE, the interface `jakarta.enterprise.inject.spi.ProcessBean` is also a supertype of `jakarta.enterprise.inject.spi.ProcessSessionBean` : [source, java] ---- diff --git a/spec/src/main/asciidoc/javase/bootstrap_se.asciidoc b/spec/src/main/asciidoc/javase/bootstrap_se.asciidoc index 29784e0a2..c4b5cc5bd 100644 --- a/spec/src/main/asciidoc/javase/bootstrap_se.asciidoc +++ b/spec/src/main/asciidoc/javase/bootstrap_se.asciidoc @@ -5,7 +5,7 @@ In Java SE, the CDI container must be explicitly bootstrapped by the user. This is performed by the `SeContainerInitializer` abstract class and its static method `newInstance()`. -`SeContainerInitializer` is a `ServiceProvider` of the service `jakarta.enterprise.inject.se.SeContainerInitializer` declared in META-INF/services. +`SeContainerInitializer` is a service provider of the service `jakarta.enterprise.inject.se.SeContainerInitializer` declared in META-INF/services. This class allows a user to configure the CDI container before it is bootstrapped. The `SeContainerInitializer.initialize()` method bootstraps the container and returns a `SeContainer` instance. @@ -19,7 +19,7 @@ CDI container can be configured and bootstrapped from `jakarta.enterprise.inject A CDI implementation is required to provide an implementation of `SeContainerInitializer` declared as a service provider. Static method `newInstance()` uses Java service provider mechanism to obtain an implementation of `SeContainerInitializer` and return an instance of it. -There must be exactly one provider available, otherwise an IllegalStateException is thrown. +There must be exactly one provider available, otherwise an `IllegalStateException` is thrown. `SeContainerInitializer` configuration allows explicit addition of elements to the set of automatically discovered elements. These additions are done in an internal synthetic bean archive that is added to the set of bean archives discovered by the container during deployment. @@ -101,7 +101,7 @@ If it is called and the container was already shutdown, it throws an `IllegalSta * `getBeanManager()` method returns the `BeanManager` (as defined in <>) for the running container. If it is called and the container was already shutdown, it throws an `IllegalStateException`. -SeContainer implements `jakarta.enterprise.inject.Instance` and therefore might be used to perform programmatic lookup as defined in <>. +`SeContainer` implements `jakarta.enterprise.inject.Instance` and therefore might be used to perform programmatic lookup as defined in <>. If no qualifier is passed to `SeContainer.select()` method, the `@Default` qualifier is assumed. If any `Instance.select()` method is called and the container was already shutdown, the `IllegalStateException` is thrown. diff --git a/spec/src/main/asciidoc/javase/javase.asciidoc b/spec/src/main/asciidoc/javase/javase.asciidoc index 4a61a4ebe..0cce1b969 100644 --- a/spec/src/main/asciidoc/javase/javase.asciidoc +++ b/spec/src/main/asciidoc/javase/javase.asciidoc @@ -2,6 +2,7 @@ -- This part of the document specifies additional rules and features when using CDI in Java SE. All content defined in <> applies to this part. +// TODO are implementations required to support Full? -- include::bootstrap_se.asciidoc[] diff --git a/spec/src/main/asciidoc/javase/packagingdeployment_se.asciidoc b/spec/src/main/asciidoc/javase/packagingdeployment_se.asciidoc index e7cea3fa8..64359c922 100644 --- a/spec/src/main/asciidoc/javase/packagingdeployment_se.asciidoc +++ b/spec/src/main/asciidoc/javase/packagingdeployment_se.asciidoc @@ -8,7 +8,7 @@ When running in Java SE, the container must extend the rules defined in <> and also ensure that : -An archive which doesn't contain a beans.xml file can't be discovered as an _implicit bean archive_ unless: +An archive which doesn't contain a `beans.xml` file can't be discovered as an _implicit bean archive_ unless: * the application is launched with system property `jakarta.enterprise.inject.scan.implicit` set to `true`, or * the container was initialized with a map containing an entry parameter with `jakarta.enterprise.inject.scan.implicit` as key and `Boolean.TRUE` as value. diff --git a/spec/src/main/asciidoc/preface.asciidoc b/spec/src/main/asciidoc/preface.asciidoc index f5d12ae3c..30b56176a 100644 --- a/spec/src/main/asciidoc/preface.asciidoc +++ b/spec/src/main/asciidoc/preface.asciidoc @@ -3,6 +3,7 @@ == Preface +// TODO [NOTE] ==== This part has to be rewritten to present a consitent history of the spec @@ -20,28 +21,28 @@ include::license-{license}.asciidoc[] This document is organized in 4 parts: * An introduction (this part), which is not part of the specification but introduces CDI concepts and gives examples. -* Core CDI specification: <>. -** CDI Lite specification which contains a subset of CDI features a which can be implemented in more restricted environments -** CDI Full specification that builds on top of Lite and adds all advanced CDI features; this is the standard Jakarta EE CDI platform +* Core CDI specification: <>. This part has two sections: +** {cdi_lite} specification which contains a subset of CDI features and which can be implemented in more restricted environments; +** {cdi_full} specification that builds on top of Lite and adds all advanced CDI features; this is the standard Jakarta EE CDI platform. * Specific CDI features for Java SE: <>. * Specific CDI features for Jakarta EE: <>. === Major changes -CDI 4.0 splits the core CDI into Lite and Full. Lite contains a subset of original features which are designed to work under more restricted environments. CDI Full contains everything that is in Lite plus all other features that were formerly in core CDI and are not in Lite. +CDI 4.0 splits the CDI core into Lite and Full. Lite contains a subset of original features which are designed to work in more restricted environments. CDI Full contains everything that is in Lite plus all other features that were formerly in core CDI and are not in Lite. Jakarta Contexts and Dependency Injection 3.0 (link:https://jakarta.ee/specifications/cdi/3.0/[CDI 3.0]) is an update to Jakarta Contexts and Dependency Injection 2.0 (link:https://jakarta.ee/specifications/cdi/3.0/[CDI 2.0]). CDI 3.0 includes a change in the base namespace used by the APIs from -javax to jakarta. For example, the `BeanManager` interface has moved from +`javax` to `jakarta`. For example, the `BeanManager` interface has moved from `javax.enterprise.inject.spi.BeanManager` to `jakarta.enterprise.inject.spi.BeanManager`. -There is a new beans.xml 3.0 schema file has been added and the namespace of the -beans_3_0.xsd schema file has changed from xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee" to -xmlns:jakartaee="https://jakarta.ee/xml/ns/jakartaee". +New `beans.xml` 3.0 schema file has been added and the namespace of the +`beans_3_0.xsd` schema file has changed from `xmlns:javaee="http://xmlns.jcp.org/xml/ns/javaee"` to +`xmlns:jakartaee="https://jakarta.ee/xml/ns/jakartaee"`. -Starting with version 2.0 CDI targets Java SE and Jakarta EE platforms. +Starting with version 2.0, CDI targets Java SE and Jakarta EE platforms. CDI in Java SE and CDI in a Jakarta EE container share the features defined in core CDI. :numbered: \ No newline at end of file From e29216e3608347aaaee66f9957d9632b54d64b92 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Tue, 4 May 2021 15:20:19 +0200 Subject: [PATCH 08/11] remove duplicate interceptors_full inclusion --- spec/src/main/asciidoc/cdi-spec.asciidoc | 2 -- 1 file changed, 2 deletions(-) diff --git a/spec/src/main/asciidoc/cdi-spec.asciidoc b/spec/src/main/asciidoc/cdi-spec.asciidoc index 721f02268..cf376483c 100644 --- a/spec/src/main/asciidoc/cdi-spec.asciidoc +++ b/spec/src/main/asciidoc/cdi-spec.asciidoc @@ -77,8 +77,6 @@ include::core/interceptors_full.asciidoc[] include::core/decorators.asciidoc[] -include::core/interceptors_full.asciidoc[] - include::core/events_full.asciidoc[] include::core/spi.asciidoc[] From b1638a2e057a9df125c54f2a52fcd42af39fbad6 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Tue, 4 May 2021 17:49:47 +0200 Subject: [PATCH 09/11] actually include the beanmanager_lite.asciidoc file --- spec/src/main/asciidoc/cdi-spec.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/src/main/asciidoc/cdi-spec.asciidoc b/spec/src/main/asciidoc/cdi-spec.asciidoc index cf376483c..a57fb00c4 100644 --- a/spec/src/main/asciidoc/cdi-spec.asciidoc +++ b/spec/src/main/asciidoc/cdi-spec.asciidoc @@ -53,7 +53,7 @@ include::core/interceptors.asciidoc[] include::core/events.asciidoc[] -include::core/beanmanager_lite.asciidoc +include::core/beanmanager_lite.asciidoc[] include::core/spi_lite.asciidoc[] From d8d288585ebf4f1a255d99ae43b42cacbd05f6a8 Mon Sep 17 00:00:00 2001 From: Matej Novotny Date: Wed, 5 May 2021 12:02:11 +0200 Subject: [PATCH 10/11] Rename occurrences of BeanManagerLite to BeanContainer. --- .../asciidoc/core/beanmanager_lite.asciidoc | 52 +++++++++---------- spec/src/main/asciidoc/core/events.asciidoc | 2 +- spec/src/main/asciidoc/core/spi.asciidoc | 6 +-- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc b/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc index f8715090e..42eb60d58 100644 --- a/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc +++ b/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc @@ -3,51 +3,51 @@ == Programmatic access to container CDI 3.0 used to provide a single `BeanManager` object, which allows access to many useful operations. -In CDI 4.0, this is split into `BeanManagerLite` and `BeanManager`. +In CDI 4.0, this is split into `BeanContainer` and `BeanManager`. -`BeanManagerLite` provides access to a subset of `BeanManager` features which can be implemented in more restricted environments; +`BeanContainer` provides access to a subset of `BeanManager` features which can be implemented in more restricted environments; It is available in {cdi_lite} environments. -`BeanManager` extends `BeanManagerLite` and provides the remaining features. +`BeanManager` extends `BeanContainer` and provides the remaining features. It is available in {cdi_full} environments. In {cdi_lite} environment, attempting to obtain a `BeanManager` or invoking methods on it results in non-portable behavior. [[beanmanager]] -=== The `BeanManagerLite` object +=== The `BeanContainer` object -The interface `jakarta.enterprise.inject.spi.BeanManagerLite` provides operations for obtaining contextual references for beans, along with many other operations of use to applications. +The interface `jakarta.enterprise.inject.spi.BeanContainer` provides operations for obtaining contextual references for beans, along with many other operations of use to applications. -The container provides a built-in bean with bean type `BeanManagerLite`, scope `@Dependent` and qualifier `@Default`. -Thus, any bean may obtain an instance of `BeanManagerLite` by injecting it: +The container provides a built-in bean with bean type `BeanContainer`, scope `@Dependent` and qualifier `@Default`. +Thus, any bean may obtain an instance of `BeanContainer` by injecting it: [source, java] ---- -@Inject BeanManagerLite manager; +@Inject BeanContainer manager; ---- -The operations of `BeanManagerLite` may be called at any time during the execution of the application. +The operations of `BeanContainer` may be called at any time during the execution of the application. [[provider]] ==== Obtaining a reference to the CDI container Application objects sometimes interact directly with the container via programmatic API call. -The abstract class `jakarta.enterprise.inject.spi.CDI` provides access to the `BeanManagerLite` as well providing lookup of bean instances. +The abstract class `jakarta.enterprise.inject.spi.CDI` provides access to the `BeanContainer` as well providing lookup of bean instances. [source, java] ---- public abstract class CDI implements Instance { public static CDI current() { ... } public static void setCDIProvider(CDIProvider provider); - public abstract BeanManagerLite getBeanManagerLite(); + public abstract BeanContainer getBeanContainer(); public abstract BeanManager getBeanManager(); } ---- An object may obtain a reference to the current container by calling `CDI.current()`. -`CDI.getBeanManagerLite()`, as well as other methods on `CDI`, may be called after the application initialization is completed until the application shutdown starts. +`CDI.getBeanContainer()`, as well as other methods on `CDI`, may be called after the application initialization is completed until the application shutdown starts. If methods on `CDI` are called at any other time, non-portable behavior results. `CDI` implements `jakarta.enterprise.inject.Instance` and therefore might be used to perform programmatic lookup as defined in <>. @@ -76,7 +76,7 @@ If this method is not implemented the default priority `0` is assumed. ==== Obtaining a contextual reference for a bean -The method `BeanManagerLite.getReference()` returns a contextual reference for a given bean and bean type, as defined in <>. +The method `BeanContainer.getReference()` returns a contextual reference for a given bean and bean type, as defined in <>. [source, java] ---- @@ -93,7 +93,7 @@ If the given type is not a bean type of the given bean, an `IllegalArgumentExcep ==== Obtaining an injectable reference -The method `BeanManagerLite.getInjectableReference()` returns an injectable reference for a given injection point, as defined in <>. +The method `BeanContainer.getInjectableReference()` returns an injectable reference for a given injection point, as defined in <>. [source, java] ---- @@ -105,13 +105,13 @@ The second parameter is an instance of `CreationalContext` that may be used to d If typesafe resolution results in an unsatisfied dependency, the container must throw an `UnsatisfiedResolutionException`. If typesafe resolution results in an unresolvable ambiguous dependency, the container must throw an `AmbiguousResolutionException`. -Implementations of `Bean` usually maintain a reference to an instance of `BeanManagerLite`. When the `Bean` implementation performs dependency injection, it must obtain the contextual instances to inject by calling `BeanManagerLite.getInjectableReference()`, passing an instance of `InjectionPoint` that represents the injection point and the instance of `CreationalContext` that was passed to `Bean.create()`. +Implementations of `Bean` usually maintain a reference to an instance of `BeanContainer`. When the `Bean` implementation performs dependency injection, it must obtain the contextual instances to inject by calling `BeanContainer.getInjectableReference()`, passing an instance of `InjectionPoint` that represents the injection point and the instance of `CreationalContext` that was passed to `Bean.create()`. [[bm_obtain_creationalcontext]] ==== Obtaining a `CreationalContext` -An instance of `CreationalContext` for a certain instance of `Contextual` may be obtained by calling `BeanManagerLite.createCreationalContext()`. +An instance of `CreationalContext` for a certain instance of `Contextual` may be obtained by calling `BeanContainer.createCreationalContext()`. [source, java] ---- @@ -124,7 +124,7 @@ An instance of `CreationalContext` for a non-contextual object may be obtained b ==== Obtaining a `Bean` by type -The method `BeanManagerLite.getBeans()` returns the set of beans which have the given required type and qualifiers and are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules for candidates of typesafe resolution defined in <>. +The method `BeanContainer.getBeans()` returns the set of beans which have the given required type and qualifiers and are available for injection in the module or library containing the class into which the `BeanContainer` was injected, according to the rules for candidates of typesafe resolution defined in <>. [source, java] ---- @@ -145,7 +145,7 @@ If an instance of an annotation that is not a qualifier type is given, an `Illeg ==== Obtaining a `Bean` by name -The method `BeanManagerLite.getBeans()` which accepts a string returns the set of beans which have the given bean name and are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules of name resolution defined in <>. +The method `BeanContainer.getBeans()` which accepts a string returns the set of beans which have the given bean name and are available for injection in the module or library containing the class into which the `BeanContainer` was injected, according to the rules of name resolution defined in <>. [source, java] ---- @@ -158,7 +158,7 @@ The parameter is a bean name. ==== Resolving an ambiguous dependency -The method `BeanManagerLite.resolve()` applies the ambiguous dependency resolution rules defined in <> to a set of `Bean` s. +The method `BeanContainer.resolve()` applies the ambiguous dependency resolution rules defined in <> to a set of `Bean` s. [source, java] ---- @@ -167,7 +167,7 @@ public Bean resolve(Set> beans); If the ambiguous dependency resolution rules fail (as defined in <>, the container must throw an `AmbiguousResolutionException`. -`BeanManagerLite.resolve()` must return null if: +`BeanContainer.resolve()` must return null if: * null is passed to `resolve()`, or * no beans are passed to `resolve()`. @@ -176,7 +176,7 @@ If the ambiguous dependency resolution rules fail (as defined in <>. +The method `BeanContainer.resolveObserverMethods()` resolves observer methods for an event according to the rules of observer resolution defined in <>. [source, java] ---- @@ -209,7 +209,7 @@ If an instance of an annotation that is not a qualifier type is given, an `Illeg ==== Interceptor resolution -The method `BeanManagerLite.resolveInterceptors()` returns the ordered list of interceptors for a set of interceptor bindings and a type of interception and which are enabled in the module or library containing the class into which the `BeanManagerLite` was injected, as defined in <>. +The method `BeanContainer.resolveInterceptors()` returns the ordered list of interceptors for a set of interceptor bindings and a type of interception and which are enabled in the module or library containing the class into which the `BeanContainer` was injected, as defined in <>. [source, java] ---- @@ -243,7 +243,7 @@ public boolean isStereotype(Class annotationType); ==== Obtaining the active `Context` for a scope -The method `BeanManagerLite.getContext()` retrieves an active context object associated with the given scope, as defined in <>. +The method `BeanContainer.getContext()` retrieves an active context object associated with the given scope, as defined in <>. [source, java] ---- @@ -254,9 +254,9 @@ public Context getContext(Class scopeType); ==== Obtain an `Instance` -The method `BeanManagerLite.createInstance()` returns an `Instance` to request bean instances programmatically as described in <>. +The method `BeanContainer.createInstance()` returns an `Instance` to request bean instances programmatically as described in <>. -The returned `Instance` object can only access instances of beans that are available for injection in the module or library containing the class into which the `BeanManagerLite` was injected, according to the rules defined in <>. +The returned `Instance` object can only access instances of beans that are available for injection in the module or library containing the class into which the `BeanContainer` was injected, according to the rules defined in <>. [source, java] ---- diff --git a/spec/src/main/asciidoc/core/events.asciidoc b/spec/src/main/asciidoc/core/events.asciidoc index 5361599f2..0d577491b 100644 --- a/spec/src/main/asciidoc/core/events.asciidoc +++ b/spec/src/main/asciidoc/core/events.asciidoc @@ -435,7 +435,7 @@ public interface EventMetadata { * `getQualifiers()` returns the set of qualifiers with which the event was fired. * `getInjectionPoint()` returns the `InjectionPoint` from which this event payload was fired, or `null` if it was fired from `BeanManager.getEvent()`. -// TODO BeanManagerLite +// TODO BeanContainer * `getType()` returns the type representing runtime class of the event object with type variables resolved. diff --git a/spec/src/main/asciidoc/core/spi.asciidoc b/spec/src/main/asciidoc/core/spi.asciidoc index 7c3e8117c..1a2b0085e 100644 --- a/spec/src/main/asciidoc/core/spi.asciidoc +++ b/spec/src/main/asciidoc/core/spi.asciidoc @@ -210,8 +210,8 @@ In addition to rules defined in <>, the following rules apply. The interface `jakarta.enterprise.inject.spi.BeanManager` provides operations for obtaining contextual references for beans, along with many other operations of use to applications and portable extensions. -The interface `jakarta.enterprise.inject.spi.BeanManager` extends `jakarta.enterprise.inject.spi.BeanManagerLite`. -In {cdi_full} environment, `BeanManagerLite` is subject to the same rules as `BeanManager`. +The interface `jakarta.enterprise.inject.spi.BeanManager` extends `jakarta.enterprise.inject.spi.BeanContainer`. +In {cdi_full} environment, `BeanContainer` is subject to the same rules as `BeanManager`. The container provides a built-in bean with bean type `BeanManager`, scope `@Dependent` and qualifier `@Default`. The built-in implementation must be a passivation capable dependency, as defined in <>. Thus, any bean may obtain an instance of `BeanManager` by injecting it: @@ -251,7 +251,7 @@ Portable extensions and other objects sometimes interact directly with the conta The abstract `jakarta.enterprise.inject.spi.CDI` provides access to the `BeanManager` as well providing lookup of bean instances. A portable extension or other object may obtain a reference to the current container by calling `CDI.current()`. -`CDI.getBeanManager()` and `CDI.getBeanManagerLite()` may be called at any time after the container fires the `BeforeBeanDiscovery` container lifecycle event until the container fires the `BeforeShutdown` container lifecycle event. +`CDI.getBeanManager()` and `CDI.getBeanContainer()` may be called at any time after the container fires the `BeforeBeanDiscovery` container lifecycle event until the container fires the `BeforeShutdown` container lifecycle event. If methods on `CDI` are called at any other time, non-portable behavior results. [[bm_obtain_injectable_reference_full]] From 864e1b4f779e4d6d5a80f147d975a510446d4987 Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Wed, 5 May 2021 11:31:12 +0200 Subject: [PATCH 11/11] fix some typos and clumsy wording --- .../main/asciidoc/core/beanmanager_lite.asciidoc | 16 ++++++++-------- .../core/injectionandresolution_full.asciidoc | 2 +- .../asciidoc/core/interceptors_full.asciidoc | 2 +- spec/src/main/asciidoc/core/spi.asciidoc | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc b/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc index 42eb60d58..602ba5863 100644 --- a/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc +++ b/spec/src/main/asciidoc/core/beanmanager_lite.asciidoc @@ -2,18 +2,17 @@ == Programmatic access to container -CDI 3.0 used to provide a single `BeanManager` object, which allows access to many useful operations. -In CDI 4.0, this is split into `BeanContainer` and `BeanManager`. +The `BeanContainer` and `BeanManager` interfaces allow programmatic access to the CDI container. -`BeanContainer` provides access to a subset of `BeanManager` features which can be implemented in more restricted environments; -It is available in {cdi_lite} environments. +`BeanContainer` provides features that can be implemented in more restricted environments. +It is available in {cdi_lite} environment, and therefore also in {cdi_full} environment. -`BeanManager` extends `BeanContainer` and provides the remaining features. -It is available in {cdi_full} environments. +`BeanManager` extends `BeanContainer` and provides additional features. +It is only available in {cdi_full} environment. In {cdi_lite} environment, attempting to obtain a `BeanManager` or invoking methods on it results in non-portable behavior. -[[beanmanager]] +[[beancontainer]] === The `BeanContainer` object @@ -24,10 +23,11 @@ Thus, any bean may obtain an instance of `BeanContainer` by injecting it: [source, java] ---- -@Inject BeanContainer manager; +@Inject BeanContainer container; ---- The operations of `BeanContainer` may be called at any time during the execution of the application. +// TODO Full has restrictions on when BeanManager methods can be called, do we want to reflect them here in some way? [[provider]] diff --git a/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc b/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc index 7569b123d..a7ba40ca2 100644 --- a/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc +++ b/spec/src/main/asciidoc/core/injectionandresolution_full.asciidoc @@ -15,7 +15,7 @@ An alternative is not available for injection, lookup or name resolution to clas ==== Declaring selected alternatives in {cdi_full} -{cdi_full} provides an additional way to select alternatives to the one defined in <>: +{cdi_full} provides an additional way to select alternatives to the one defined in <>. [[declaring_selected_alternatives_bean_archive]] diff --git a/spec/src/main/asciidoc/core/interceptors_full.asciidoc b/spec/src/main/asciidoc/core/interceptors_full.asciidoc index 4472aedb2..8ba8e791f 100644 --- a/spec/src/main/asciidoc/core/interceptors_full.asciidoc +++ b/spec/src/main/asciidoc/core/interceptors_full.asciidoc @@ -16,7 +16,7 @@ Interceptor bindings may be used to associate interceptors with any managed bean It is possible to apply interceptors programmatically to the return value of a producer method, with the `InterceptionFactory` interface as defined in <>. -[[enabled_interceptors_full]] +[[enabled_interceptors]] === Interceptor enablement and ordering in {cdi_full} diff --git a/spec/src/main/asciidoc/core/spi.asciidoc b/spec/src/main/asciidoc/core/spi.asciidoc index 1a2b0085e..77918663e 100644 --- a/spec/src/main/asciidoc/core/spi.asciidoc +++ b/spec/src/main/asciidoc/core/spi.asciidoc @@ -202,11 +202,11 @@ The container sets the value of all injected fields, and calls all initializer m Implementations of `Producer` and `InjectionTarget` must ensure that the set of injection points returned by `getInjectionPoints()` are injected by `produce()` or `inject()`. -[[beanmanager_full]] +[[beanmanager]] === The `BeanManager` object -In addition to rules defined in <>, the following rules apply. +In addition to rules defined in <>, the following rules apply. The interface `jakarta.enterprise.inject.spi.BeanManager` provides operations for obtaining contextual references for beans, along with many other operations of use to applications and portable extensions.