java – 使用ManagerServlet进行Tomcat多线程部署
我在tomcat中有30个WAR,它们之间存在依赖关系.所以我们有一个servlet来按顺序部署它们.现在我想先按顺序部署所需的应用程序,然后再并行部署它们.
我的代码如下所示. 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(); } } 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,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) 我无能为力,这里缺少什么,我在我的线程中使用相同的对象引用.如果有可能以多线程方式部署? 解决方法
这里的问题是你忘了初始化你的MyAsyncDeployer servlet.
您需要的是在构造之后(在启动线程之前)立即调用MyAsyncDeployer #init(ServletConfig config)方法. 对于串行情况,它可以工作,因为Tomcat在为init状态部署为javadoc之前初始化了您的servlet(MyDeployerServlet)本身:
但只要您不需要将异步servlet部署到容器中并且只需要使用其部署能力,就没有人为您实例化它. 固定版本的代码: if(count < serialContexts){ super.deploy(writer,sm); delpoyer.setWrapper(getWrapper()); deployer.init(getServletConfig()); Thread deployerThread = new Thread(deployer); deployerThread.start(); } } UPD:注意,你无法避免创建servlet(也就是在Runnable#run中调用this.deploy),因为ManagerServlet#deploy方法的线程安全性是通过完全同步保证的(整个方法是同步的),所以实际上这样的方法会也是连续的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |