Skip to main content

@PreDestroy

13 replies [Last post]
ronak2121
Offline
Joined: 2006-08-24

All,

I am writing a Web Service that launches background threads in a method annotated with the @PostConstruct annotation.

In a method annotated with the @PreDestroy annotation, I am trying to shut down those threads to cleanly exit.

However, I have noticed that the container seems to be invoking my methods in a manner inconsistent with my understanding.

This is what seems to be happening:

On Deploy and first access to service:

The container invokes the Endpoint Constructor.
The container invokes the method labeled with the @PostConstruct annotation.

On Undeploy:

The container invokes the EndpointConstructor
The container invokes the method labeled with the @PreDestroy annotation.

Why does the container do this? This results in many NullPointerExceptions and leaked resources and threads. Why can't the container just call the @PreDestroy method using the object it already created?

Is this a matter of scope? If it is, what setting do I use to make sure that the container reuses the Service endpoint object it already has?

Please reply ASAP.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
ronak2121
Offline
Joined: 2006-08-24

If it doesn't work reliably, then why is it there? The name PreDestroy says that it catches life cycle events.

http://java.sun.com/javaee/5/docs/api/javax/annotation/PreDestroy.html

The Javadoc at that link does not state that PreDestroy is an optional invocation by the container. In fact, it says the exact opposite.

martinstraus
Offline
Joined: 2003-08-22

You should not start threads from JEE components directly. If you need asynchronic and/or parallel processing, you should use JMS.

ronak2121
Offline
Joined: 2006-08-24

I had to run background threads in order to pull data from hardware while still servicing service requests.

My web services connect to hardware and not databases to get data. This requires me to poll the hardware periodically.

Custom hardware does not understand JMS of course. It understands raw byte-based messages.

Clive Brettingham-Moore

>Custom hardware does not understand JMS of course. It understands raw
byte-based messages.

This is *EXACTLY* what JCA is meant for, also if you are using EJB note
that any JCA can be used with a message driven bean, not just JMS.
And in defence of JMS, you can send messages with byte bodies that the
endpoint code (eg MDB) could then send to the hardware; although if you
have to do anything fancy you are probably better of writing a RA rather
than playing tricks with JMS.

RA code operates outside the container, interfacing through connectors
and/or message driven beans.
Speaking from personal experience it is not too hard to make a custom RA
and package into a RAR (which all compliant JEE servers should support)
- you will have a well defined interface with the container boundary,
and via JCA api will be given well defined lifecycle events - take a
look at javax.resource and subpackages.

As the (referenced above
http://forums.java.net/jive/thread.jspa?messageID=284448&#284448)
glassfish thread points out, just creating you own threads will not
always work (it is perfectly legitimate for a server to deny application
code thread create permission), and can cause all sorts of grief with
container functions such as JNDI, transactions and security.

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

ronak2121
Offline
Joined: 2006-08-24

What does RA stand for?

Clive Brettingham-Moore

Resource Adapter, sorry.
JCA (Java Connector Architecture) is the standard, a implementation is a
Resource Adapter, a RA is packaged in a rar file. JCA is a required part
of JEE/J2EE.
http://java.sun.com/j2ee/connector/

Implementation will require writing around half a dozen classes
(depending on the particular features you implement; in this case
probably the ResourceAdapter and connection factory classes), but
nothing really complicated if you just want basic function (eg no
transaction support).

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

duncant
Offline
Joined: 2007-04-06

This will not work reliably. There is no guarantee that PreDestroy methods will be called when your application is undeployed or shutdown, which is probably what you want.

I tried to do exactly the same thing you did - but PreDestroy is not guaranteed to work that way. I solved the problem by implementing a lifecycle listener. This gets notified by the app server of lifecycle events such as startup and shutdown.

duncant
Offline
Joined: 2007-04-06
ramapulavarthi
Offline
Joined: 2004-06-01

Yes, Its the scope. You can have @PreDestroy on protected or private method as well.

JAX-WS by default should use the same instance and am not sure what the problem is.

If you are don't want it that way, See iff @HttpSessionScope (https://jax-ws-commons.dev.java.net/http-session-scope/) or @ThreadScope (https://jax-ws-commons.dev.java.net/nonav/thread-scope/) works for you.

ronak2121
Offline
Joined: 2006-08-24

I've tried Glassfish V2 Final, Sun Java Application Server 9.1 so far and this effect happens in both of them.

I can try upgrading to Glassfish V3 and see if this problem is fixed there.

Why hasn't anyone observed this problem before? This is so fundamental.

ramapulavarthi
Offline
Joined: 2004-06-01

Please file a bug at https://jax-ws.dev.java.net/servlets/ProjectIssues if you still see the issue with latest nightly bits.

jitu
Offline
Joined: 2003-06-14

I am not seeing that behaviour with sun-jaxws.xml. Is the deployment happens via sun-jaxws.xml or 109 style of deployment.

ronak2121
Offline
Joined: 2006-08-24

No one has observed this before?

If everyone has, why isn't this a problem for other people besides me?