Calling from an EJB into a JSF Backing Bean

Hello all,

I'm looking for some help in making callsfrom an EJB into a Backing Bean (the converse is fairly straightforward). My basic question is: what is regarded as the best way to do this?

However, for anybody who's interested, I'll describe what I've been trying...

Here's my situation (I'm working with OC4J 10.1.3.2). I have a simple application-scoped backing bean:

publicclass BackingBeanimplements SimpleInterface, Serializable{

private String greeting ="Hello, World";

private SessionEJBRemote blBeanRemote =null;

public BackingBean(){

// get hold of EJB

// [ ... code to obtain EJB's remote interface snipped ... ]

// set the callback with the EJB

try{

blBeanRemote.setCallback(this);

}catch (Exception ex){

ex.printStackTrace();

}

}

// methods to manipulate the greeting string

public String getGreeting(){

return greeting;

}

publicvoid setGreeting(String greeting){

this.greeting = greeting;

}

}

SimpleInterface, which my Backing Bean implements is, well, a simple interface:

publicinterface SimpleInterface{

publicvoid setGreeting(String greeting);

}

And my EJB is also pretty straightforward:

@Stateful(name="SessionEJB")

publicclass SessionEJBBeanimplements SessionEJBRemote, SessionEJBLocal{

private SimpleInterface callback =null;

publicvoid setCallback(SimpleInterface callback){

this.callback = callback;

callback.setGreeting("Goodbye, World");

}

}

Now, by using SimpleInterface, my intention was to ensure a one-way dependency: i.e. the JSF-level code would depend on the EJB-level code, but not vice versa.

However, my experimentation has shown that when I make the call to blBeanRemote.setCallback, the parameter appears to be passed by value rather than by reference. This means firstly that, at runtime, by EJB needs to have access to my backing bean class and secondly, that the call to callback.setGreeting has no effect.

Can anybody suggest how to work around this? Is it possible to pass the backing bean by reference? Is there a better way to achieve this callback? I appreciate that these questions might be more general Java/AppServer queries rather than JSF-specific ones - but hopefully this is something that all you JSF experts have encountered before.

(Incidentally, I realise that what I'm doing in this example is pointless - what I'm building towards is using the ICEFaces framework to have the EJBs prod a backing bean which will in turn cause a user's browser to rerender.)

Many thanks - any help very much appreciated!

Alistair.

[4269 byte] By [AJYa] at [2007-11-27 9:39:20]
# 1

It has occurred to me that my pass-by-value (or "pass-by-copy", if you prefer) problem <i>may</i> be avoided if I were to use the EJB's local interface instead of its remote interface.

Unfortunately... I've yet to figure out how to get hold of the local interface...! I posted a query about it over on the Oracle forums: <http://forums.oracle.com/forums/thread.jspa?messageID=1934786> but if anybody here knows the answer, please share. I can't help but feel that it should be trivial which probably makes it a stupid question - but please humour me!

Alistair.

AJYa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

Okay, I've got this working now. Local interfaces were the key. Once I got that sorted, the rest fell into place as I'd been expecting.

The Oracle forums thread I referenced above contains details on obtaining the local interface - I was right, it was somewhat trivial! :)

Alistair.

AJYa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3

I would be wary of this implementation. You've tied yourself to using local interfaces for your EJBs. If down the line you need to scale up your server you may run into issues. Also, this kind of need, to have an EJB invoke a backing bean method, indicates to me you have not separated your concerns properly. EJBs should be concerned with business logic. Backing beans should be concerned with UI code.

RaymondDeCampoa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4

Hi Raymond,

I'll certainly keep the scaling issue in mind - it wasn't something I'd really considered - though for various reasons I don't believe that it will be an issue in my particular case.

I agree with your second point, in general - however, as I said in my original post, what I need to do is have some business logic event (e.g. receipt of a JMS message) cause a user's browser to rerender with the new information (one of the facilities provided by the ICEFaces framework).

It seems unavoidable, therefore, that there needs to be some "back flow" of information. Even if (as in this case) it's a simple prod. I believe that the use of an interface minimizes this blurring of concerns as it allows the UI (JSF) layer to hook into the business layer (EJBs) as an anonymous client.

I'm very interested to hear any contrary views, of course. Are there other, standard ways of achieving this server-driven behaviour?

Thanks,

Alistair.

AJYa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5
Well, the first thought that comes to my mind is when I need to pass information from the EJB layer is to use the return value from the method.
RaymondDeCampoa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6

... which is fine if I have something in the UI layer to stimulate an EJB in the first place. If, however, the user isn't doing anything, then that's not going to happen. Hence the need for a push, rather than a pull.

I suppose it might be possible for the UI layer to poll the the EJB layer periodically - but to meet the sort of responsiveness we need, this would probably have to occur around once a second and this sits far more uneasily with me than the callback.

Alistair.

AJYa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 7

I guess I am not really understanding your use case here.

Here is my best guess as to what you are trying to accomplish. Something causes the EJB fire (perhaps a JMS message?). This causes updates in data that you want to push to the client, but not necessarily the client that made the request of the EJB (if one even exists). Currently you use the local interface of the EJB to gain access to one of the backing beans (application scope? session scope? If session scope how do you handle multiple users? If application scope how do you narrow down to the correct clients to refresh?). This somehow causes the user's browser to refresh, even though there was no request from this user. How does ICEFaces cause the browser to rerender?

RaymondDeCampoa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 8

Hi Raymond - yes, you've pretty much got that spot on: an event occurs (say receipt of a JMS message - which is spontaneous, as far as the users are concerned). As a result of that event, the client's view (in their browser) needs to be re-rendered.

ICEFaces uses the AJAX technique to allow server-pushes, and rather than refreshing the whole page it uses "Direct-to-DOM" rendering to maninpulate the page components. If you've not come across it, and you're interested, then there are some pretty interesting demos here: http://www.icefaces.org/main/demos/ - the "chat" feature of the Auction Monitor demo (if you open it up in two browsers) is the nearest to the effect I'm looking for.

The Auction Monitor demo uses a number of session-scoped beans, each implementing the ICEFaces "Renderable" interface, and each of which registers itself with an application-scoped bean. The application-scoped bean can thus iterate through each of the session-scoped beans and cause the corresponding browser to refresh.

Unfortunately, in the Auction Monitor demo, the entry point is always from a browser - albeit the result is then mirrored across all connected browsers. I haven't found any examples of this processing being driven by an external event, hence my experimentation in this area!

AJYa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 9
What I was really getting at is that the ICEFaces component is likely already polling the server itself. If you could hook into that you might be able to get somewhere.
RaymondDeCampoa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 10
I forgot to mention it might be more appropriate to have a JMS listener within the web container itself that the EJB could publish messages to. That would eliminate the tight binding you have created.
RaymondDeCampoa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 11

Thanks for the suggestions, Raymond.

Re: hooking into the ICEFaces component - I'm pretty sure that the only mechanism for this is to call one of the appropriate re-render methods on the ICEFaces API... which is what I'm doing.

Re: JMS listener in the web container - I like the sound of this, but hadn't realised it was possible. I imagine it's probably beyond the scope of this thread, but perhaps you know of some resource that describes how to go about setting up such a thing? If this had access to the JSF managed beans, then I'd be a very happy man.

AJYa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 12

> Re: JMS listener in the web container - I like the

> sound of this, but hadn't realised it was possible.

> I imagine it's probably beyond the scope of this

> thread, but perhaps you know of some resource that

> describes how to go about setting up such a thing?

> If this had access to the JSF managed beans, then

> I'd be a very happy man.

You are allowed to launch threads in the web container, so any tutorial on setting up a JMS listener would work. I know that the Spring library has some easy ways to do this, but using Spring is more of an application-wide commitment to do it correctly. In any case, set a thread and you ought to be able to get at an application scope bean.

RaymondDeCampoa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 13
Okay, many thanks for this suggestion Raymond - I shall investigate it further and hopefully report back on how it goes.
AJYa at 2007-7-12 23:14:25 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...