Deal of the Day

Home » Main » Manning Forums » 2006 » EJB3 in Action

Thread: initializing stateful bean instances from servlet

Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 8 - Pages: 1 - Last Post: Jul 22, 2008 4:39 AM by: Jay2008
Ylva D

Posts: 8
From: Västerås, Sweden
Registered: 2/14/08
initializing stateful bean instances from servlet
Posted: Feb 15, 2008 12:49 PM
  Click to reply to this thread Reply

Hi,

I'm trying to learn how to use a stateful bean, kind of like you did in the book. I'm using it for creating an account, it has a local interface and I want to access it from a servlet. How am I supposed to do that?

I have tried a lot of things - first injecting the bean with @EJB but then I read that this will only create One instance per servlet instance, so that won't work for several users.

Then I tried having an @EJB at the class level and injecting an instance of a SessionContext but that didn't work either.

My last attempt was to try to do the simplest type of lookup (I mean "simple" as in that it can be done from a simple java class) but then I got a
javax.naming.NameNotFoundException. I think I might have the wrong JNDI name but I'm not so good at how I'm supposed to do that.

My latest try was "java:comp/env/ejb/UserAccountCreatorBean" but that didn't work.
Isn't the beginning, "java:comp/env" correct anyway?

I'm using NetBeans IDE 5.5.1 and Sun's Glassfish server, if that's helpful to you.

Could someone please help me 'cause I really want to learn how to do this!

/Ylva

reza_rahman


Posts: 430
From: Philadelphia ,PA
Registered: 11/30/05
Re: initializing stateful bean instances from servlet
Posted: Feb 15, 2008 7:08 PM   in response to: Ylva D in response to: Ylva D
  Click to reply to this thread Reply

Ylva:

You are right in that you shouldn't inject directly into a Servlet or "static" class. Both have "application" and not session scope and are therefore not good candidates for injecting Stateful Session Beans (as an aside injecting Stateless Beans into such contexts is fine). Since you are using Servlets, I'm guessing using Seam/JSF is really not an option right now. Given this, you are also correct in that look-ups are the way to go where Stateful Session Beans are concerned.

"java:comp/env" is only correct if you explicitly create an ejb-local-ref to the bean in the web.xml file. Here is more info on "java:comp/env" for a Servlet context: http://www.onjava.com/pub/a/onjava/excerpt/java_servlets_ch12/index.html?page=4.

Personally, I've never found the indirection in EJB local environments too useful and opt to use global JNDI names instead. Your best bet is to use mappedName like so:

@Stateful(name="Example", mappedName="ejb/SimpleBeanJNDI")
public class SimpleBeanImpl implements SimpleBean

The corresponding lookup code should be something like:

InitialContext ctx = new InitialContext();
SimpleBean bean = (SimpleBean) ctx.lookup("ejb/SimpleBeanJNDI");

This works quite nicely in JBoss AS, but in GlassFish you'll need to use a remote interface instead of a local interface. If you are very averse to EJB remote interfaces, you can do the following: https://glassfish.dev.java.net/javaee5/ejb/EJB_FAQ.html#POJOLocalEJB.

Hope this helps.

Reza

reza_rahman


Posts: 430
From: Philadelphia ,PA
Registered: 11/30/05
Re: initializing stateful bean instances from servlet
Posted: Feb 15, 2008 7:16 PM   in response to: Ylva D in response to: Ylva D
  Click to reply to this thread Reply

As a somewhat irrelevant aside, I'm hoping the ejb-local-ref indirection sees an early grave when EJB packaging rules are further simplified in EJB 3.1. Oh well, at least @EJB gets rid of this muck in 90% of use application use cases...

Cheers,
Reza

Ylva D

Posts: 8
From: Västerås, Sweden
Registered: 2/14/08
Re: initializing stateful bean instances from servlet
Posted: Feb 18, 2008 11:20 AM   in response to: reza_rahman in response to: reza_rahman
  Click to reply to this thread Reply

Thank you so much for your help, Reza!

I realized it was very hard (or impossible) to make it work with a local interface and the Glassfish server, so I changed it to a Remote interface. (It doesn't matter much to me, anyway. I'm just doing a test application to learn how to use ejbs and Java EE 5 in general, which I will use for my thesis work.)

And after having corrected a few other errors, finally it Works!

Now I just have a small question, which you don't have to answer if you don't have the time but I really want to learn how this works so it would be nice if I could get an answer..

I'm just wondering why it doesn't work to typecast the bean instance I get through the lookup call to my bean class (UserAccountCreatorBean), when that instance variable is declared to be of the Interface type (UserAccountCreatorRemote).

In other object oriented languages like C++ (if I remember correctly) that's the way you Have to do it when a class is implementing an interface. - You can't create an object dynamically that has the actual interface type, but it's "good programming style" that you let the interface type be the static type of the instance variable and let the "class type" be the dynamic type, right?

I tried to apply that to my Java EE application, but it didn't work. Am I supposed to forget about the "good O.O. programming standards" in this case when it comes to java EE (or Java in general)?

And what type is recommended when I'm doing a bean lookup - the type of the bean instance or the interface?
When my bean class only is implementing one interface and the interface only is connected to one bean class (there's no other way, right?) I don't think it matters much. I'd just like to know what a skilled Java EE programmer would recommend.

Thanks again,

/Ylva

reza_rahman


Posts: 430
From: Philadelphia ,PA
Registered: 11/30/05
Re: initializing stateful bean instances from servlet
Posted: Feb 18, 2008 12:06 PM   in response to: Ylva D in response to: Ylva D
  Click to reply to this thread Reply

Ylva:

Actually, good OO practice would dictate avoiding any reliance on the underlying implementation and using interfaces whenever possible. This has been the programming model for CORBA, COM, DCOM, COM+ and EJB 2.x. It is almost the entire point of DI containers like Spring and PicoContainer. Naturally, EJB 3 is not an exception. Taking a look at the plain code lookup code, aren't you making program less loosely coupled by casting to a specific implementation type?

In terms of casts on JNDI lookup, the spec does not mandate one way or the other. In other words, container implementations are not guaranteed to allow you to cast to the actual bean implementation (the GlassFish lead is of the opinion that it should not be allowed because it breaks loose coupling guidelines).

Hope this helps.

Reza

P.S.: Just a few minor things to keep in mind:
1. A bean class may implement multiple interfaces. Multiple beans can implement the same interface. The relationship is not one-to-one :-)
2. Most robust C++/C#.NET systems I've seen avoid direct instantiation of dependencies and use Factories instead like so:

SomeService service = SomeServiceFactory.getInstance(); // Gets you an instance of SomeServiceImpl.

Ylva D

Posts: 8
From: Västerås, Sweden
Registered: 2/14/08
Re: initializing stateful bean instances from servlet
Posted: Feb 19, 2008 2:26 AM   in response to: reza_rahman in response to: reza_rahman
  Click to reply to this thread Reply

Thanks again, Reza!

Now I feel a little bit wiser. You're right in what you said. It's been a couple of years since I took a C++ or O.O.P. course and I'm not so up to date with the newest technologies. But I'm learning..

Have a nice day!

/Ylva

reza_rahman


Posts: 430
From: Philadelphia ,PA
Registered: 11/30/05
Re: initializing stateful bean instances from servlet
Posted: Feb 19, 2008 9:09 AM   in response to: Ylva D in response to: Ylva D
  Click to reply to this thread Reply

Good luck and best wishes!

Jay2008

Posts: 8
From: London
Registered: 7/22/08
Re: initializing stateful bean instances from servlet
Posted: Jul 22, 2008 4:36 AM   in response to: reza_rahman in response to: reza_rahman
  Click to reply to this thread Reply

Hi,
I have followed this thread with interest and have a few questions:

a) A servlet is usually instantiated once (depending on web.xml config.) and so is accessed by all requests/threads from the client-browser. It was never good practise to use instance variables because of this since they wouldn't be thread-safe and instead was better to keep all variables method-local ie declared inside the required method in the servlet.

But, the @EJB usage is on an instance variable... why is this now accepted practise? What am i missing?

b) I've tried using the @EJB in my servlet and the session EJB that accompanies it is not being initialised. I'm using the latest version 'web-app version="2.5"' in my web.xml but it still is not working. I am using JBoss 4.2.2. Any tips?

Many thanks for your time,
Jeremy

Jay2008

Posts: 8
From: London
Registered: 7/22/08
Re: initializing stateful bean instances from servlet
Posted: Jul 22, 2008 4:39 AM   in response to: Jay2008 in response to: Jay2008
  Click to reply to this thread Reply

Hi,

Sorry - but i started a new thread called "using @EJB in a servlet" and referenced this thread.

Apologies
J

Legend
Gold: 300 + pts
Silver: 100 - 299 pts
Bronze: 25 - 99 pts
Manning Author
Manning Staff