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]

# 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 >

# 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 >

# 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.