tags:

views:

1044

answers:

6

Hello there, I am experimenting with EJB3 on JBoss, developing a stateless bean. Basically once the module has been deployed I need to perform some actions related to load application settings. To do this I've annotated a method as @PostConstruct, which as far as I know from the API instructs the container to invoke it once the bean has been deployed and before get in service. (correct?) Now, I am confused, because from the log on that method looks like is not simply called after has been deployed but before each exposed method is called. I only need to call that method once, not every time it receives a call. What would be the best approach?

Thanks in advance

Alessandro Ilardo

+1  A: 

A stateless bean should be just that - stateless. Meaning that in use, you should neither be able to tell or to care if the bean was pulled from a pool or constructed on demand for your request. I'm hard-put to envision how a PostConstruct could apply to a stateless environment, since I always use that function to finish building a bean's state.

Apparently, JBoss is either forgoing the pooling of stateless beans and constructing them fresh each time, or, if it is using pooling, treating them like they were reconstructed each time (since they shouldn't be carrying state information). I'm actually a little surprised that it invokes the PostConstruct at all.

Tim H
Stateless just means "no conversation state", it doesn't mean no state at all. They almost certainly have collaborator objects inside them, and @PostConstruct can be used to initialise those.
skaffman
A: 

It is up to the app server to manage the lifecycle of EJBs. It may decide to construct, initialise and tear down beans whenever it sees fit. It may be that each call to your stateless bean is on a fresh instance of the your bean class, although that does seem like an off thing to do.

Is the app server calling the @PostConstruct method multiple times on the same object instance, or on a different instance each time? Try sticking log statements inside the constructor and the @PostConstruct method.

skaffman
A: 

How many SLSB do you have in your pool? Depending on the container the @PostConstruct may not be called until the first client accesses it (not sure about JBoss) so this may be why it looks like it is on every access. It would be interesting to see if it stopped calling your post-construct method after calling your method the number of times equalling your pool size.

If you are performing some expensive actions in your post-construct method then maybe do these in a SFSB at startup and "inject" that SFSB into your SLSB in the post-construct.

Damo
A: 

First of all PostConstruct is called before first method will be invoked on the bean. If no method will be invoked no post construct ever be called.

Secondly you can execute inverse actions in PreDestory method to remove side effects.

Anyway which kind of action you have to perform?

Mykola Golubyev
The action is just one and invokes a class which unmarshall an XML file. Someone suggested me to use @Resource instead, not clear if he meant to move this code into an SFSB
Alessandro Ilardo
A: 

I have applied latest Ejb3 plugin over JBoss5.1 version.Still JBOSS is not applying a pooling for Stateless Session Beans.The MaximumSize in pool still shows as 0.

hari
A: 

PostConstruct gets called before the client runs a biz method. This means that if the bean isn't pooled the container will instantiate the bean, do injection, call the @PostConstruct method, then allow the biz method to run.

In the case of a pooled be then the @PostConstruct method will be run every time the bean is pulled from the pool. With Stateless beans this will be between every method call. With Stateful beans this will be after client lookup or injection.

If you need to run something on application deployment your options will depend on the version of Java EE you have.

For Java EE 6 you can use @Startup on a @Singleton EJB which contains a @PostConstruct method.

For Java EE 5 and previous you'll have to use a ServletContextListener in a web archive. You can have the ServletContextListener call an EJB if you want.

However what might be a more important question is where do you want to load these application settings to? If you are dealing with a non-clustered single JVM configuration then you probably going to want to load them into a Singleton of some type. In Java EE 5- you'll have to implement the singleton design pattern yourself or in EE 6 use the @Singleton EJB type.

Chase