2016-04-29 20 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