News

Weld Tip 2 - Development Mode

2016-10-7   tips   Martin Kouba

In this article we’re going to cover the special mode for application development. When enabled, a built-in tool called Probe provides a detailed insight into internals of a CDI application. Probe makes it easy to inspect:

  • bean archives

  • beans and their properties such as qualifiers, stereotypes and name

  • a graph of bean dependencies

  • observers and producers declared by beans

  • interceptors and decorators bound to a bean

  • extensions

  • information about current contextual instances

  • tracking of invocations and invocation trees

  • tracking of fired events

  • Weld configuration

  • and more!

Ok, now let’s get it working!

How to enable the development mode

No surprise that the development mode is DISABLED by default. It should NEVER be used in production as it may have negative impact on performance and/or represent a potential security risk. Note that if you successfully enable the development mode you should see Weld Development Mode: ENABLED warning in the log during application bootstrap. Make sure to disable the development mode before deploying to production!

Web application

For any web application, set the Servlet initialization parameter org.jboss.weld.development to true:

<web-app>
        <context-param>
            <param-name>org.jboss.weld.development</param-name>
            <param-value>true</param-value>
        </context-param>
    </web-app>

WildFly

Since WildFly 10 it’s also possible to enable the Weld development mode globally (i.e. for all the applications deployed) by setting development-mode attribute to true:

/subsystem=weld:write-attribute(name=development-mode,value=true)

Weld SE

For a Java SE application, set the system property org.jboss.weld.development to true:

java -cp myCoolApp.jar -Dorg.jboss.weld.development=true com.foo.MyMain

or use the Weld.property() method:

org.jboss.weld.environment.se.Weld;
    
    public static void main(String[] args) {
       Weld weld = new Weld().property("org.jboss.weld.development", true);
       try (WeldContainer container = weld.initialize()) {
          ...
       }
    }

How does it actually work?

Probe collects CDI-related data from your application and then makes the data available through the REST API, eventually through the MXBean of name org.jboss.weld.probe:type=JsonData,context=ID where ID should be replaced with an idenfitier of an application.

Probe UI

Probe has also a web UI (single-page application) available at {webapp-context-path}/weld-probe (once your webapp starts), e.g. http://localhost:8080/weld-numberguess/weld-probe. By default, Probe also embeds a tiny information bar directly into the application’s HTML output. That makes it easy to navigate to Probe directly from the application anytime. Furthermore, if invocation tracking is enabled, the information bar helps navigate directly to the invocation tree related to the request that rendered the output.

  • The best place to start is probably the Beans view

  • You may also discover the observer methods declared by an extension

  • Monitor all the fired events and track which observer methods a particular event was delivered to

  • And more…​

We believe the UI is quite intuitive but feel free to ask questions on any channel (irc, gitter, mailing list, etc.).

Tip
There are some configuration properties which allow to tune or disable Probe features, e.g. to restrict the set of components which will be monitored. See also Development Mode Configuration.

What if I don’t have a webapp?

Nothing is lost! JMX and weld-probe-client-adapter come to rescue. This "adapter" allows to reuse the default HTML UI even if there is no REST API available (non-web environments). The adapter either connects to a JMX server (Probe JMX support must be enabled) or loads data from an exported file (see also Does it work offline?), then starts an embedded Undertow webserver instance and exposes the default HTML client but using the data from the first step.

Does it work offline?

Sometimes it’s not possible to inspect a running system (e.g. due to security reasons). Probe allows to export the collected data and inspect it offline. There are two ways to export the data:

  1. Using REST API: HTTP GET {webapp-context-path}/weld-probe/export

  2. Configure Probe to export data after deployment (see also org.jboss.weld.probe.exportDataAfterDeployment property in Development Mode Configuration)

And now use the weld-probe-client-adapter again:

java -jar weld-probe-client-adapter-1.0.0.Final-shaded.jar /home/weld/weld-probe-export.zip

Weld Tip 1 - Logging

2016-10-1   tips   Martin Kouba

This is the first article from a series of short articles covering some useful Weld features. In this article we talk about logging. The topics for the next articles include: DEVELOPMENT MODE, PERFORMANCE, NON-EE ENVIRONMENTS and TESTING.

Motivation

Logging is usually no fancy stuff. But very often it’s the best thing to start with if problems arise. Moreover, it’s the easiest form of debugging.

In this article you will find:

Under the hood

Weld is using JBoss Logging. This is an abstraction layer wchich does not "write" any log messages at all. Instead, it effectively constructs a log message and then delegates to a back-end logging framework. The supported frameworks include jboss-logmanager, Log4j, SLF4J and JDK logging.

So which logging framework is actually used to write the Weld messages? Well, it depends on the environment. In a Java EE container (e.g. WildFly) the logging configuration is under the direction of the container. You should follow the container-specific guides to change the configuration (see for example WildFly - Logging Configuration and How do I enable debug logging for Weld in a specific container?).

A web application deployed to a servlet container usually bundles a logging framework and possibly some configuration file. In this case, the configuration is in hands of the application developer. If no logging framework is bundled follow the container-specific guides to change the configuration (e.g. Logging in Tomcat).

Tip
A system property org.jboss.logging.provider can be used to specify the logging framework directly. If not set, the JBoss Logging will attempt to find the "best match" on the classpath. See also LoggerProviders.

In Java SE the situation is very similar to servlet containers except the class loading is usually even less complicated (see also How do I enable debug logging for Weld SE?).

Set the log level and use categories to filter messages

The default log level is usually INFO. Weld does not log that much information with this level. You will have to set the log level to DEBUG (or even TRACE) to see what’s going on in your application. If you set the level globally (for all frameworks and libraries), the log files will be bloated and it will be very hard to get some relevant info from there. If you set the level for Weld only (i.e. for org.jboss.weld), it should be better. Moreover, it’s possible to use categories to filter messages from a particular "domain". Weld log messages are grouped into several categories:

  • org.jboss.weld.Bootstrap

  • org.jboss.weld.Validator

  • org.jboss.weld.Bean

  • org.jboss.weld.Context

  • org.jboss.weld.El

  • and others (see also org.jboss.weld.logging.Category)

So for example, if you’re only interested in log messages related to EL resolution set the log level for the org.jboss.weld.El category to TRACE (or level with corresponding priority). Another useful example is the check of Weld configuration. Simply set the log level to DEBUG and filter the org.jboss.weld.Configuration category:

DEBUG [Configuration] WELD-001907: Reading properties file: test.war/WEB-INF/classes/weld.properties
    DEBUG [Configuration] WELD-001903: Configuration key RESOLUTION_CACHE_SIZE already set to 1 000 in a source with higher priority, value 500 from system properties is ignored
    DEBUG [Configuration] WELD-001904: Unsupported configuration key found and ignored: com.foo.bar
    DEBUG [Configuration] WELD-001902: Configuration initialized: {CONCURRENT_DEPLOYMENT=false, RESOLUTION_CACHE_SIZE=1000, RELAXED_CONSTRUCTION=true}

Monitoring bootstrap

CDI is designed to fail fast. An extensive validation is performed during application initialization in order to avoid malicious errors at runtime. Container usually also logs a lot of interesting info during bootstrap. Let’s try to set the log level to DEBUG for the org.jboss.weld.Bootstrap category and see what we get.

Registered beans

As simple as it looks - Weld logs all the beans found in the application, e.g.:

DEBUG [Bootstrap] WELD-000106: Bean: Managed Bean [class org.jboss.cdi.tck.tests.lookup.dependency.resolution.broken.unsatisfied.Vanilla] with qualifiers [@Any @Default]
    DEBUG [Bootstrap] WELD-000106: Bean: Producer Method [String[]] with qualifiers [@BatchProperty @Any] declared as [[UnbackedAnnotatedMethod] @Produces @BatchProperty public org.jberet.creation.BatchBeanProducer.getStringArray(InjectionPoint)]

Actions performed by extensions

There is no doubt that portable extensions are really powerful. They can change almost anything. That’s great for framework/libraries developers. On the other hand, this may cause problems when looking for a bug. There is an application class provided by a developer but what does the CDI container actually see? Well, it depends…​ because portable extensions are allowed to redefine this. And that’s why Weld logs all the "modification" operations performed by extensions, such as ProcessAnnotatedType.veto():

DEBUG [Bootstrap] WELD-000148: ProcessAnnotatedType.veto() called by com.foo.MyExtension@50fed5b1 for [BackedAnnotatedType] public class com.foo.Foo
Tip
If your application deploys successfully, you can use Development Tools to inspect the runtime info (will be covered in one of the follow-up articles).

Weld 2.4.0.Final

2016-9-13   release   Martin Kouba

I am very pleased to announce the first stable version of Weld 2.4 (CDI 1.2). See also the release details. From now on, 2.4 is the current stable version of Weld and 2.3 is not actively developed anymore. Thanks to everyone involved in this release!

Most of the new features were already introduced in First release candidate of Weld 2.4. To sum it up:

  • Removed dependency on com.google.guava:guava

  • Enhanced version of javax.enterprise.inject.Instance

  • Veto AnnotatedType not annotated with a bean defining annotation

  • @ActivateRequestScope interceptor binding moved to Weld API and renamed to @ActivateRequestContext

  • Improved rolling upgrades support

  • Events - reflect the output of CDI-494

  • Probe - allow to filter unused beans

  • Cleanup, cleanup, cleanup…​

  • Initial Java 9 support

Moreover, 2.4.0.Final allows to export the Probe development tool data (to be discussed in one of the following blog posts) and fixes a minor problem in non-EE environments (see also WELD-2227).

In the coming weeks, the Weld team is also going to publish "Weld tips" - a series of concise articles. The intention is to familiarize developers with less known Weld features. There will be no hot news, just useful existing features (repetition is the mother of wisdom ;-).

WildFly Patch

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


First release candidate of Weld 2.4

2016-8-19   release   Martin Kouba

I am pleased to announce the first release candidate of Weld 2.4 (CDI 1.2). See also the release details. Thanks to everyone involved in this release!

Removed dependency on com.google.guava:guava

Weld does not depend on com.google.guava:guava anymore (actually, Weld 3 does not depend on guava since 3.0.0.Alpha2). This significantly reduces the footprint of both Weld SE and Weld Servlet. The dependency is also not bundled with shaded artifacts for Weld SE and Weld Servlet.

Enhanced version of javax.enterprise.inject.Instance

Weld now provides org.jboss.weld.inject.WeldInstance - an enhanced version of javax.enterprise.inject.Instance. There are three additional methods - getHandler(), handlers() and isResolvable(). A handler allows to inspect the metadata of the relevant bean and to destroy the underlying contextual instance. isResolvable() is just a convenient method - a replacement for !isUnsatisfied() && !isAmbiguous(). For more details see also the reference guide.

WeldInstance is automatically available in Weld SE and Weld Servlet where the Weld API is always on the class path. It is also available in Weld-powered EE containers. In this case, users would have to compile their application against the Weld API and exclude the Weld API artifact from the deployment (e.g. use provided scope in Maven).

This functionality is based on a new proposal for CDI-589.

Veto AnnotatedType not annotated with bean defining annotation

Sometimes it might be useful to process all types during bootstrap, i.e. fire/observe ProcessAnnotatedType event for each Java class discovered, but veto types which are not annotated with a bean defining annotation. The main reason is that not all classes that meet all of the necessary conditions are intended to become beans. And so vetoing such types helps to conserve memory used by the container. Note that if you use bean-discovey-mode=annotated (implicit bean archive) then no ProcessAnnotatedType will be fired for any such type because it’s not discovered at all. And there might be portable extensions which use ProcessAnnotatedType to extract some important information from classes which are not beans.

Therefore, Weld allows to use bean-discovey-mode=all (explicit bean archive) and veto types without a bean defining annotation whose AnnotatedType#getJavaClass().getName() matches a regular expression. In other words, a type is vetoed if its name matches a regular expression and at the same time is not annotated with a bean defining annotation. This functionality is implemented as a built-in portable extension processing all types from all bean archives (it was already doable using an extension but we believe it’s more convenient to have this functionality out of the box).

This is a workaround for problems of bean-discovey-mode=annotated mentioned in CDI-420.

@ActivateRequestScope moved to Weld API

This interceptor binding can be used to activate the request scope within a business method invocation. It was previously part of the Weld SE but we believe it might be useful in any environment. See also WELD-2150.

Improved rolling upgrades support

Lenny Primak (a Weld community member - thanks for the report again!) struggled with rolling upgrades on certain application servers (Payara, GlassFish). Therefore, a new configuration property was introduced. This property allows to specify a delimiter which is used to abbreviate a bean archive identifier (which is usually derived from the archive name) before used as a part of an identifier of an internal component (such as bean). See also the reference guide and WELD-2064.

Events - reflect the output of CDI-494

This change reflects the clarification around Event operations - "A wildcard type is not considered an unresolvable type variable". See also WELD-2137 and CDI-494. Simply said, the snippet below and similar ones should now work:

@Inject Event<List<?>> event;
    
    public void fireLists() {
      List<String> stringList = new ArrayList<>();
      event.fire(stringList);
      List<Integer> intList = new ArrayList<>();
      event.fire(intList);
    }
    
    void observeAllLists(@Observes List<?> anyList) {
      // Will be notified
    }

Probe - allow to filter unused beans

The Probe development tool now identifies beans which are most likely unused (a bean is considered unused if it has no direct dependents, does not declare any observer or producer methods, is not annotated with @Named and is not a built-in bean, extension, interceptor or decorator). This might be useful to identify types suitable for vetoing as mentioned in [_veto_code_annotatedtype_code_not_annotated_with_bean_defining_annotation].

Cleanup

Weld has underwent an internal cleanup. A lot of deprecated and unused classes were removed.

Initial Java 9 support

It’s now possible to build Weld with Java 9. Note that this does not mean that Weld is modularized in a Jigsaw way. It’s just the first step on a long road ;-).

Bugs

Last but not least - a few bugs were killed. Weld SE - provided ClassLoader is also used to load extensions (WELD-2209). AnnotatedTypeValidator does consider extended interfaces (WELD-2221). Invocation of a JDK8 default method should be intercepted (this only works if using jboss-classfilewriter 1.2.0.Beta1+, WELD-2093).

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.


Arquillian container Weld 2.0.0.Beta1 released!

2016-7-21   arquillian , testing   Tomas Remes

We are pleased to announce a release of embedded Arquillian container adapter for Weld. This container has deserved some love for really long time. We tried to refactor it and introduced new master branch which now corresponds to the 2.0.0.x version stream. The original master was branched in 1.0. There is no more any arquillian-weld-ee-embedded-1.1 or arquillian-weld-se-embedded. It’s squashed to one arquillian-weld-embedded and you can configure environments either programmatically or using configuration properties. See link:https://github.com/arquillian/arquillian-container-weld This new version is going to be used in Weld as soon as possible.

Maven Coordinates:
    <dependency>
            <groupId>org.jboss.arquillian.container</groupId>
            <artifactId>arquillian-weld-embedded</artifactId>
            <version>2.0.0.Beta1</version>
        </dependency>

We would really appreciate if you can try it and let us know your experience!