News

Weld meets Vert.x

2016-4-11   vertx , integration   Martin Kouba

Vert.x defines itself as "a toolkit for building reactive applications on the JVM". Sounds cool and trendy. Weld, on the other hand, comes from the Java EE world, based on standards and traditional concepts. But wait, what if we try to combine the two worlds to get the best of them?

Vert.x makes use of a light-weight distributed messaging system to allow application components to communicate in a loosely coupled way. This should sound familiar to all CDI users where beans may produce and consume events as well. Weld team developed a working prototype of Weld/Vert.x integration that allows to automatically register certain observer methods as Vert.x message consumers. A simple echo message consumer could look like this:

import org.jboss.weld.vertx.VertxConsumer;
    import org.jboss.weld.vertx.VertxEvent;
    
    class Foo {
        public void echoConsumer(@Observes @VertxConsumer("test.echo.address") VertxEvent event) {
            event.setReply(event.getMessageBody());
        }
    }
  • @VertxConsumer - a qualifier used to specify the address the consumer will be registered to: test.echo.address

  • VertxEvent - a wrapper of a Vert.x message

Since we’re working with a regular observer method, additional parameters may be declared (next to the event parameter). These parameters are injection points. So it’s easy to declare a message consumer dependencies:

public void consumerWithDependencies(@Observes @VertxConsumer("test.dependencies.address") VertxEvent event, CoolService coolService, StatsService statsService) {
        coolService.process(event.getMessageBody());
        statsService.log(event);
    }
Note
If you inject a dependent bean, it will be destroyed when the invocation completes.

Last but not least - an observer may also send/publish messages using the Vert.x event bus:

public void consumerStrikesBack(@Observes @VertxConsumer("test.publish.address") VertxEvent event) {
        event.messageTo("test.huhu.address").publish("huhu");
    }

And how does it work under the hood? First of all, it’s necessary to deploy org.jboss.weld.vertx.WeldVerticle. This Verticle starts Weld SE container and automatically registers org.jboss.weld.vertx.VertxExtension to process all observer methods and detect observers which should become message consumers. Then a special handler is registered for each address to bridge the event bus to the CDI world. Handlers use Vertx.executeBlocking() since we expect the code to be blocking. Later on, whenever a new message is delivered to the handler, Event.fire() is used to notify all relevant observers.

The prototype is surely missing some features. Nevertheless, it shows the CDI programming model might be applicable to the "reactive" world even if not a first class citizen. Moreover, the prototype demonstrates the flexibility of the CDI extension mechanism.

If you want to try it out, you’ll have to clone the https://github.com/weld/weld-vertx repository and build it from source (i.e. run mvn clean install). And if you find it useful feel free to add comments to this blog post. Any feedback is appreciated!


Weld 2.3.3.Final

2016-2-12   release   Martin Kouba

Weld 2.3.3.Final the next bug-fix version of the stable 2.3 branch has been released! See also the release details. Thanks to everyone involved in this release! Notable improvements:

WildFly Patch

As usual, a patch for WildFly is available. This time the target platform is WildFly 10.0.0.Final. If you’re not familiar with patching WildFly, check Markus’s tutorial.


Weld SE and synthetic container lifecycle event observers

2016-2-8   api , draft   Martin Kouba

Last week Weld 3.0.0.Alpha15 was released and so it’s time to reveal the features that should go into the next experimental release. The main goal of Weld 3.0.0.Alpha16 is to reflect the output of CDI-558. However, we would also like to continue to deliver experimental prototypes so that users could test a new functionality (that we find interesting and useful) and the CDI EG could eventually include this into CDI 2.0.

It should be easier to start playing with extensions in Weld SE. Right now, it’s possible to pass an Extension instance to the Weld builder so that it’s not necessary to configure service providers (i.e. META-INF/services/javax.enterprise.inject.spi.Extension file). In such case, the extension class is automatically scanned for observer methods and the instance is used as the receiver of the notifications. We would like to make this even easier. It is now possible to add a synthetic container lifecycle event observer without declaring an extension class. The observer logic is represented as a lambda expression. This might be especially useful for prototyping and/or for discovering how extensions work.

The starting point is the org.jboss.weld.environment.se.ContainerLifecycleObserver class. There are few static methods, each corresponding to a specific container lifecycle event (e.g. beforeBeanDiscovery()). Some variants return a builder so that it’s possible to customize the observer (observed type, priority, etc.). Others accept a lambda and return an observer instance direcly.

A synthetic observer may be added to the builder directly - see Weld.addContainerLifecycleObserver() - or grouped in a synthetic extension - see ContainerLifecycleObserver.extensionBuilder().

Extension testExtension = ContainerLifecycleObserver.extensionBuilder()
        .add(afterBeanDiscovery((e) -> System.out.println("Bean discovery completed!")))
        .add(processAnnotatedType().notify((e) -> {
                if (e.getAnnotatedType().getJavaClass().getName().startsWith("com.foo")) {
                    e.veto();
                }
            })).build();
    
    try (WeldContainer container = new Weld().addExtension(testExtension).initialize()) {
        // Use the container...
    }

This feature is merged in the master branch. If you want to try it out, you’ll have to use a 3.0.0-SNAPSHOT version or build the Weld from source: mvn clean install. Do you find it useful? Any feedback is appreciated! Feel free to add comments to this blog post or to the corresponding issue: WELD-2012.


Weld 3.0.0.Alpha15

2016-2-4   release , cdi2   Martin Kouba

Weld 3.0.0.Alpha15 the next experimental Weld version has been released. See also the release details.

The CompletionStage used to bind actions to the completion of the asynchronous delivery is now using org.jboss.weld.manager.api.ExecutorServices SPI as the default asynchronous execution facility. Previously, the ForkJoinPool#commonPool() (a default executor of the underlying CompletableFuture) was used. It’s an important change because the ForkJoinPool#commonPool() is not a good fit for Java EE. See also WELD-2073.

The ExperimentalAfterBeanDiscovery receives two more methods: interceptorBuilder() and addInterceptor(). An interceptor builder allows you to create an interceptor bean without the need to create an interceptor class. This might be handy for simple use cases:

class MyExtension {
      void afterBeanDiscovery(@Observes AfterBeanDiscovery event) {
        event.addInterceptor().intercept(InterceptionType.AROUND_INVOKE, (c) -> {
                long start = System.currentTimeMillis();
                try {
                    return c.proceed();
                } finally {
                    System.out.println("Time: " + System.currentTimeMillis() - start);
                }
            }).priority(2600).addBinding(MonitoringBinding.Literal.INSTANCE);
      }
    }

See also WELD-2008.

This release also contains some enhancements and bugfixes around proxies. E.g. better support for DeltaSpike partial beans (WELD-2084), better support for Camel CDI (WELD-2089) and better support for proxies with non public classes (WELD-2091). Furthermore, we are going to drop Jetty 7,8, 9.0, 9.1 and 9.2 support in Weld 3 (WELD-2032). Also the decorator validation was improved (WELD-2085, WELD-1811, WELD-2039). Last but not least, we have performed some SPI cleanup (WELD-2077, WELD-2079).

WildFly Patch

As usual, a patch for WildFly is available. This patch not only upgrades Weld within an existing WildFly instance but also upgrades CDI API to 2.0 EDR1. This time the target platform is WildFly 10.0.0.Final. If you’re not familiar with patching WildFly, check Markus’s tutorial.


Weld 2.3.2.Final

2015-12-10   release   Martin Kouba

Weld 2.3.2.Final the last version for this year has been released! It is a bug-fixing release with 15 issues resolved. See also the release details. Thanks to everyone involved in this release!

Notable bug-fixes and enhancements

  • Weld proxies - add workaround for IBM JVM 8 (WELD-2056 and DELTASPIKE-1010)

  • Fix resource injection when using arquillian-weld-ee-embedded-1.1 (WELD-2065 and ARQ-2000)

  • All conversation contexts should be destroyed after the Servlet.service() method completes (WELD-2052)

  • Clear RequestScopedCache for remote EJB calls (WELD-2069)

  • Weld Servlet

    • Allow to perform dependency injection upon objects not having a CDI-compatible constructor (WELD-2039)

    • Add Jandex support even for WARs not extracted to the file system (WELD-2070)

  • Probe development tool is now part of the OSGi bundle (WELD-2061)