Ensure some @ApplicationScoped beans are eagerly initialized with JavaEE, camel-cdi case


In a CDI application @ApplicationScoped beans are pretty important but the fact is they are often initialized lazily.

It is often fine but not always. An example where it is wrong is using camel-cdi module and an @ApplicationScoped bean as a consumer. In this case camel needs the consumer to be active to be able to consume messages from it (note: and having a consumer which is not @ApplicationScoped doesn’t mean that much IMO). The camel-cdi extension tries to eagerly initialize them but in reality it only initializes the proxy of the bean and not the instance of the bean itself.

In JavaEE the solution is pretty obvious even if it doesn’t look very sexy: use a @Singleton EJB to force the @ApplicationScoped bean to be initialized. The idea is simply to call any method of the @ApplicationScoped bean in the @PostConstruct method of a @Startup EJB :). Easy isn’t it?

Let’s take this consumer:

@javax.enterprise.context.ApplicationScoped
public class MyConsumer {
    @org.apache.camel.EndpointInject(uri = "direct:out")
    private ProducerTemplate producer;

    @org.apache.camel.Consume(uri = "direct:start")
    public void consume(final String in) {
        producer.sendBody(">>> " + in + " <<<");
    }
}

Here how the init can looks like:

@javax.ejb.Singleton
@javax.ejb.Startup
public class EagerInitializer {
    @javax.inject.Inject
    private AppBean appBean;

    @javax.annotation.PostConstruct
    public void eagerInit() {
        appBean.toString();
    }
}

And that’s all!

But why not using the ejb as consumer directly? In some cases it will be pretty fine but in extensions EJBs are not complete CDI beans (some events are not fired). In the case of camel-cdi it simply doesn’t work.

Moreover i personally think it can make sense in application to have a bean ensuring the application is initialized. I’d go even further ensuring the configuration is valid with the same kind of tip (well i’m no more speaking about camel here ;)).

The @Startup annotation is not in CDI but in JavaEE but it is a pretty important one we sometimes forget.

For more info about camel POJO programming model have a look to:

Note: the real – and better – camel-cdi component is not yet released and only available on trunk in version 2.11-SNAPSHOT

Want more content ? Keep up-to-date on my new blog

Or stay in touch on twitter @rmannibucau

Advertisement

9 thoughts on “Ensure some @ApplicationScoped beans are eagerly initialized with JavaEE, camel-cdi case

  1. Tcharl

    Hi,

    I’m not able to consume a message with @Consume and camel-cdi (osgi env) and just producing via @Inject @Uri (not @Produce), any info/clue on this?

    Regards,

    Reply
    1. rmannibucau Post author

      Can depend the scope of the bean or the Bean you use, the way CDI is integrated in OSGi (nothing standard here). Ping camel dev on irc or mailing list, they will help you for sure if you provide enough details.

      Reply
  2. Kinfofmemphis

    Its kind of crazy that CDI doesn’t have an annotation to eagerly initialise @ApplicationScoped beans no? This has been available in Spring say for many years! Not everyone is using JavaEE. (e.g. GUI guys or guys writing simple java processes but would like to use CDI). To omit a “simple” thing like this from the CDI spec is kinda crazy IMHO.

    Reply
  3. Kinfofmemphis

    Also, I’m quite new to CDI. And it seems a bit of a mess :D. Or at least the documentation is. It doesn’t explicitly say what features are available in JavaSE vs JavaEE. All the dock is mainly for JavaEE with a line or 2 for JavaSE along the lines of “CDI works in JavaSE”. They don’t mention that you can’t use @RequestScoped or @SessionScoped in JavaSE, etc for example. Thats an obvious example, but other non-compatible “features” might not be as “obvious”.

    Reply
    1. rmannibucau Post author

      That’s because JavaSE will be targeted by CDI 2.0. But deltaspike document JavaSE usage. A lot of users are using requestscoped in batches (standalone) to get prototype scope (if you are a spring guy ;))

      Reply
      1. Kinfofmemphis

        Ha.. I used to be a spring guy but I’ve been trying to drink the CDI coolaid and have been finding deficiencies. 🙂 Regarding DeltaSpike its great (although again Doco needs _alot_ of work!) and I use the CdiTestRunner in my project.

        But what confused me a bit is that DeltaSpike talks about using @RequestScoped in JavaSE (for unit testing for example). Is this something that can actually be used in “real” code and not tests? However, Weld Doco, specifically says the Weld _doesn’t_ support @RequestScoped in JavaSE. So more confusion there…

      2. rmannibucau Post author

        well deltaspike has cdictrl to be able to handle it properly. @RequestScoped is just a ThreadLocal scope so fine in JavaSE too when well managed

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s