Skip to main content

@PreDestroy method in web service not called when web app undeployed?

10 replies [Last post]
duncant
Offline
Joined: 2007-04-06

I have a web service that needs to do some cleanup (shut down a background thread). So I implemented a method annotated with @PreDestroy. Unfortunately, the method is never called. I would have expected it to be called when the web service application is undeployed or disabled, but it is not.

This is an extremely simple JAX-WS web service written in Netbeans 6.1 and deployed to Glassfish v3.

I looked at the specs, and it's a bit vague about exactly when PreDestroy methods are to be called. The language says "Should" rather than "Must".

Question: Is there a reliable way I can get my method called whenever the app is undeployed or redeployed? Note that my @PostConstruct method *does* get called!

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Stephen Connolly

On Tue, Jul 8, 2008 at 12:04 AM, wrote:
> Are you suggesting, Stephen, that if I have a SessionBean web service deployed, that I still need minimal WAR in order to get the WebService lifecycle methods called on SessionBeans web services?

In effect, yes. If you read the specification, as far as I recall the
@PostDestroy method is called only if:

* the session bean is about to be finalized; _and_
* your application is still deployed

So if your application is undeployed and then the garbage collector
runs... @PostDestroy does not make any sense as your application has
been undeployed.

Think of @PostDestroy as being for when your bean gets created as part
of a pool, and the pool grows temporarily bigger than its resting size
to accommodate a surge in requests. The container says, ohh I've got
too many of these around, let's get rid of some of them... In those
cases will the lifecycle method be called.

You are trying to see the lifecycle method get called when it makes no
sense (to the container) as anything that it could call has been
unhooked from the container (because your context is undeployed,
either by being undeployed or being stopped)

I know it's ugly, but if you want to be standards compliant and not
tie yourself to glassfish, the WAR with ServletContextListener is the
only way to do it :-(

-Stephen

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

Stephen Connolly

On Fri, Jul 4, 2008 at 5:23 PM, wrote:
> I have a web service that needs to do some cleanup (shut down a background thread). So I implemented a method annotated with @PreDestroy. Unfortunately, the method is never called. I would have expected it to be called when the web service application is undeployed or disabled, but it is not.

The other thing I notice is that you are starting a background
thread.... AFAIK you should not really be starting threads in a
container.... (yes, I know everyone, myself included, does it)

If I remember correctly, background threads are supposed to be started
within a JCA resource adapter as it is the only thing that is given a
WorkManager by the container.

Man I hope they fix this for JavaEE 6.... I don't see why WorkManagers
are restricted to JCA adapters... and the fact that it is a separate
instance and not an ExecutorService... sure that's just wrong!

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

duncant
Offline
Joined: 2007-04-06

OK, thanks for the explanation, that helps a lot.

I understand your explanation about @PreDestroy - it's related to garbage collection - clearly not what I want.

I am deploying my application in a WAR file (by either copying it to the autodeploy directory, or using the Netbeans IDS "undeploy and deploy" action) so I should be able to implement a ServletContextListener as you suggest.

Regarding starting a thread in a container not being kosher, well, I've written several web apps that need some kind of background processing, so I can't see any way to avoid this. If there's a standard way that this is supposed to be done, that would be fine, but it's not so easy to figure out what that would be. I'm coming at this whole web service programming thing from the background of someone who's used to writing C code to listen on sockets and fork off handlers. The scale of all this Java EE machinery is quite intimidating for us mere mortal programmers who learned our trade back in the day when the entire app progam, operating system and all, would fit in a few Kbytes of memory.

Thanks,

Duncan

Stephen Connolly

On Mon, Jul 14, 2008 at 4:40 PM, wrote:
> OK, thanks for the explanation, that helps a lot.
>
> I understand your explanation about @PreDestroy - it's related to garbage collection - clearly not what I want.
>
> I am deploying my application in a WAR file (by either copying it to the autodeploy directory, or using the Netbeans IDS "undeploy and deploy" action) so I should be able to implement a ServletContextListener as you suggest.
>
> Regarding starting a thread in a container not being kosher, well, I've written several web apps that need some kind of background processing, so I can't see any way to avoid this. If there's a standard way that this is supposed to be done, that would be fine, but it's not so easy to figure out what that would be. I'm coming at this whole web service programming thing from the background of someone who's used to writing C code to listen on sockets and fork off handlers. The scale of all this Java EE machinery is quite intimidating for us mere mortal programmers who learned our trade back in the day when the entire app progam, operating system and all, would fit in a few Kbytes of memory.

I completely agree that 99% of people do exactly what you have
done.... but from my reading of the JavaEE5 specs... it's not
something that the specs are expecting you to be always permitted to
do...

The only part of the spec that I can see that actually lets you start
your own threads is the JCA.

I agree it's a hole in the spec... I was more pointing it out from the
"Oh! spec leads fix this" kind of way.

The other thing is as starting a thread in your ejb/servlet is not
encouraged, you hit a lot of problems... which people then invent
crazy workarounds to solve.

The basic problems are around security and all that JAAS. There are
also issues with transactions.

The JCA spec does split out some of this stuff, but it probably needs
to be made more general, and why a resource adapter is the only thing
that can get the workmanager instance is another question....

Hmmm I've just thought of something... a trivial resource adapter
could expose the work manager that it has been given as a "propriatory
api" and therefore allow ejb, etc to access the work manager and even
have it injected with the @Resource annotation! .... I smell an
uber-hack! ;-)
>
> Thanks,
>
> Duncan
> [Message sent by forum member 'duncant' (duncant)]
>
> http://forums.java.net/jive/thread.jspa?messageID=286449
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

duncant
Offline
Joined: 2007-04-06

Sorry, correction, I'm using glassfish-v2ur2
- Duncan

Stephen Connolly

you'll need to have a war. in the java ee 5 spec the only standard way
is to implement a servletContextListener in the web container

On 7/4/08, glassfish@javadesktop.org wrote:
> Sorry, correction, I'm using glassfish-v2ur2
> - Duncan
> [Message sent by forum member 'duncant' (duncant)]
>
> http://forums.java.net/jive/thread.jspa?messageID=284429
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

duncant
Offline
Joined: 2007-04-06

When you say I'll need to have a war, I assume you mean war as in big fight, as opposed to war as in web archive... Do you mean there's an ongoing debate/fight about PreDestroy and the general topic of lifecycle management?

PostConstruct seems to work reliably, by the way.

Stephen Connolly

Nope I mean war as in web archive.... but if you want to start a war
about needing to have a war in java ee 5 just to get the context start
and stop events, don't let me stop you ;-)

On Mon, Jul 7, 2008 at 4:48 PM, wrote:
> When you say I'll need to have a war, I assume you mean war as in big fight, as opposed to war as in web archive... Do you mean there's an ongoing debate/fight about PreDestroy and the general topic of lifecycle management?
>
> PostConstruct seems to work reliably, by the way.
> [Message sent by forum member 'duncant' (duncant)]
>
> http://forums.java.net/jive/thread.jspa?messageID=284735
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

whartung
Offline
Joined: 2003-06-13

So, are you saying that in order to get the WebService lifecycle methods to work (mind, this isn't a servlet listener, this is a simple WebService), that you need to have a WAR deployed?

How are you deploying the web service. As a SessionBean, or as part of a web app?

Are you suggesting, Stephen, that if I have a SessionBean web service deployed, that I still need minimal WAR in order to get the WebService lifecycle methods called on SessionBeans web services?

Stephen Connolly

Nope I saying that if you want to know about your application being
deployed and undeployed or the container within which your application
is deployed being stopped and started you need to have a WAR.

A ServletContextListener is notified whenever the container deploys
(which also includes starts) and undeploys (which also includes stops)
the WAR within which the ServletContextListener is contained.

You then have that listener call your Stateless session bean or web
services that is in the EJB jar or whatever you have to say:

"Oy! we is starting" or "Oy! we is stopping"

Bung the whole lot in an EAR so that the start and stop do not run
into sequencing issues.

There are other ways of getting the start and stop events, but for
JavaEE version 5, this is the only _standards compliant_ way that I
know of.

On Tue, Jul 8, 2008 at 12:04 AM, wrote:
> So, are you saying that in order to get the WebService lifecycle methods to work (mind, this isn't a servlet listener, this is a simple WebService), that you need to have a WAR deployed?
>
> How are you deploying the web service. As a SessionBean, or as part of a web app?
>
> Are you suggesting, Stephen, that if I have a SessionBean web service deployed, that I still need minimal WAR in order to get the WebService lifecycle methods called on SessionBeans web services?
> [Message sent by forum member 'whartung' (whartung)]
>
> http://forums.java.net/jive/thread.jspa?messageID=284884
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net