Servlet to Servlet Communication

M

MattC

My application uses 2 Servlets - ServletMain and ServletPoll.
ServletMain is the main Servlet for my MVC application. ServletPoll is
responsible for polling for data files. The idea is that every 10
minutes ServletPoll will "wake up" and check to see if there are any
new data input files to process. If there is it will process these
files and then go back to sleep for 10 minutes and start the cycle all
over again.

The problem I have is that I do not no how to start the method in
ServletPoll that will loop forever checking for data input files.

I have set up the web.xml file so that ServletMain and ServletPoll get
loaded when the web app is deployed. Now the question is how can I
invoke the method to start the polling. This needs to begin as soon as
the web app is deployed.

Is it possible to invoke ServletPoll's polling method from the init()
method of ServletMain?
 
A

Alun Harford

MattC said:
My application uses 2 Servlets - ServletMain and ServletPoll.
ServletMain is the main Servlet for my MVC application. ServletPoll is
responsible for polling for data files. The idea is that every 10
minutes ServletPoll will "wake up" and check to see if there are any
new data input files to process. If there is it will process these
files and then go back to sleep for 10 minutes and start the cycle all
over again.

The problem I have is that I do not no how to start the method in
ServletPoll that will loop forever checking for data input files.

I have set up the web.xml file so that ServletMain and ServletPoll get
loaded when the web app is deployed. Now the question is how can I
invoke the method to start the polling. This needs to begin as soon as
the web app is deployed.

Is it possible to invoke ServletPoll's polling method from the init()
method of ServletMain?

I've not tried it myself, but I'd think calling the method in the
static {
....
}
block would do it.
 
J

Juha Laiho

MattC said:
My application uses 2 Servlets - ServletMain and ServletPoll.
ServletMain is the main Servlet for my MVC application. ServletPoll is
responsible for polling for data files. The idea is that every 10
minutes ServletPoll will "wake up" and check to see if there are any
new data input files to process.

No, this doesn't sound like a servlet. A servlet wakes up on external
trigger, handles the event and goes back to sleep. It doesn't, by
itself, wake up periodically.

I'm seconding the comment from Ross that a ServletContextListener
would be a better place to hook up this kind of functionality.
 
M

MattC

You recommend using a static block:
"static {

}

I am unclear exactly what you mean. Where should the static block be
placed, in ServletMain or ServletPoll? If in ServletPoll can I assume
that by the time the static block is executed the class is fully
constructed and the polling method available?
 
M

MattC

ServletPoll is a servlet dedicated to periodically retrieving data
files. As such my idea is that it will be put into a continuous loop.
Every 10 minutes it will check for data files and process them. It will
then wait - System.wait(); - and start the cycle all over again.

Is there a simpler way to do this?
 
R

Ross Bamford

ServletPoll is a servlet dedicated to periodically retrieving data
files. As such my idea is that it will be put into a continuous loop.
Every 10 minutes it will check for data files and process them. It will
then wait - System.wait(); - and start the cycle all over again.

Is there a simpler way to do this?

Start with something along the lines of:

<pseudocode>
public class LifecycleListener implements
javax.servlet.ServletContextListener {

private volatile Thread manager;

private static class Manager implements Runnable {
public void run {
Thead me = Thread.currentThread();
while (manager == me) {

// Do your stuff here

try {
Thread.sleep(10000)
} catch (InterruptedException e) {
// could be we're to stop, or just a 'spurious wakeup'
}
}
}
}

public void contextInitialized(...) {
manager = new Thread(new Manager());
manager.start()
}

public void contextDestroyed(...) {
Thread t = manager;
manager = null;
t.interrupt();
}
}
</pseudocode>

And then look into the Servlets docs, since there are some things you need
to be aware of with this kind of processing.
 
H

HalcyonWild

Ross said:
Start with something along the lines of:

<pseudocode>
public class LifecycleListener implements
javax.servlet.ServletContextListener {

private volatile Thread manager;

private static class Manager implements Runnable {
public void run {
Thead me = Thread.currentThread();
while (manager == me) {

// Do your stuff here

try {
Thread.sleep(10000)
} catch (InterruptedException e) {
// could be we're to stop, or just a 'spurious wakeup'
}
}
}
}

public void contextInitialized(...) {
manager = new Thread(new Manager());
manager.start()
}

public void contextDestroyed(...) {
Thread t = manager;
manager = null;
t.interrupt();
}
}
</pseudocode>

Hi ,

ServletContextListener is one method. I was also thinking about this
problem , and ServletContextListener did not occur to me.

I thought, in the init() of ServletPoll, we can call another plain
Runnable java class. I do not know if there is something wrong in doing
this, but I am not sure. Is there anything wrong with doing this.
The only thing I can think of is that , the server thread running might
be blocked by ServletPoll, while ServletMain, waits to get its control,
to process subsequent requests.
Or might be I am wrong. There are two separate server threads for
ServletMain and ServletPoll. Please advise. Thanks.
 
R

Ross Bamford

Hi ,

ServletContextListener is one method. I was also thinking about this
problem , and ServletContextListener did not occur to me.

I thought, in the init() of ServletPoll, we can call another plain
Runnable java class. I do not know if there is something wrong in doing
this, but I am not sure. Is there anything wrong with doing this.
The only thing I can think of is that , the server thread running might
be blocked by ServletPoll, while ServletMain, waits to get its control,
to process subsequent requests.
Or might be I am wrong. There are two separate server threads for
ServletMain and ServletPoll. Please advise. Thanks.

I wouldn't suggest going down that route. If I understand you correctly
you're suggesting something like the following:

<pseudocode>
public class ServletPoll extends javax.servlet.http.HttpServlet {

public void init() {

Runnable lifecycleMgr = new LifecycleManager();
lifecycleMgr.run();

}

public void doGet(HttpServletRequest req, HttpServletResponse resp) {

// what on earth goes here?

}
}
</pseudocode>

IIRC this is a very bad idea, since theres probably no guarantee that the
init() calls will be made on separate threads (you should check the
Servlet spec to be sure because I haven't), and just calling the run()
method on a runnable does NOT start a new thread. So not only would your
init() method fail to return (bad in itself) but you may well prevent
other servlets being initialized too. The server would probably not hook
it up to service requests, which is what I think you mean when you say
ServletPoll might block the server thread.

The thread model with Servlets is actually slightly more complex than you
imply, and usually involves a thread pool, with the next free thread
handling requests as they come in. I think the spec is fairly non-specific
about the specifics of the threading model, and instead chooses a very
open-ended approach (if it doubt, assume it's not safe), to allow servers
to manage the threading how they choose according to the performance and
resource requirements.

Of course, the real question is, why is ServletPoll even a Servlet? What
is it serving, i.e. what would you be doing with the doGet, doPost, or
whatever methods, in that class? A servlet should aim to process
individual requests, in any order, generating responses as appropriate, as
quickly and with as little shared state as possible (read: none). Think
the MVC controller. Another, entirely separate part is application,
request and session lifecycle and initialization, and for this the spec
provides separate interfaces to hook into these things, which in this
particular case means ServletContextListener.

If you are determined, you could probably get away with _starting a new
thread_ from the ServletPoll.init() method, allowing the method to return.
I'd guess you'd be on shaky ground, however, with regard to running on
different app servers and platforms, and you would of course need to
consider graceful shutdown of your new thread - not just for server
shutdown but also because it's possible to dynamically deploy and undeploy
apps in most containers.
 
A

Alun Harford

MattC said:
You recommend using a static block:
"static {

}

I am unclear exactly what you mean. Where should the static block be
placed, in ServletMain or ServletPoll? If in ServletPoll can I assume
that by the time the static block is executed the class is fully
constructed and the polling method available?

ServletPoll. And yes, the block is executed immediately AFTER the class gets
loaded (as per java standards).
(Although what you say you want doesn't seem to be what you actually want,
based on what you've said - Why is ServletPoll a servlet?)

Alun Harford
 
M

MattC

OK, so what I am hearing is that I really should spawn a new thread
rather than using the servlet ServletPoll.

My approach would be to start a new thread in the Servlet.init() method
and then kill that thread in the Servlet.destroy() method. Since the
new thread will be started and then the init() method will complete I'm
not clear on what the concern is in starting the thread from the
init() method. Can you explain?
 
H

HalcyonWild

Ross said:
I wouldn't suggest going down that route. If I understand you correctly
you're suggesting something like the following:

<pseudocode>
public class ServletPoll extends javax.servlet.http.HttpServlet {

public void init() {

Runnable lifecycleMgr = new LifecycleManager();
lifecycleMgr.run();

}

public void doGet(HttpServletRequest req, HttpServletResponse resp) {

// what on earth goes here?

}
}
</pseudocode>

Yes. This is what I meant. But then again you are right. Why does
ServletPoll need to be a servlet.
IIRC this is a very bad idea, since theres probably no guarantee that the
init() calls will be made on separate threads (you should check the
Servlet spec to be sure because I haven't),

Ok. That is one aspect. So we are not sure whether each servlet runs in
its own thread.
and just calling the run()
method on a runnable does NOT start a new thread. So not only would your
init() method fail to return (bad in itself) but you may well prevent
other servlets being initialized too.

calling run() on a Runnable does not start a new thread. Really, am I
missing something in fundamentals of Java, or is it some internal JVM
trick.
The server would probably not hook
it up to service requests, which is what I think you mean when you say
ServletPoll might block the server thread.
Yes.


The thread model with Servlets is actually slightly more complex than you
imply, and usually involves a thread pool, with the next free thread
handling requests as they come in. I think the spec is fairly non-specific
about the specifics of the threading model, and instead chooses a very
open-ended approach (if it doubt, assume it's not safe), to allow servers
to manage the threading how they choose according to the performance and
resource requirements.

Of course, the real question is, why is ServletPoll even a Servlet? What
is it serving, i.e. what would you be doing with the doGet, doPost, or
whatever methods, in that class? A servlet should aim to process
individual requests, in any order, generating responses as appropriate, as
quickly and with as little shared state as possible (read: none). Think
the MVC controller. Another, entirely separate part is application,
request and session lifecycle and initialization, and for this the spec
provides separate interfaces to hook into these things, which in this
particular case means ServletContextListener.

If you are determined, you could probably get away with _starting a new
thread_ from the ServletPoll.init() method, allowing the method to return.
I'd guess you'd be on shaky ground, however, with regard to running on
different app servers and platforms, and you would of course need to
consider graceful shutdown of your new thread - not just for server
shutdown but also because it's possible to dynamically deploy and undeploy
apps in most containers.


Matt , I think you are better off with the Listener.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top