动态添加一个 webApp 到 Tomcat Embedded

问题描述

我需要了解为什么使用下面的代码向嵌入式 tomcat 动态添加 webapp 会出现以下错误,当我们在启动时添加 Context 时一切正常,代码是相同的。 代码

data

我们得到的错误是:

/*
 * Add a context to the host and contexts map; be careful to call this only
 * within a synchronization block of this.contexts
 */
private Context addContextDynamically(String contextpath,String folderName) {
    logger.info("Adding context " + contextpath + " at " + folderName);

    Context contextNew = this.embedded.addWebapp(this.host,contextpath,folderName);
    // Context contextNew = this.embedded.addContext(this.host,// folderName);
    // this.embedded.addContext(host,dir)
    // logger.info("contextNew-->"+contextNew);
    List<File> filterdJarfiles = getappjarFilesAlone(folderName);
    WebResourceRoot resources = new StandardRoot(contextNew);
    for (File jf : filterdJarfiles) {
        String st = jf.getAbsolutePath().substring(0,jf.getAbsolutePath().lastIndexOf(File.separator));
        logger.info("st-->"+st);
        resources.addPreResources(new DirResourceSet(resources,"/WEB-INF/lib",st,"/"));
    }
    logger.fine("Adding context setResources " + resources);
    logger.fine("Adding context contextNew "+ contextNew);
    logger.fine("Adding context filterdJarfiles " + filterdJarfiles.toString());
    try {
        contexts.put(contextNew.getPath(),contextNew);
        contextNew.setResources(resources);
        INexxWebappLoader loader = new INexxWebappLoader(contextNew.getParentClassLoader(),contextNew);
        contextNew.setLoader(loader);
        // host.addChild(context);
        cleanContextworkdir((StandardContext) contextNew);

    }catch (Exception e) {
        logger.info("Caught exception while adding context :"+ e.getLocalizedMessage());
        e.printstacktrace();
    }
    return contextNew;
}

所以基本上我们的产品会下载 zip 文件并将其解压缩到我们设置的 web 应用程序目录和 server.xml 中:

java.lang.IllegalStateException: Error starting static Resources
at org.apache.catalina.core.StandardContext.setResources(StandardContext.java:2470)
at com.medicity.iNexx.AppServer.addContextDynamically(AppServer.java:541)
at com.medicity.iNexx.AppServer.monitorEnablements(AppServer.java:439)
at com.medicity.iNexx.AppServer.run(AppServer.java:345)
at com.medicity.iNexx.AppServer.init(AppServer.java:244)
at com.medicity.iNexx.AppServer.main(AppServer.java:335)

解决方法

如果您将 Context 添加到正在运行的 Host,它将自动启动,除非 startChildren 组件上的属性 false 设置为 Host .您可能不希望这样,因为您的 addContextDynamically 需要先配置上下文。

因此在用于配置Tomcat的方法中需要调用:

final Host host = this.embedded.getHost()
if (host instanceof ContainerBase) {
    ((ContainerBase) host).setStartChildren(false);
}

并且您需要添加到 addContextDynamically

final State hostState = this.embedded.getHost().getState();
if (hostState.isAvailable() || LifecycleState.STARTING_PREP.equals(hostState)) {
    contextNew.start();
}

参见source code 了解更多信息。

备注:在 Host 开始之前添加的上下文不受 startChildren 属性的影响。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...