Vaadin + CDI + JMS MessageConsumer

Hello everybody,

I’m currently working on a Vaadin application in a JEE6 context with Glassfish v3 Full Profile.

I followed the instructions given on the wiki page (http://vaadin.com/wiki/-/wiki/Main/Creating%20JEE6%20Vaadin%20Applications) and my application is successfully loaded.

When the application is started, I get some Entities from a database thanks to Stateless Bean managing itself the EntityManager and fill a Vaadin Table with results.

Now, i’m trying to put in place a JMS message consumer to refresh my UI, instead of querying directly the database.

To do that, I injected the Destination and ConnectionFactory using JNDI Lookup and @Resources into my Vaadin Application and set a message listener.

But it seems that I never catch messages.

I’m not sure that my application’s design is well adapted to my needs, and I guess this is something related to the lifecycle of the Vaadin Application. What is the best way to launch my JMS message’s consumer ? I want it to be session scoped too.

In the vaadin’s init() method ?

In method annotated with @PostConstruct ?

Thank you for your help,

Best Regards,
J.M

Hi,

I think I can help, but I’m not sure from description what you’re trying to do. Please tell me if I have the concept correct:

Version 0:
Vaadin servlet creates your application (“MyApp”), and MyApp has an EJB object reference (“DataBean”). FWIW, I recommend not having MyApp be a session bean – you can just look up an instance of DataBean or inject it into the servlet class and pass it to MyApp. But that’s beside the point. Back to the point…MyApp calls a method in DataBean to get data to fill out a table. When a new request comes in from the client, MyApp queries DataBean again.

Is that right so far?

Version 1:
Now instead of MyApp querying DataBean, you instead want to use a message-driven bean to maintain the data (in memory) and MyApp can query that instead? (Simple answer in this case: make the MDB a singleton and just query it for info.)

Let me know if I’m understanding you correctly.

Cheers,
Bobby

Hi Bobby,

Sorry for the late reply !

It seems that you have the concept correct.

I don’t understand why I couldn’t inject a EJB directly in my Vaadin Application, as i want it to be session scoped. If I inject it in my servlet, i have no guarantee that I won’t share my EJB instances between VaadinApplication instances (one per user session, I guess).

By the way, I did’nt know that it was possible to make a MDB a singleton, is that a good practice ? As far as I know, MDB are stateless beans, and it would mean that I have to store all references of incoming messages, even my Vaadin Application isn’t launched, that’s not really efficient.

Thank you for your help,

B.R
Jérôme M.

PS: Sorry for my english…

Hi again,

No problem on the late reply. I’m usually waaaay behind on these forums.

That’s a good point, but it magically (almost magically) works. You can’t directly inject an EJB into an unmanaged object like a Vaadin Application, but you could use CDI for this. I like injecting the EJB into the servlet and passing it to the Vaadin application because it’s so simple.

When you do this, you don’t actually have a handle to the EJB, but to an EJB Object. I don’t think it matters whether this object is shared or not, as it’s just a proxy for an actual EJB. If you output something like myEjb.toString() you’ll see what I mean. I don’t recall exactly, but a different EJB Object could be injected into the servlet before each invocation, in which case each new Vaadin Application would have its own.

But that doesn’t matter either way because it’s just a proxy. When you make some call on the EJB Object, assuming it’s stateless, an instance of the real EJB is picked from the pool and returned to the pool after the invocation. So it’s not the case that you’re tying up some real EJB among your Vaadin instances. It’s also what makes serialization of the http session possible, whether because you’re in some high availability situation or the server is just storing your session because it hasn’t been used in a while.

I may be fuzzy on the details, but I ran this situation by the EJB spec lead in the early EE 6 cycle and he confirmed my use. For what it’s worth, I don’t see the need (yet) for using stateful session beans with Vaadin since the whole state of the web app is already stored in the http session. Put another way, the “web site checkout” example of stateful session beans doesn’t apply in the Vaadin case. I like the way Vaadin works better. :slight_smile:

Right after writing that, I wasn’t sure if you could have a singleton MDB or not. I’m not sure why not, but I haven’t had a good chance to try it since I’m spending most of my time working on some EE5 things. If it doesn’t work, then you can create the singleton bean to store the state and inject it into the MDB and your Vaadin app. The @Singleton annotation was created so that you could have some shared state across the application server (per JVM), and this sounds like a good match for what you’re doing.

Cheers,
Bobby

Hi Bobby,

Thank you for your detailed explanations, I learned a lot of things. That makes me think that I really need to learn how EJB work in details before going further.

Just for the story, i’m going to use a lazy-loading container (like JPAContainer ou Lazy Query Loading from Vaadin addons), instead of JMS, as I want to be able to get and filter data previously persisted.

Cheers,
Jérôme M.

hello, i have the same problem, i want to fill a “table” with a bean, i call my EJB and , which method could i use for it,
i try table.SetContainerDataSourc(my bean), but anything…

If all the fields in your EJB are Java primitives, I think you could just wrap the bean in a BeanItemContainer and pass it to the Table with setContainer. That would give you a table with a row per field (I
think
– it’s been a while since I’ve used that).

You may want to start a new thread, if you haven’t already, with more information about what you want to do. In Java EE 5 and 6, EJBs are just simple Java objects (POJOs) with an annotation on them. The EJB field you have in your Vaadin application is a proxy to that real POJO class, but you can treat it like any simple Java class.

Cheers,
Bobby