中止Tomcat初创公司

具体来说,当我的Web应用程序无法初始化时(由于配置错误),我希望Tomcat中止启动。

  1. 我试图使用Tomcat关闭端口。 当我的网络应用程序启动时,这还没有准备好。

  2. -Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE = true,不起作用。 Tomcat启动就好了。

  3. 抛出一个未被捕获的例外。 我试过抛出exception。 Tomcat仍然正确初始化,但我的Web应用程序处于非function状态。

  4. 使用Tomcat JMX API。 没有任何关闭方法会导致Tomcat关闭。

到目前为止,我唯一的另一个选择是System.exit(-1) 。 这确实有效,但我担心对Tomcat这样做会导致问题。

Tomcat旨在对不能启动的编写错误的应用程序具有弹性。

org.apache.catalina.startup.EXIT_ON_INIT_FAILURE用于在Tomcat的某个组件(例如其中一个连接器)未启动时停止Tomcat(例如,因为端口正在使用中)。

System.exit()是丑陋的,但它会起作用,就Tomcat来说它是安全的(至于kill -9)。 应用程序可能不喜欢这种相当残酷的关闭方法。

有一种Tomcat特定的方法可以更干净地完成这项工作。 将自定义LifecycleListener添加到服务器组件并让它响应AFTER_START_EVENT。 让侦听器将Container层次结构从服务器导航到上下文[服务器 – >服务 – >引擎 – 主机 – >上下文],并检查每个上下文是否处于STARTED状态。 如果没有,请在服务器上调用stop()然后destroy()。

正如Mark Thomas所提到的,这是一个中断Tomcat启动的监听器实现。 StrictStateCheckListener是一个启动后服务器侦听器。 它检查所有Container的状态,包括引擎,主机和上下文。 如果任何组件无法启动(状态与STARTED不同),服务器启动将中止。

 package com.example.lifecycle; import java.util.logging.*; import org.apache.catalina.*; public class StrictStateCheckListener implements LifecycleListener { private static final Logger LOGGER = Logger.getLogger(StrictStateCheckListener.class.getName()); private boolean hasFailures; private String containerState; @Override public void lifecycleEvent(LifecycleEvent event) { String type = event.getType(); Lifecycle lifecycle = event.getLifecycle(); if (lifecycle instanceof Server && type.equals(Lifecycle.AFTER_START_EVENT)) { Server server = (Server) lifecycle; hasFailures = false; // Check status of each container StringBuilder sb = new StringBuilder("Status:").append(System.lineSeparator()); for (Service service : server.findServices()) { checkState(service.getContainer(), sb, ""); } if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info(sb.toString()); } if (hasFailures) { /* * The server will not be stopped by this listener. Indeed, * an exception is raised to trigger shutdown hook. See: * `org.apache.catalina.startup.Catalina`. */ throw new IllegalStateException(containerState); } } } private void checkState(Container container, StringBuilder report, String indent) { if (!hasFailures && container.getState() != LifecycleState.STARTED) { hasFailures = true; containerState = stateOf(container); } report.append(indent).append(stateOf(container)); for (Container child : container.findChildren()) { checkState(child, report, indent + " "); } } private String stateOf(Container container) { String className = container.getClass().getSimpleName(); String stateName = container.getStateName(); return String.format("%s[%s]: %s%n", className, container.getName(), stateName); } } 

通过server.xml将此侦听器注册到您的服务器组件:

  ...  ...  

你的观点1你的意思是你从调用tomcat shutdown.bat文件的应用程序抛出未初始化的状态exception。你试图从程序中调用shutdown.bat文件。

我知道这个问题有点陈旧,但我会在这里进一步思考开箱即用的解决方案。 看起来您的要求是在Webapp无法初始化时停止tomcat。 这与“中止Tomcat启动”有点不同。 Tomcat本身已经启动,并将在启动后立即开始部​​署您的webapp。 根据您的要求,我假设您没有任何其他Web应用程序。 如果是这样的话,你为什么不只使用Spring Boot? Spring引导提供了一种部署自包含Web应用程序的方法。 在这种情况下,如果初始化失败,应用程序将无法启动。