简体   繁体   中英

Tomcat Multithreaded deployment using ManagerServlet

I have 30 WARs in tomcat and there is a dependency between them. So we have a servlet to deploy them sequentially. Now I want to deploy the required apps first sequentially and then rest of them in parallel.

My code is something like below.

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, context, contextName, null, false, sm);
            Thread deployerThread = new Thread(deployer);
            deployerThread.start();
        }
}

MyAsyncDeployer runnable code 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, context, null, false, sm);
    }

When I call this, serial deployment goes fine but the multithreaded deployments throw below exception.

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)

I am clueless what is missing here, I am using the same object references in my thread. If this is possible at all to deploy in multithreaded way?

The problem here is that you forgot to initialize your MyAsyncDeployer servlet. What you need is to call MyAsyncDeployer#init(ServletConfig config) method right after construction (before starting a thread). For serial case it works because Tomcat initialized your servlet ( MyDeployerServlet ) itself before deploying as javadoc for init states:

Called by the servlet container to indicate to a servlet that the servlet is being placed into service. See Servlet#init . This implementation stores the ServletConfig object it receives from the servlet container for later use. When overriding this form of the method, call super.init(config) .

But as long as you don't need to deploy you async servlet into container and only need to use its deploy ability, no one is instantiating it for you.

Fixed version of your code:

if(count < serialContexts){
            super.deploy(writer, context, contextName, null, false, sm);
            count++;
        } else {
            MyAsyncDeployer deployer = new MyAsyncDeployer(writer, context, contextName, null, false, sm);
            delpoyer.setWrapper(getWrapper());
            deployer.init(getServletConfig());
            Thread deployerThread = new Thread(deployer);
            deployerThread.start();
        }
}

UPD: Note, that you can't avoid creating servlet (aka having this.deploy call in Runnable#run ) because thread-safety of ManagerServlet#deploy method is guaranteed via total synchronization (the whole method is synchronized ), so in fact such approach will be serial as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM