CDI usage in custom components and other UI classes

I was able to get @Inject working in the Application class using information from the J2EE6/CDI wiki page. However, @Inject isn’t working in a CustomComponent-based class that I’m playing with. The @Injected members are being set to null.

How do I get CDI injection working in the other UI classes other than the Application-derived one?

Thanks,
-Aaron

The problem is that application class is managed by CDI container but your UI classes is not. So there is no way get it working. But if you choose to use SpringFramework instead there is possibility of using Configurable annotation in your UI classes. Since Spring is not CDI container this might not be option but at least Spring 3.0 now supports Inject annotations.

As alternative, you can use the
ThrealLocal
pattern to be able to get your app instance anywhere in UI classes. You can either implement this yourself, it is not very hard task, or just use a helper library which already implements this.

For instance, you may take a look at my
TPT
addon which also implements this technique and also propagates it to the spawned server-side threads as well and adds a .getApplication() static method you can call from anywhere.

One more way to go:
I’m using views module form http://vaadin.com/directory#addon/76

Views module instantiates views by class name.
It is easy to replace default factory with your own, which will perform injections for created view instances.

If i rememver correctly, TPT also allows to specify default views factory.

If I got Aaron correctly, he want to inject application instance into the UI classes, not one UI classes to another, so Im afraid, AppFoundation and TPT with its TPTMultiView will not help.

I have a bunch of business logic implemented as EJBs and CDI (i.e. @Named) beans. I want to use Vaadin as a view layer for these beans by accessing them via CDI. So, there isn’t any way to use any of my beans in a Vaadin app?

Can you inject all required EJB’s and Beans to your application class. Then, by getting the reference to your application instance via, say, ThreadLocal, you’ll have access to all your beans, something like this:

MyApplication.getCurrentApplication().getReservationBean()

Understood. Thanks! However, it is a little clunky.

Is there any way that this could be fixed/solved in the future? Is it an architectural limitation of CDI or Vaadin or both?

I’m playing with Seam 3, JSF/IceFaces, Vaadin, JAX-RS/SmartGWT, etc. and it would be nice to easily and naturally reuse my beans. I was hoping to fully utilize J2EE6 as a common business logic layer. It seems like Vaadin isn’t really a good fit for J2EE v6.

-Aaron

I think this is a CDI limitation. Vaadin’s UI components are just POJOs. They’re not bound to any context.

I think you can try creating main UI objects ( Windows, Dialogs, Generic panels) inside the application servlet, just where you create an application instance. Maybe this way those objects will go under CDI control and you can use injections of JEE beans and App instance there. Did not try this, however, just a last minute thought.

It’s not a CDI limitation. All you got to do is to use @Inject to instantiate your component instead of the “new” keyword.


@Inject MyComponent component;

public void init() {
    ....
    windows.addComponent(component);
}

Never use “new” if you want something to be managed.

Cloves,

I meant the usecase when you have, say, your custom Window class


public class MyWindow extends Window
{
   @Inject private Application app;
   @Inject private myWidget;
   ...
}

The scenario above does not work with CDI as MyWindow is not a managed bean.

I’m very late to this thread, but I’ve tried what you suggest already and it worked fine for me. I injected an EJB reference into the servlet and passed it to the application constructor:


http://blogs.sun.com/bobby/entry/authentication_without_the_form

I haven’t tried the CDI method, but possibly you just need the ManagedBean annotation on the Vaadin application object. It’s in Java EE 6.

Cheers,
Bobby