Skip to main content

How could I implement and deploy a background process in Glassfish?

15 replies [Last post]
abelmj
Offline
Joined: 2006-05-03

Hi, in our system whe have a lot of SNMP equipment, whose functionality we manage through several EJB3 session beans; we use JMS to send events and notifications to our swing clients. One of our client application, is a browser that display "graphically" all the remote units; in that browser I need to show in real-time if the server has communication with those remote units; basically ping each remote unit and if we have response, paint the unit in green, and if we haven´t paint it in red. I need to code a background process whose only job is "ping" the remote units, and send events with the response (I already have a session bean with several methods to send events via JMS). The problem is that I don´t know how to deploy such a process in Glassfish. I've done session beans, entity beans, and MDB beans, but none of these "seem to fit" with the problem. For this application I don`t need a pool of beans, I just need that the Application Server start the background process that simply try to ping to a list of IPs, and send events with the result of that pings. I don´t want to have an external application, so which is the best way to implement this and deploy to Glassfish?
Thanks!

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
whartung
Offline
Joined: 2003-06-13

> 3. The EJB Timer approach was one of my thoughts, but
> I have a lot of pings to do, and we are not supposed
> to do Threads in that beans, do we?

The portable and clusterable solution to this then is to use a combination of the EJB Timer and MDBs. I appreciate that this seems a bit heavyweight, but at the moment, that's all we have.

What you do is create an MDB that takes a parameter of somekind so that it will specifiy which subset of your 1400 sites to ping. You'll need to configure your MDB pool to handle as many instances as you have subsets (say your parameter selects a subset of 100 sites, then you'd need 1400 instances of the MDB). Note, this parameter can simply be a list of sites.

Then, you EJB Timer fires and creates 1 message for each subset (in this case, 14 subsets).

The cluster will ensure that the timer fires once, and you can cluster the MDBs to fire on different servers, if that's what you like.

It's a bit coarse, but using basic JEE components, this is how JEE "threads". But you get all the rest "for free", the clustering, the portability etc. And the simplicity. This is a really simple solution.

I've used this technique to great effect for parallelizing tasks. The task would fire (from an EJB Timer), I would create N messages, and submit them all via JMS. I would see improvements just running locally on a multicore laptops doing mundane tasks like creating 10000 customer statements. JMS offers little overhead to the problem. Certainly it will be faster to send 14 messages with 100 site each than 1400 messages with 1 site each. But in our case we DID send "10000" messages, and we were still DB bound, so the JMS impact wasn't as much as one would expect. Using 4 MDB instances, we got a 2.5x increase in our mundane processing on a 2 core laptop over a simple for loop doing each statement. Using a memory only JMS queue makes it even less overhead. We never clustered it, but with a cluster of machines you should scale even better (until the DB melts of course).

So, I'd give that a shot. Everything you need is in the JEE tutorial to pull this off (save tuning the number of instances, that's in the GF docs).

Jose Noheda

To me it seems really heavyweight. If you absolutely need a portable (read
nothing beyond JEE), clusterable and multi-threaded solution this is it. On
the other hand you may decide you don't REALLY have that needs. How would I
do it then?

1.- I would create a (stateless) (thread-safe) bean with one method that
selects a subset of servers from the (injected) complete list and pings them
2.- I would use DWR (reverse AJAX) to push the data to the browser
3.- I would fire the bean using a Quartz task with Spring's
MethodInvokingJobDetailFactoryBean and may be deploy the context using the
new JCA (rar) capabilities

Of course, if you haven't ever worked with Spring, Quartz and DWR that may
seem even more complicated..

Regards,

On Jan 15, 2008 5:57 PM, wrote:

> > 3. The EJB Timer approach was one of my thoughts, but
> > I have a lot of pings to do, and we are not supposed
> > to do Threads in that beans, do we?
>
> The portable and clusterable solution to this then is to use a combination
> of the EJB Timer and MDBs. I appreciate that this seems a bit heavyweight,
> but at the moment, that's all we have.
>
> What you do is create an MDB that takes a parameter of somekind so that it
> will specifiy which subset of your 1400 sites to ping. You'll need to
> configure your MDB pool to handle as many instances as you have subsets (say
> your parameter selects a subset of 100 sites, then you'd need 1400 instances
> of the MDB). Note, this parameter can simply be a list of sites.
>
> Then, you EJB Timer fires and creates 1 message for each subset (in this
> case, 14 subsets).
>
> The cluster will ensure that the timer fires once, and you can cluster the
> MDBs to fire on different servers, if that's what you like.
>
> It's a bit coarse, but using basic JEE components, this is how JEE
> "threads". But you get all the rest "for free", the clustering, the
> portability etc. And the simplicity. This is a really simple solution.
>
> I've used this technique to great effect for parallelizing tasks. The task
> would fire (from an EJB Timer), I would create N messages, and submit them
> all via JMS. I would see improvements just running locally on a multicore
> laptops doing mundane tasks like creating 10000 customer statements. JMS
> offers little overhead to the problem. Certainly it will be faster to send
> 14 messages with 100 site each than 1400 messages with 1 site each. But in
> our case we DID send "10000" messages, and we were still DB bound, so the
> JMS impact wasn't as much as one would expect. Using 4 MDB instances, we got
> a 2.5x increase in our mundane processing on a 2 core laptop over a simple
> for loop doing each statement. Using a memory only JMS queue makes it even
> less overhead. We never clustered it, but with a cluster of machines you
> should scale even better (until the DB melts of course).
>
> So, I'd give that a shot. Everything you need is in the JEE tutorial to
> pull this off (save tuning the number of instances, that's in the GF docs).
> [Message sent by forum member 'whartung' (whartung)]
>
> http://forums.java.net/jive/thread.jspa?messageID=254018
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>
[att1.html]

whartung
Offline
Joined: 2003-06-13

> To me it seems really heavyweight. If you absolutely
> need a portable (read
> nothing beyond JEE), clusterable and multi-threaded
> solution this is it.

It's only heavyweight if you don't already have the JEE infrastructure. If you do already have it, it's pretty straightforward requiring only a Session Bean, and Message Driven Bean (which are just POJO's today), small bit of code to prime the timer, and a queue on the server. All told, there's maybe 30-40 lines of code required to pull this off, plus your actual logic.

Its APPEARS heavyweight because of the need of the JEE infrastructure, but once you've taken that step, this is almost free. Hardest part for most is getting JMS set up, and Netbeans has a wizard that will do that for you.

> On the other hand you may decide you don't REALLY have
> that needs. How would I do it then?

If I didn't do it this way, I'd create a thread in one of the WAR instances and be done with it. Tie some lifecycle bits to the ContextListener and go my merry way. The Java 5 concurrent services make this stuff pretty easy to do. Or I'd take it out of the server completely and run it as a standalone service feeding a remote JMS queue. Tie it in to Solaris's SMF service and never think of it again.

All of this can be readily done simply with the JDK.

ewernli
Offline
Joined: 2007-10-21
ewernli
Offline
Joined: 2007-10-21

I don't know if it's ok according to the spec, but you can also write a ServletContextInitialized that starts a thread in the init method and kills it in the destroy method. It worked for me at least. If portability is not critical you can also write a Glassfish lifecycle module that starts a thread. Note that the ServletContextInitializer (which is deployed as a web application) can be redeployed without restarting Glassfish, which is not possible with a lifecycle. Of course, if you have a clustered Glassfish, then these simple solutions may not work (each node will have its background thread). In this case an EJB timer is probably better because it will be executed correctly in a cluster.

abelmj
Offline
Joined: 2006-05-03

Hi, Thanks for all the answers:

1. Actually I'm doing a JMX Bean, to start a pool of threads to ping the 1400 remote units we have. Problem with this approach: Not Portable and I don`t know how to implement something like a timer that calls the startPing Process method of my JMX bean every 15 minutes. So I'm not fully satisfied with this.

2. I really like the Connector approach because you can use threads, and is Portable, but the problem is that I don't know nothing about connectors, and I don't know if it requires much time to learn; time is always a problem. bbergquist, you've posted that yo've done a SNMP Connector, could you share some code with me? I'm really a newby in connector issues.

3. The EJB Timer approach was one of my thoughts, but I have a lot of pings to do, and we are not supposed to do Threads in that beans, do we?

4. ServletContextInitialized -> problems with cluster, so dismissed

jr158900
Offline
Joined: 2005-04-13

For connector sample, you can look at J2EE 1.4 samples

http://java.sun.com/j2ee/1.4/download.html
(Samples bundle) samples/connectors/apps/mailconnector

You can also see :
http://java.sun.com/developer/technicalArticles/J2EE/connectorclient/res...

whartung
Offline
Joined: 2003-06-13

The others are valid suggestions, but you could probably get things done more easily by just using the EJB Timer Service.

It's your application, but you can easily creating a timer task that runs every, say, 5 or 10 seconds, to do your polling.

The benefit is that your code is a generic, everyday session bean. You need to write a little of plumbing logic to prime the EJB timer, but once it's up, the rest is pretty much the same.

Rumor has it in EJB 3.1, this will be even easier to do as well.

Jose Noheda

Every time I have tried to make the timer API to work I've given up and
revert to just using Quartz. Spring helps here as well

Regards

On Jan 14, 2008 6:58 PM, wrote:

> The others are valid suggestions, but you could probably get things done
> more easily by just using the EJB Timer Service.
>
> It's your application, but you can easily creating a timer task that runs
> every, say, 5 or 10 seconds, to do your polling.
>
> The benefit is that your code is a generic, everyday session bean. You
> need to write a little of plumbing logic to prime the EJB timer, but once
> it's up, the rest is pretty much the same.
>
> Rumor has it in EJB 3.1, this will be even easier to do as well.
> [Message sent by forum member 'whartung' (whartung)]
>
> http://forums.java.net/jive/thread.jspa?messageID=253799
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
> For additional commands, e-mail: users-help@glassfish.dev.java.net
>
>
[att1.html]

whartung
Offline
Joined: 2003-06-13

The primary differences between Quartz and EJB Timer are:

1) that EJB Timer runs in the EJB tier, whereas Quartz runs in the Servlet Tier (an EJB Timer is implemented as a Session bean).

2) The timer scheduling model. Quartz has a more "cron like" scheduling model "run every Tuesday", "run at 15 after the hour", etc. whereas EJB Timer is simpler and basically can run at a specific time, or at a specific time and "every N seconds" after.

#2 tends to be most folks sticking points with the EJB Timer.

The other detail is that once an EJB Timer is created (notably recurring timers), there's no need to recreate it since they're persistent. So, you have to bootstrap the service. That can be confusing for folks to that initialize the timer in an init servlet, and naively recreate the timer each container start.

I didn't have any real problem with the EJB Timer service, but it could use a little richer interface and could well do to be exposed on the Admin GUI. It's one of those odd hybrid application/container artifacts.

sm157516
Offline
Joined: 2005-03-28

You could do this using the Self Management Framework in GlassFish. An event could be created that will try to ping the IPs and the with the results, some action could be taken. One event is associated with one action in Self Management and the event-action form a rule. The Self Management service is started during GlassFish startup and the rules could be created using the administration console or Command line interface, after creating the event and action mbeans.

Please see http://blogs.sun.com/technical/entry/self_management_rules for more details.

HTH,
Shalini.

abelmj
Offline
Joined: 2006-05-03

Thanks, I'll give it a try

tjquinn
Offline
Joined: 2005-03-30

Another approach to solving a problem like this is to write a custom connector as specified by the Java EE connector spec. Connectors are the portable and spec-compliant way of allowing applications to exchange information with the outside world in ways other than web pages, databases, etc.

JSR 112 [http://jcp.org/en/jsr/detail?id=112] describes the Java EE Connector Architecture, which GlassFish supports. There is a 1.6 revision in process (JSR 322) but it is not final yet.

- Tim

bbergquist
Offline
Joined: 2007-04-02

The Connector is the way that I do it. A connector is one of the J2EE components that can use threads. So I've built a connector that does my SNMP work. It supports both outbound SNMP request/response and also inbound SNMP notifications.

abelmj
Offline
Joined: 2006-05-03

Hi, Thanks for all the answers:

1. Actually I'm doing a JMX Bean, to start a pool of threads to ping the 1400 remote units we have. Problem with this approach: Not Portable and I don`t know how to implement something like a timer that calls the startPing Process method of my JMX bean every 15 minutes. So I'm not fully satisfied with this.

2. I really like the Connector approach because you can use threads, and is Portable, but the problem is that I don't know nothing about connectors, and I don't know if it requires much time to learn; time is always a problem. bbergquist, you've posted that yo've done a SNMP Connector, could you share some code with me? I'm really a newby in connector issues.

3. The EJB Timer approach was one of my thoughts, but I have a lot of pings to do, and we are not supposed to do Threads in that beans, do we?

4. ServletContextInitialized -> problems with cluster, so dismissed