2016-04-29 55 views
4

我在tomcat中有30个WAR,它们之间存在依赖关系。所以我们有一个servlet按顺序部署它们。现在我想先按顺序部署所需的应用程序,然后再并行地部署它们。Tomcat使用ManagerServlet的多线程部署

我的代码如下所示。

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运行的代码是:

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); 
    } 

当我打电话,串行部署去罚款,但多线程部署抛出异常下面。

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) 

我很无能什么是在这里失踪,我在我的线程中使用相同的对象引用。如果这可以在多线程的方式进行部署?

+0

我也打开任何其他方法,这个想法是部署前几个上下文,然后并行休息。 – Pankaj

+0

什么类型的依赖关系(jar ...) –

+0

@Pankaj我已经更新了我的答案,你可以再试一次吗? – qwwdfsad

回答

0

这里的问题是您忘记初始化您的MyAsyncDeployer servlet。 您需要的是在施工后(在启动线程之前)立即调用MyAsyncDeployer#init(ServletConfig config)方法。 对于串行情况下,它的作品,因为Tomcat的初始化你的servlet(MyDeployerServlet)本身的javadoc init状态在部署之前:

由servlet容器调用来指示该servlet的 正被放入服务的servlet。 See Servlet#init。 此实现存储ServletConfig对象,它从servlet容器中收到 供以后使用。当覆盖这种形式的 该方法时,请致电super.init(config)

但是,只要您不需要将异步servlet部署到容器中,只需要使用其部署功能,就没有人为您实例化它。

代码的修正版本:

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: 注意,你不能避免创建的servlet(又名具有Runnable#runthis.deploy通话),因为ManagerServlet#deploy方法的线程安全性是通过保证总同步(整个方法是​​),所以实际上这种方法也是连续的。

+0

我正在获取init调用的错误。 2016年5月12日下午10时40分51秒org.apache.catalina.core.StandardWrapperValve调用 SEVERE:在路径[/ deployer]上下文中,Servlet [Deployer]的Servlet.service()抛出异常 javax.servlet。UnavailableException:Container尚未为此Servlet调用setWrapper() \t at org.apache.catalina.manager.ManagerServlet.init(ManagerServlet.java:453) \t at javax.servlet.GenericServlet.init(GenericServlet.java:158)调用setWrapper()方法后,它的工作方式为 – Pankaj

+0

。 – Pankaj