Java – Tomcat multithreading deployment using managerservlet
I have 30 wars in tomcat, and there are dependencies between them So we have a servlet to deploy them sequentially Now I want to deploy the required applications in order, and then deploy them in parallel
My code is as follows
public class MyDeployerServlet extends ManagerServlet { ... public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException { ... if(count < serialContexts){ super.deploy(writer,context,contextName,null,false,sm); count++; } else { MyAsyncDeployer deployer = new MyAsyncDeployer(writer,sm); Thread deployerThread = new Thread(deployer); deployerThread.start(); } }
The runnable code of myasyncdeployer is:
public class MyAsyncDeployer extends MyDeployerServlet implements Runnable{ private PrintWriter writer; private String config; private ContextName context; private String war; private boolean update; private StringManager sm; public MyAsyncDeployer(PrintWriter writer,String config,ContextName context,String war,boolean update,StringManager sm) { this.writer = writer; this.config = config; this.context = context; this.war = war; this.update = update; this.sm = sm; } public void run() { super.deploy(writer,config,sm); }
When I call it this, serial deployment is fine, but multithreaded deployment throws exceptions
Exception in thread "Thread-9" java.lang.NullPointerException at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123) at javax.servlet.GenericServlet.log(GenericServlet.java:188) at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:834) at com.example.servlet.MyAsyncDeployer.run(MyAsyncDeployer.java:30) at java.lang.Thread.run(Thread.java:745) Exception in thread "Thread-10" java.lang.NullPointerException at javax.servlet.GenericServlet.getServletContext(GenericServlet.java:123) at javax.servlet.GenericServlet.log(GenericServlet.java:188) at org.apache.catalina.manager.ManagerServlet.deploy(ManagerServlet.java:834) at com.example.servlet.MyAsyncDeployer.run(MyAsyncDeployer.java:30) at java.lang.Thread.run(Thread.java:745)
There's nothing I can do. What's missing here? I use the same object reference in my thread If possible, multi-threaded deployment?
Solution
The problem here is that you forgot to initialize your myasyncdeployer servlet
But as long as you don't need to deploy an asynchronous servlet into a container and only need to use its deployment capabilities, no one instantiates it for you
Fixed version code:
if(count < serialContexts){ super.deploy(writer,sm); delpoyer.setWrapper(getWrapper()); deployer.init(getServletConfig()); Thread deployerThread = new Thread(deployer); deployerThread.start(); } }
UPD: notice that you can not avoid creating servlet (that is, calling this.deploy in Runnable#run), because the thread safety of ManagerServlet#deploy method is guaranteed by full synchronization (the whole method is synchronous), so in practice, such a method will be continuous.