Skip to main content

Running a background thread and shutting down when undeployed

25 replies [Last post]
jportway
Offline
Joined: 2003-09-22

Hi,
My app needs to do continuous processing in a background thread, ideally created when the application is deployed to the server (but my previous posting about how to create an object on deployment didn't get any answers). I've settled for lazily creating the thread the first time the app is used, but my problem now is that I don't know how to get notified when my app is undeployed - that means that I don't get a chance to shut down the threads I'm running (one of which is holding a port open), which in turn means that i can't redeploy - i have to shut down the whole server and start it up to get rid of my app.
Surely there's a way around this ?
Is there no way to register for a callback when my app is going to be undeployed ?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
tomwitmer
Offline
Joined: 2004-10-13

I know I'm probably replying to a stale topic now, but I've repeatedly run into this same problem with no good solution. (Warning: I'm ranting a little here because I've been chasing this very issue again for the last few days through specifications, books, forums, mailing lists, etc.)

If web.xml has a
entry, why shouldn't the application.xml (or something similar) support the same type of entry, and possibly some explicit deployment dependencies between modules?

As a quick example, I'm currently looking at converting a tomcat web service application to EJBs. It has a background thread and socket pools, both of which convert over to EJB3 nicely through EJB timers and JCA resource adapters.

However, we also have a ton of legacy hibernate code. The session factories need configuration at app startup, and closure at app shutdown. That's trivial with a ContextListener, but there is no equivalent for this in a J2EE app.

(Mini side-rant: We use a lot of individual db logins for security and hipaa reasons, which makes data sources partially useless in our app. It would help if Apache DBCP supported getConnection(username,password), but that's pretty minor.)

Options we've considered and discarded for managing our hibernate session factories:

1) Add a web module just for hibernate startup/shutdown. But the webapp gets deployed before the EJBs are ready. That might be fixable with declaring ejb-refs in the web.xml of the web module, but it's an inelegant solution to begin with since we have no other need for a web module.

2) Use JCA to manage our session factories? This isn't a good fit for JCA, but was seriously considered and still looks like the best option.

3) Convert all hibernate code to JPA and assume it handles EJB dependencies correctly. This can't be done due to the number of files involved, the short schedule, and the lack of a fallback strategy should this fail.

4) Build custom JMX MBean to detect application start/stop. This greatly complicates things since it has to live outside our application. It might also be a problem if we wanted to deploy multiple versions (names) of our application to the same container to make it easier for clients to migrate to the new web service API.

The EJB3 spec went a long way to make our lives easier as J2EE developers, but this little issue is about to leave us back in tomcat land.

We may be missing something obvious, and I'm happy to admit my own ignorance, but no one I've spoken with has found a good solution either. This just seems crazy for something so simple and natural.

whartung
Offline
Joined: 2003-06-13

Simply put, I cheat.

Some servers explicitly offer startup services. Portability is a guideline, but not a suicide pact. Acknowledge the potential portability impact, get the work done and document it. Port it when porting is a real problem.

Another choice is lazy loading. This can be explicit by having your code run through a factory or facade that ensures the resources are loaded, or it can be implcit by giving a class a static initialization method. These methods are executed only once by the class loader when the class is initially loaded. But you have to be careful of your class loaders, and your first hit to the application may well be a doozy depending on what kind of initialization really happens at the juncture. Odds are the poor soul who's going to hit that is the guy performing the "it's up" test to ensure everything started ok.

I also tend to be cavalier with the "no threads in the EJB" edict, as I haven't been burned by using them yet -- as much as I know its forbidden. Someday maybe, someday. But not today, not yet. With MDBs and EJB Timers, this is less of an issue.

I appreciate that there is no documented application lifecycle in the standard, and it's odd that they have not addressed it. But I think it can be taken as a given that it's not been addressed simply because it's not a pressing and crippling problem. A concern, sure. But we've made it so far without it, and I don't think it's the one thing holding EJB back from whatever it may be held back from.

dalecooper82
Offline
Joined: 2006-10-04

Interesting thread. There is not much to add... though...

[quote]it's not a pressing and crippling problem[/quote] (hum, how does one quote here?)

I can't disagree more. Obviously from the thread there is a strong need for such functionality, you saw many workarounds. Some more complex, some less. But nothing that JEE would offer in the spec to make this task easy AND portable, as far as I understood and Googled.

My life with Glasfish (and JEE) would have been much easier if the specs had something as @Service annotation (or "@RunAtStartup", LOL) that could be also MDB. That is some object that could load expensive (in time) data on startup and provide them to the app... plus, get notified via JMS that something changed and refresh itself. Is it there, am I missing something? If not, would this be good for more people than just me? :)

Dale

If it sounds as a rant, sorry. Am tired, was fighting damned collections all night long only to find out later there is a bug in Hibernate. Fixed 3 days ago. Sigh.

trevorwilliams
Offline
Joined: 2004-11-08

I'm a little surprised that no one has mentioned Spring yet. We just did a very similar thing, with an application that spawns multiple processing threads. Using spring, and a minimal amount of xml configuration, it was just a matter of implementing Spring's InitializingBean and DisposableBean interfaces to be notified when the app was deployed and undeployed. Hope this helps.

- Trevor

jportway
Offline
Joined: 2003-09-22

yes, I've used Spring before and I know it's possible with Spring, but I'm not sure how one makes Spring live comfortably inside Glassfish, and is it worth it simply so that I can create an object on startup ?
To the other poster - you may well be right that I should be using a servlet somehow if I'm opening a port. I don't think I know enough about the servlet spec to comment, but I'm not sure that it's exactly what I'd need for this (which is a traditional server socket which pushes streaming data to clients). Even if a servlet was a good idea in this instance, and I would then add a web application module to my application, and then I could add a servlet context listener to create my background thread, it still feels like a hack. Why is my background processing thread coupled to the web layer ? etc. etc.
My point in this thread isn't that it's not possible somehow or other to create a background thread (and I'm thankful for the hints offered by people here - all of which are a lot cleaner and better than the method I suggested). My point is that creating something at startup of an application and having it informed when the app is shutting down seems like such a fundamental and obvious thing to need that I find it absolutely extraordinary that the specification doesn't provide a clean and simple way to do it.

stvconsultants
Offline
Joined: 2006-03-06

Well it's not really a web layer, more a servlet layer...

Most (i'd guess 99.9%) people use servlets to do web stuff, so we call the servlet layer a web layer...

However, it's just a servlet layer.

Servlets are designed to allow you to manage conversations attached to a port.

The original spec envisioned people having, e.g. telnet servlets, etc.

There is nothing stopping these conversations from being monologoues (i.e. only pushing data out)

If you ask me, you seem to be re-inventing the servlet layer with your background thread... there's the hack, and it's your hack ;-)

N.B.
I'm not saying that servlets are the solution for _your_ problem, just that they were originally designed to be the solution for the type of problem you seem to be describing.

I hope this answers your question as to why your background processing thread is coupled to the web (servlet) layer, i.e. the servlet layer is where TCP/IP communication should be handled!

-Stephen.

jportway
Offline
Joined: 2003-09-22

Thanks for your advice about servlets and i really will ook into them for the network side of my code, however you seem to be speaking under the misconception that the background thread that I want to run has something directly to do with networking. The background thread and objects I want to create do compute intensive processing continuously on the data in my application - they're not network related at all. There's no reason I can think of that they should be treated as part of the servlet layer - they're actually part of my model.
I'm not trying to re-invent servlets by simply wanting a generic way to create an object when my application starts up - this really has nothing whatsoever to do with servlets. JBoss does have the perfect solution with their @Service annotation - I don't want to re-invent anything, I think they've pretty much got it right. Why do you think JBoss felt it necessary to create this feature ?

ljnelson
Offline
Joined: 2003-08-04

Speaking from memory, quickly, without references, etc. etc., take it for what it's worth...

What about setting up a Message Driven Bean that receives a message when your application is ready to go, and receives a message when it shuts down?

There is no defined order to how EJBs start up and shut down (bean A can't be made explicitly to depend on bean B), but this may or may not be important to you.

Laird

jsl123
Offline
Joined: 2006-07-20

Hi, i've just noticed this thread and i've been attempting a similar thing. But some of the responses have raised a few questions.

Firstly, is it safe to start your own background threads in the server. I thought was generally frowned upon. Are there any rules/guidelines you should stick to when doing this.

Secondly is it safe or how do you go about calling EJBs from the thread. How does the container manage the transactions, etc. I ask because my app is using a 3rd party library (which starts the threads) and responds using callbacks. Should i mark the beans it calls as RequiresNew?

At the moment i'm using a LifeCycle Module to manage the threads and then calling the beans remotely. But this has 2 problems, firstly i need remote interfaces and secondly it seems both parts have separate classloaders/path so i'm duplicating the interface functions which seems clumsy.

Thanks

jportway
Offline
Joined: 2003-09-22

For anyone else with this kind of problem the way i've ended up doing this within glassfish is to have a singleton object (which gets created on the first request to the app - i ended up having to put a check in each session bean method to create the singleton if it wasn't already created - yuck) which creates the background thread.
Every twenty seconds or so the thread check to see if a flag has been set and if not then it exits the thread. Once it's checked the flag it clears it.
Every ten seconds or so I have a J2EE timer that calls one of my session beans which sets the flag - so as long as the timer is running the thread stays running, and when the timer stops hopefully the thread will stop soon after.
I tried just running the whole thing from a repeating j2ee timer set to run ten times a second, but it was so wildly innacurate i gave up on that approach (it was being called once every five to ten seconds).
This approach *seems* to work so far, but I'm still not completely sure whether my app is being closed down properly or not - at least it's releasing resources like ports etc. now.

Needless to say, I still find this an extraordinarily complicated and messy procedure to go through just to do something as simple as create an object on startup and spawn a background thread.

tjquinn
Offline
Joined: 2005-03-30

A quick follow-up to the discussion...

1. Did you consider and reject using a life-cycle module? If so, it would be useful to hear why. Of course life cycle modules are started at app server start-up (not at the start-up of a specific app) but that might have been a way to accomplish what you want to do.

2. When you mentioned that your thread opens a port, one of my first thoughts was whether a connector - as a Java EE concept for handling interfaces to the outside world such as ports - would be a way of addressing your need. For example, configuring which port should be used, etc. might be easier that way.

Granted that might be more complicated than what you had initially hoped for, but it might be cleaner (and compliant) compared to what you have.

- Tim

jportway
Offline
Joined: 2003-09-22

I'll check out the life-cycle module idea, but it sounds as if it's external to my actual application with all the added complexity that that entails to communicate with it from inside my app.

It really surprises me that no one else seems to need to do things like running background tasks - does anyone know of an architectural reason why this isn't easily possible in glassfish (scalability problems?) , or is it just an oversight ? If it's an oversight it's extraordinary. If it's not an oversight, and there's a real reason why it's not a good idea to just run a background thread, then there needs to be something else to replace it surely - or is it just that absolutely everyone does fairly simple request driven applications that mainly just read data from databases ?

carlavmott
Offline
Joined: 2005-02-10

Please file an RFE so we can track this.

Thanks,
Carla

jportway
Offline
Joined: 2003-09-22

I've filed a ROE for this issue - issue #729
https://glassfish.dev.java.net/issues/show_bug.cgi?id=729

tinashechipomho
Offline
Joined: 2005-01-24

I might be missing something, i had been in a similar situation and I simply used the ServletContext listener which is notified when the application is deployed and when the application is about to be undeployed, it works like a charm and it is compatible with any JEE server.

have you looked into that?

jportway
Offline
Joined: 2003-09-22

perhaps i could make this work somehow, but my application is a rich-client application which doesn't use any servlets or JSP etc. (at least as far as I know, though I seem to remember that glassfish *does* create some magic servlet underneath for Webstart deployment or something - but that's not really under my control). Presumably I could make a fake servlet for listening to these messages and it sounds like a cleaner approach than the one I've got - thanks for the advice. It still seems pretty hacky compared to the JBoss @service annotation though.

tinashechipomho
Offline
Joined: 2005-01-24

You dont need a servlet or JSP all you need is make an enterprise application with a web-component. There is no restriction on the number of servlets or jsps.
If u dont need them dont use put them in, all you need is a web component with a web.xml file configured to use a servlet context listener, which will be notified when the application is deployed and notified again when the application is about to be undeployed.

jportway
Offline
Joined: 2003-09-22

yes, that's what I mean - my project doesn't have a web component - it's purely a rich client app. I guess I could add a web component just so that I can listen for when my app starts up and shuts down, but that's a little awkward don't you think ?

stvconsultants
Offline
Joined: 2006-03-06

> yes, that's what I mean - my project doesn't have a
> web component - it's purely a rich client app. I
> guess I could add a web component just so that I can
> listen for when my app starts up and shuts down, but
> that's a little awkward don't you think ?

From your original post

> one of which is holding a port open

What I ask is, what is a servlet if not a JavaEE method for listening to a port. Traditionally, we use it to listen to port 80 for HTTP protocol communications, but that is just because most people want to do that.

It seems to me that if you are holding a port open, you want to use the JavaEE mechanisms that map well to having ports open and, as originally designed, servlets are therefore what you'd use!

jportway
Offline
Joined: 2003-09-22

thanks for the tip about the JBoss service declaration - it looks as if the simplest thing to do might be to use JBoss instead, though it's a pity because Glassfish just generally feels so much cleaner and simpler than JBoss.

jportway
Offline
Joined: 2003-09-22

thanks again for your help - the cause of my confusion is that I can't believe this isn't a problem people run into all the time, and that there isn't an easy solution to it somehow - I keep thinking I must surely have missed an obvious answer. All I want to do is run a thread to do background processing while my application is running - isn't that something that people need to do all the time, except it purely request driven applications ?

I'm not sure what the problem is with having a listener within the application - obviously it couldn't be called AFTER the application was undeployed if it was in the app, but it could be called when the application was ABOUT to be undeployed - giving it a chance to shut down any running threads etc. before returning and allowing the app server to then clean out the application as normal.

stefanarentz
Offline
Joined: 2006-05-23

> thanks again for your help - the cause of my
> confusion is that I can't believe this isn't a
> problem people run into all the time, and that there
> isn't an easy solution to it somehow - I keep
> thinking I must surely have missed an obvious answer.
> All I want to do is run a thread to do background
> processing while my application is running - isn't
> that something that people need to do all the time,
> except it purely request driven applications ?

The problem is that EJB3 is extremely well suited for the standard J2EE blueprints application that was created in the lab but fails miserably for anything more complex. Read: anything you actually build in real life.

Sorry for being so blue, but I'm also running into so many annoying limitations of EJB3 and the current EJB3 application servers that I'm considering dropping EJB3 completely and to simply go with JBoss and Spring 2.0 again. That wil at least give me the flexibility and many many extension points to basically do anything I want. From singleton services running in the background to integrating interesting open source projects into a deployment unit.

Maybe the apps that I build are simply not standard JEE material. I don't know.

Oh, JBoss 4.0.4 has a @Service annotation that will do what you want with the ease of EJB3. See http://docs.jboss.org/ejb3/app-server/tutorial/service/service.html for more info on how to turn a POJO into a service.

Why was someting so simple omitted from the EJB3 spec? No idea. But you are not the only one missing it. Ah wel, maybe EJB4 in a couple of years will get it right :-)

S.

jportway
Offline
Joined: 2003-09-22

thanks for your reply - I'll look at doing a JMX or AMX approach, but I'm astonished that there is no standard API for such a simple and obvious requirement. This makes it extremely awkward for any application to do any background processing at all - surely someone recognises that not all applications can be purely request driven?

As you mentioned JMX isn't really designed for use inside your application, but for remote management - it's a complicated and fiddly process just to know something as basic as when you're being shut down. All that's really needed is a deployment descriptor which specifies an object to instantiate on startup, and which gets a callback when the application is about to be shut down.

The fact that something like this doesn't already exist makes me wonder if there's a reason that it's not there. If not I really think it should be something added to the next version of the spec - or at least added to Glassfish

km105526
Offline
Joined: 2005-04-04

> As you mentioned JMX isn't really designed for use
> inside your application, but for remote management -
> it's a complicated and fiddly process just to know
> something as basic as when you're being shut down.
> All that's really needed is a deployment descriptor
> which specifies an object to instantiate on startup,
> and which gets a callback when the application is
> about to be shut down.
>
I am a bit confused.
Are you saying that the Class that you want instantiated
at application loading time? If that's the case, then
who should load this Class? All the classes that are
specific to application are loaded by a separate instance
of an application class loader. When the application is
undeployed, the class loader and all the classes it loaded
are going to be garbage collected. So, I am not sure how
you'd do it as part of the same application.

Don't you think you need a listener code that is not part
of the application itself, but is interested in that
application or various events in its life cycle?

Unless I am missing something really basic, I feel you
will have to rely on proprietary application server
extensions to be able to do this reasonably. GlassFish
does have such extensions:
- provision of Life Cycle Modules.
- provision of registering your own MBeans.
- provision of AMX. Take a look at DeploymentManager
(http://tinyurl.com/nlgce)

Remember, you said you want the listener code to be [b]part of app server's runtime[/b]. If it is not a
standard Java EE application, how else can it (your code)
be part of app server's runtime => Only through extensions
that app server provides.

> The fact that something like this doesn't already
> exist makes me wonder if there's a reason that it's
> not there. If not I really think it should be
> something added to the next version of the spec - or
> at least added to Glassfish

Well, I have articulated above how it is already a part of
GlassFish. You could easily achieve what you are looking for. (i.e. if I understand it correctly).

Making it a part of specification is another story.

For that matter, you should take a close look at JSR-88 (I
am not very familiar with it) -- but it might have
something that you are looking for.

http://tinyurl.com/mhk4n

Thanks,
Kedar

km105526
Offline
Joined: 2005-04-04

> Hi,
> My app needs to do continuous processing in a
> a background thread, ideally created when the
> application is deployed to the server (but my
> previous posting about how to create an object on
> deployment didn't get any answers).

Sorry to have missed your earlier post.

> I've settled for
> lazily creating the thread the first time the app is
> used, but my problem now is that I don't know how to
> get notified when my app is undeployed - that means
> that I don't get a chance to shut down the threads
> I'm running (one of which is holding a port open),
> which in turn means that i can't redeploy - i have to
> shut down the whole server and start it up to get rid
> of my app.
> Surely there's a way around this ?
> Is there no way to register for a callback when my
> app is going to be undeployed ?

There is a JMX based way to do this.
I am not sure though whether it is a standard way to do this.
Mostly, there is no standard way to this and your purpose
is likely to not get served when you change the deploy
platform. GlassFish implements JSR-77 which guarantees
that every time you deploy an application, JSR - 77 MBeans will come into picture.
If you try to access them through JSR-77 API, (javax.management.j2ee) (http://java.sun.com/j2ee/1.4/docs/api/index.html), you
can't register for notifications about when the MBeans
are registered or deregistered.

But, if you resort to pure JMX way of doing this,
you coul d do something like:
[code]
//Express interest in getting notifications from
MBeanServerDelegate when the MBean is registered and
deregistered (http://java.sun.com/j2ee/1.4/docs/api/javax/management/MBeanServerDelegate.html#addNotificationListener(javax.management.NotificationListener,%20javax.management.NotificationFilter,%20java.lang.Object))

// find the ObjectName of the MBean that comes into
picture when the MBean is deployed. You could actually
connect to GlassFish (from JConsole) using the JMX port that's printed when you start the domain. For example, the ObjectName is of the form:
[b]
com.sun.appserv:j2eeType=J2EEApplication,name=app-name.."
[/b]
// Once you add the notification listener to notification
broadcaster (MBeanServerDelegate), you'll come to know
when the application is deployed/undeployed.
[/code]

It is interesting to know where you'll register this
thread that listens to the notifications. What are your
ideas? Obviously, the thread can't be a part of the
application itself.

There might be alternate ways of doing this using what's
called AMX. Let me know if you'd be interested in doing it
that way.

Thanks,
Kedar

Message was edited by: km105526