【问题标题】:Adding a webApp to Tomcat Embedded dynamically将 webApp 动态添加到 Tomcat Embedded
【发布时间】:2021-06-29 14:54:28
【问题描述】:

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

/*
 * 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,contextPath,
    // folderName);
    // this.embedded.addContext(host, contextPath, 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;
}

我们得到的错误是:

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)

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

  <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">

【问题讨论】:

    标签: java tomcat8 embedded-tomcat-8


    【解决方案1】:

    如果将Context 添加到正在运行的Host,它将自动启动,除非Host 组件上的属性startChildren 设置为false。您可能不希望这样,因为您的 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 属性的影响。

    【讨论】:

    • ((ContainerBase) this.embedded.getHost()).setStartChildren(false); 是我的 Eclipse 允许我正确编写的内容。 tomcat Embedded 8.5.27是版本
    • 是的,你是对的,谢谢。我相应地修改了答案。
    猜你喜欢
    • 2016-04-11
    • 2013-12-02
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 2014-10-02
    • 2016-12-06
    相关资源
    最近更新 更多