views:

167

answers:

1

I'm not exactly sure what question to ask here since I don't know the vocabulary...

Tomcat servlets (and any server for that matter) work nicely if they are stateless and respond quickly to requests, with state stored in a database. It seems like if I have long-running operations then maybe I want to run some other service in the background, and have the Tomcat handlers communicate with it. Is there a way to run a long-running Java application in the same JVM as Tomcat and interact with it via "regular" Tomcat servlet?


Example: Let's say I want to offer a RESTful number factorization service in HTTP.

Here's a possible scenario (I hope I have the HTTP syntax right, I'm omitting most of the headers):

# comments start with #, > = request, < = response
# 
# first we create a queue
> POST /factorizer/create-queue
> {information here}
< queue=12345B
# then we post some numbers to it
> POST /factorizer/queue/12345B
> 123
> 456
> 678
> 12345678901234567890123456789
< OK
# let's look at the status
> GET /factorizer/queue/12345B/status
< requested=4
< processed=3
# query
> GET /factorizer/queue/12345B/7
< Error: invalid index
> GET /factorizer/queue/12345B/3
< Error: not complete
> GET /factorizer/queue/12345B/0
< 123=3*41
# wait a while
> GET /factorizer/queue/12345B/status
< requested=4
< processed=4
> GET /factorizer/queue/12345B/3
< 12345678901234567890123456789=3*3*3*7*13*31*37*211*241*2161*3607*3803*2906161

I can think of how to write the servlet to handle the queries, but how could I go about implementing a daemon / independently-running service in the same JVM?

edit: In the above example, what I would like to do is to have a background application that runs autonomously, with work queues, to factor prime numbers, and has a Java interface that supports the operations that the Tomcat servlets could use to expose the service to the web. Then I don't have to worry about the web interface or HTTP in my background app, and I don't have to worry about multithreading issues or prime factorization in my servlets.

+1  A: 

If you don't absolutely need to be in the same JVM (that is, if you don't need the performance of directly accessing the objects) you could write another Tomcat application and have your other apps communicate with it by HTTP to localhost. In effect you would be writing a web service that happens to run on the same machine. (I don't know how else multiple Tomcat applications can see each other. This is a problem that Enterprise Java Beans solves, but that may be too heavyweight a solution for you.)

If you have only a single Tomcat application that needs to do this, create a worker thread and put it in the application context where all the requests can communicate with it.

With regard to your specific problem, it looks like you are describing something like the Asynchronous Job pattern in the O'Reilly "Restful Web Services" book. This uses the "202 Accepted" status code to indicate that the processing is not complete. See "Asynchronous Operations" in Chapter 8 of the book.

http://www.amazon.com/RESTful-Web-Services-Leonard-Richardson/dp/0596529260/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1255555328&amp;sr=8-1

Mark Lutton
"application context"? is there a tutorial for this? I'm familiar enough with worker threads to know how to deal with most of the multithreading/concurrency aspects.
Jason S
Your servlet extends HttpServlet. HttpServlet.getServletContext() returns the ServletContext (or the "application scope") seen by all requests. ServletContext.setAttribute(String name, Object value) and ServletContext.getAttribute(String name) let you put anything you want there. A Java Server Pages tutorial probably has the most invormation about this.
Mark Lutton
oh, neat. that sounds about like what I want. Thanks!
Jason S