Can anyone advise here? I have a situation where users will submit data mining requests interactively via a Java JSP and servlet to an application of mine which will dynamically work out association rules on data and more.
As such a job may take a while, I'm thinking of some sort of process on the server to run such a request in the background so it dosen't 'lock' the session and possibly use massive amounts of server memory to the detriment of the system.
As the system is made up of a series of Java JSPs and servlets running in a Tomcat container over a MySQL database, can anyone advise a way forward?
Thanks
Mr Morgan
To run java program automatically on tomcat startup, need to use Servlet and this Servlet initialized on tomcat startup automatically. To execute a program, you have to use Servlet and Servlet should define in deployment descriptor web. xml file under WEB-INF folder. web.
The Maven pom. xml contains dependencies for the embedded Tomcat server and the assembler plugin, which builds the application. Dependencies for JSP container are not included in this application, since we only have a servlet. The EmbeddedTomcatEx is a Java console application, which includes an embedded Tomcat server.
Use an ExecutorService.
There's a few things you should do though, mark the thread as a daemon thread so it atleast won't tie up tomcat in error scenarios, and you should stop the executor when your servlet context is destroyed (e.g. when you redeploy or stop your application. To do this, use a ServletContextListener:
public class ExecutorContextListener implements ServletContextListener { private ExecutorService executor; public void contextInitialized(ServletContextEvent arg0) { ServletContext context = arg0.getServletContext(); int nr_executors = 1; ThreadFactory daemonFactory = new DaemonThreadFactory(); try { nr_executors = Integer.parseInt(context.getInitParameter("nr-executors")); } catch (NumberFormatException ignore ) {} if(nr_executors <= 1) { executor = Executors.newSingleThreadExecutor(daemonFactory); } else { executor = Executors.newFixedThreadPool(nr_executors,daemonFactory); } context.setAttribute("MY_EXECUTOR", executor); } public void contextDestroyed(ServletContextEvent arg0) { ServletContext context = arg0.getServletContext(); executor.shutdownNow(); // or process/wait until all pending jobs are done } } import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; /** * Hands out threads from the wrapped threadfactory with setDeamon(true), so the * threads won't keep the JVM alive when it should otherwise exit. */ public class DaemonThreadFactory implements ThreadFactory { private final ThreadFactory factory; /** * Construct a ThreadFactory with setDeamon(true) using * Executors.defaultThreadFactory() */ public DaemonThreadFactory() { this(Executors.defaultThreadFactory()); } /** * Construct a ThreadFactory with setDeamon(true) wrapping the given factory * * @param thread * factory to wrap */ public DaemonThreadFactory(ThreadFactory factory) { if (factory == null) throw new NullPointerException("factory cannot be null"); this.factory = factory; } public Thread newThread(Runnable r) { final Thread t = factory.newThread(r); t.setDaemon(true); return t; } }
You'll have to add the context listener to your web.xml, where you also can specify the number of threads you'll want to run the background jobs:
<listener> <listener-class>com.example.ExecutorContextListener</listener-class> </listener>
You can access the executor from your servlet and submit jobs to it:
ExecutorService executor = (ExecutorService )getServletContext().getAttribute("MY_EXECUTOR"); ... executor.submit(myJob);
If you're using Spring, all this can probably be made even simpler
I think Quartz scheduler should be able to accomplish what you want to do here. Here are some of the examples from Quartz. Using this, you can start a cron that rapidly polls to process the incoming request(s). I actually did that for one of my projects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With