Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci-actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
- name: Get Date
id: get-date
run: |
echo "::set-output name=date::$(/bin/date -u "+%Y-%m")"
echo "date=$(/bin/date -u '+%Y-%m')" >> "$GITHUB_OUTPUT"
shell: bash
- name: Cache Maven Repository
id: cache-maven
Expand Down Expand Up @@ -360,7 +360,7 @@ jobs:

# Weld Examples build and test, only JDK 17
examples-tests:
name: "Weld Examples build and test - JDK 17}"
name: "Weld Examples build and test - JDK 17"
runs-on: ubuntu-latest
needs: initial-build
timeout-minutes: 120
Expand Down Expand Up @@ -416,7 +416,7 @@ jobs:
if: failure()
with:
name: server-log-examples
path: 'test-reports.tgz'
path: 'server-log.tgz'

# CDI TCK for SE environment
CDI-TCK-SE:
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ Weld
[![Maven Central](http://img.shields.io/maven-central/v/org.jboss.weld.se/weld-se-shaded.svg)](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22weld-core-impl%22)
[![License](https://img.shields.io/badge/license-Apache%20License%202.0-yellow.svg)](http://www.apache.org/licenses/LICENSE-2.0.html)

Weld is the reference implementation of CDI: Contexts and Dependency Injection for the Java EE Platform which is the Java standard for dependency injection and contextual lifecycle management and one of the most important and popular parts of the Java EE platform.
Weld is the reference implementation of Jakarta Contexts and Dependency Injection (CDI), the Java standard for dependency injection and contextual lifecycle management.

Weld is integrated into many Java EE application servers such as WildFly, JBoss Enterprise Application Platform, GlassFish, Oracle WebLogic and others. Weld can also be used in a Servlet-only environment (Tomcat, Jetty) or plain Java SE environment.
Weld can run in Jakarta EE application servers, Servlet containers (such as Tomcat and Jetty), and plain Java SE applications.

See http://weld.cdi-spec.org for more details.

Building Weld
-------------

To build Weld simply run
To build Weld, use Java 17 or newer and run

> $ mvn clean install

Expand Down
3 changes: 1 addition & 2 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,8 @@
</developers>

<properties>
<weld.api.bom.version>7.0.CR1</weld.api.bom.version>
<weld.api.bom.version>7.0.CR2</weld.api.bom.version>
<gpg.plugin.version>3.2.8</gpg.plugin.version>
<nexus.staging.plugin.version>1.7.0</nexus.staging.plugin.version>
<jboss.releases.repo.url>https://repository.jboss.org/nexus/service/local/staging/deploy/maven2/
</jboss.releases.repo.url>
<jboss.snapshots.repo.url>https://repository.jboss.org/nexus/content/repositories/snapshots/
Expand Down
2 changes: 1 addition & 1 deletion bundles/osgi/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@
<connection>scm:git:git@github.com:weld/core.git</connection>
<developerConnection>scm:git:git@github.com:weld/core.git</developerConnection>
<url>scm:git:git@github.com:weld/core.git</url>
<tag>6.0.0-SNAPSHOT</tag>
<tag>HEAD</tag>
</scm>

</project>
24 changes: 23 additions & 1 deletion docs/reference/src/main/asciidoc/configure.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ The following properties can be used to restrict the set of beans Weld is going
|=======================================================================
|Configuration key |Default value |Description
|`org.jboss.weld.bootstrap.unusedBeans.excludeType` |`ALL`| A regular expression. A bean whose `Bean#getBeanClass()` matches this pattern is never removed. Two special values are considered. `ALL` (default value) means that all beans are excluded. `NONE` means no beans are excluded.
|`org.jboss.weld.bootstrap.unusedBeans.excludeAnnotation` |`javax\\.ws\\.rs.*`| A regular expression. A bean is not removed if the corresponding `AnnotatedType`, or any member, is annotated with an annotation which matches this pattern. By default, a type annotated with any JAX-RS annotation is excluded from removal.
|`org.jboss.weld.bootstrap.unusedBeans.excludeAnnotation` |`jakarta\\.ws\\.rs.*`| A regular expression. A bean is not removed if the corresponding `AnnotatedType`, or any member, is annotated with an annotation which matches this pattern. By default, a type annotated with any JAX-RS annotation is excluded from removal.
|=======================================================================

[[legacy-empty-beans-xml]]
Expand Down Expand Up @@ -530,3 +530,25 @@ xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/
</web-app>
-----------------------------------------------------------------------------------------------------------


[[async_handler_selection]]
=== Selecting asynchronous invocation handlers

CDI provides asynchronous invocation handlers for `CompletionStage`, `CompletableFuture`, and `Flow.Publisher`.
Additional handlers are discovered through the `AsyncHandler.ReturnType` and `AsyncHandler.ParameterType` service-provider files.
If more than one handler is registered for the same async type, including a collision with a built-in handler, deployment fails by default.

Use `org.jboss.weld.invokable.asyncHandlers` to select a handler explicitly.
Its value is a comma-separated list of `asyncType=handlerClass` mappings using binary class names (`$` for nested classes).
For example, in `weld.properties`:

[source,properties]
----
org.jboss.weld.invokable.asyncHandlers=java.util.concurrent.CompletionStage=com.example.MyStageHandler
----

The selected handler must be registered through its service-provider file (or be a built-in handler) and declare the configured async type.
Other handlers for that type are ignored when selecting the handler.
An absent provider, a mismatched async type, a malformed mapping, or repeated mappings for the same async type cause deployment to fail.
The default value is an empty string, meaning that no explicit selections are made.
As with other Weld configuration properties, the value may also be supplied through a system property or external configuration.
2 changes: 1 addition & 1 deletion docs/reference/src/main/asciidoc/environments.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ While this works most of the time, there are few rare cases, when it might be ne
* `org.jboss.weld.environment.tomcat.TomcatContainer`
* `org.jboss.weld.environment.jetty.JettyContainer`
* `org.jboss.weld.environment.undertow.UndertowContainer`
* or any custom `org.jboss.weld.environment.Container` implementation
* or any custom `org.jboss.weld.environment.servlet.Container` implementation


[[weld-se]]
Expand Down
8 changes: 5 additions & 3 deletions docs/reference/src/main/asciidoc/extend.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ AnnotatedType<SomeFrameworkComponent> type = beanManager.createAnnotatedType(Som

//The extension uses an InjectionTarget to delegate instantiation, dependency injection
//and lifecycle callbacks to the CDI container
InjectionTarget<SomeFrameworkComponent> it = beanManager.createInjectionTarget(type);
InjectionTarget<SomeFrameworkComponent> it = beanManager.getInjectionTargetFactory(type).createInjectionTarget(null);

//each instance needs its own CDI CreationalContext
CreationalContext ctx = beanManager.createCreationalContext(null);
CreationalContext<SomeFrameworkComponent> ctx = beanManager.createCreationalContext(null);

//instantiate the framework component and inject its dependencies
SomeFrameworkComponent instance = it.produce(ctx); //call the constructor
Expand Down Expand Up @@ -317,6 +317,9 @@ public interface BeanAttributes<T> {
public String getName();
public Set<Class<? extends Annotation>> getStereotypes();
public boolean isAlternative();
public default boolean isReserve() { return false; }
public default boolean isEager() { return false; }
public default boolean isAutoClose() { return false; }
}
------------------------------------------------------------

Expand All @@ -328,7 +331,6 @@ everything the container needs to manage instances of a certain bean.
public interface Bean<T> extends Contextual<T>, BeanAttributes<T> {
public Class<?> getBeanClass();
public Set<InjectionPoint> getInjectionPoints();
public boolean isNullable();
}
-------------------------------------------------------------------

Expand Down
49 changes: 12 additions & 37 deletions docs/reference/src/main/asciidoc/injection.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -575,61 +575,36 @@ Since CDI 2.0, most annotations from `jakarta.enterprise` package have their `An
Therefore, in order to programmatically obtain (for instance) `@Any` annotation, you can simply do `Any.Literal.INSTANCE`.
====

==== Enhanced version of `jakarta.enterprise.inject.Instance`

Weld also provides `org.jboss.weld.inject.WeldInstance` - an enhanced version of `jakarta.enterprise.inject.Instance`.
There are three additional methods.
The first one - `getHandler()` - allows to obtain a contextual reference handler which not only holds the contextual reference but also allows to inspect the metadata of the relevant bean and to destroy the underlying contextual instance.
Moreover, the handler implements `AutoCloseable`:
`Instance.getHandle()` returns an `Instance.Handle<T>`, which provides access to the contextual reference through `get()`, bean metadata through `getBean()`, and explicit destruction through `destroy()`.
Handles also implement `AutoCloseable` and can be used in a try-with-resources statement:

[source.JAVA, java]
----------------------------------------------------------------------------------
import org.jboss.weld.inject.WeldInstance;
import jakarta.enterprise.inject.Instance;

class Foo {

@Inject
WeldInstance<Bar> instance;
Instance<Bar> instance;

void doWork() {
try (Handler<Bar> barHandler = instance.getHandler()) {
barHandler.get().doBusiness();
// Note that Bar will be automatically destroyed at the end of the try-with-resources statement
try (Instance.Handle<Bar> handle = instance.getHandle()) {
handle.get().doBusiness();
}
Handler<Bar> barHandler = instance.getHandler()
barHandler.get().doBusiness();
// Calls Instance.destroy()
barHandler.destroy();
}

}
----------------------------------------------------------------------------------

The next method - `handlers()` - returns an `Iterable` which allows to iterate over handlers for all the beans that have the required type and required qualifiers and are eligible for injection.
This might be useful if you need more control inside the loop:
`Instance.handles()` and `Instance.handlesStream()` provide iteration and streaming over handles for all matching beans.
These are standard CDI APIs and do not require a dependency on the Weld API.

[source.JAVA, java]
----------------------------------------------------------------------------------
@ApplicationScoped
class OrderService {
==== Enhanced version of `jakarta.enterprise.inject.Instance`

@Inject
@Any
WeldInstance<OrderProcessor> instance;

void create(Order order) {
for (Handler<OrderProcessor> handler : instance.handlers()) {
handler.get().process(order);
if (Dependent.class.equals(handler.getBean().getScope()) {
// Destroy only dependent processors
handler.destroy();
}
}
}
}
----------------------------------------------------------------------------------
Weld provides `org.jboss.weld.inject.WeldInstance`, which extends `Instance` with selection by `java.lang.reflect.Type` and `getHandlePriorityComparator()`.
The comparator sorts handles by descending bean priority and can be passed to `handlesStream().sorted(instance.getHandlePriorityComparator())`.

Third method is a twist on the `select()` method, but it accepts `java.lang.reflect.Type` as parameter and optionally qualifier(s).
Weld's additional `select()` overload accepts `java.lang.reflect.Type` as a parameter and optionally qualifier(s).
This allows for generic selection of instances which can be handy while dealing with third party beans through extensions.
However, in order to stay type-safe, this method has a limitation - it can only be invoked on `WeldInstance<Object>`.
Invocation on any other type than `Object` will result in an `IllegalStateException`.
Expand Down
88 changes: 10 additions & 78 deletions docs/reference/src/main/asciidoc/interceptors.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -336,89 +336,21 @@ in which interceptors are listed at the class level.

Therefore, we recommend the use of CDI-style interceptor bindings.

=== Enhanced version of `jakarta.interceptor.InvocationContext`
=== Accessing interceptor bindings

For even more control over interceptors, Weld offers enhanced version of `jakarta.interceptor.InvocationContext` - `org.jboss.weld.interceptor.WeldInvocationContext`.

NOTE: *The functionality described below is deprecated since Weld 6 and will be removed in the future. Users should instead use newly added methods directly from `jakarta.interceptor.InvocationContext`, hence removing the need to use Weld specific APIs for this purpose.*

It comes with two additional methods - `getInterceptorBindings` and `getInterceptorBindingsByType(Class<T> annotationType)`.
You shouldn't need this in most cases, but it comes handy when working with `@Nonbinding` values in interceptor binding annotations.

Assume you have the following interceptor binding:

[source.JAVA, java]
------------------------------------------------------------------------
@InterceptorBinding
@Inherited
@Target({ TYPE, METHOD, CONSTRUCTOR})
@Retention(RUNTIME)
public @interface FooBinding {

@Nonbinding
String secret() default "";

}
------------------------------------------------------------------------

Then, in the interceptor class, you can retrieve the secret `String` in the following way:

[source.JAVA, java]
-------------------------------------------------------------------------------------------------
@Priority(value = Interceptor.Priority.APPLICATION)
@Interceptor
@FooBinding(secret = "nonbinding")
public class AroundConstructInterceptor {

@SuppressWarnings("unchecked")
@AroundConstruct
void intercept(InvocationContext ctx) throws Exception {
if(ctx instanceof WeldInvocationContext) {
Set<Annotation> bindings = ((WeldInvocationContext)ctx).getInterceptorBindings();
for (Annotation annotation : bindings) {
if (annotation.annotationType().equals(FooBinding.class)) {
FooBinding fooBinding = (FooBinding) annotation;
String secret = fooBinding.secret();
}
}
}
ctx.proceed();
}
}
-------------------------------------------------------------------------------------------------

`WeldInvocationContext` can be used with the following interceptor types:

* `@AroundConstruct`
* `@PostConstruct`
* `@AroundInvoke`

Alternatively, you can gain access to these binding directly from `InvocationContext` as we store them there using a key `org.jboss.weld.interceptor.bindings`.
This key is easily accessible from `WeldInvocationContext.INTERCEPTOR_BINDINGS_KEY`.
Let's alter the previous example to demonstrate this:
Jakarta Interceptors provides `InvocationContext.getInterceptorBindings()` to obtain all bindings and `getInterceptorBindings(Class<T>)` to obtain bindings of a given type.
This is useful for reading `@Nonbinding` members, whose values do not affect interceptor selection.
For example, an interceptor can read a `FooBinding` annotation's `@Nonbinding String secret()` member as follows:

[source.JAVA, java]
-------------------------------------------------------------------------------------------------
@Priority(value = Interceptor.Priority.APPLICATION)
@Interceptor
@FooBinding(secret = "nonbinding")
public class AroundConstructInterceptor {

@SuppressWarnings("unchecked")
@AroundConstruct
void intercept(InvocationContext ctx) throws Exception {
// retrieve data directly from InvocationContext
Set<Annotation> bindings = (Set<Annotation>) ctx.getContextData().get(WeldInvocationContext.INTERCEPTOR_BINDINGS_KEY);
if (bindings != null) {
for (Annotation annotation : bindings) {
if (annotation.annotationType().equals(FooBinding.class)) {
FooBinding fooBinding = (FooBinding) annotation;
String secret = fooBinding.secret();
}
}
}
ctx.proceed();
@AroundInvoke
Object intercept(InvocationContext ctx) throws Exception {
for (FooBinding binding : ctx.getInterceptorBindings(FooBinding.class)) {
String secret = binding.secret();
// Use the value configured on the intercepted bean or method.
}
return ctx.proceed();
}
-------------------------------------------------------------------------------------------------

Expand Down
Loading
Loading