加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 使用ManagerServlet进行Tomcat多线程部署

发布时间:2020-12-15 02:14:31 所属栏目:Java 来源:网络整理
导读:我在tomcat中有30个WAR,它们之间存在依赖关系.所以我们有一个servlet来按顺序部署它们.现在我想先按顺序部署所需的应用程序,然后再并行部署它们. 我的代码如下所示. public class MyDeployerServlet extends ManagerServlet {... public void doGet(HttpServ
我在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)本身:

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).

但只要您不需要将异步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方法的线程安全性是通过完全同步保证的(整个方法是同步的),所以实际上这样的方法会也是连续的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读