中止Tomcat初创公司
具体来说,当我的Web应用程序无法初始化时(由于配置错误),我希望Tomcat中止启动。
-
我试图使用Tomcat关闭端口。 当我的网络应用程序启动时,这还没有准备好。
-
-Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE = true,不起作用。 Tomcat启动就好了。
-
抛出一个未被捕获的例外。 我试过抛出exception。 Tomcat仍然正确初始化,但我的Web应用程序处于非function状态。
-
使用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应用程序的方法。 在这种情况下,如果初始化失败,应用程序将无法启动。
- Spring BindingResult错误
- 第一次Java循环运行时,为什么?
- NoSuchMethodError:org.apache.http.conn.scheme.Scheme。(Ljava / lang / String; ILorg / apache / http / conn / scheme / SchemeSocketFactory;)V
- 使用reflection设置对象属性
- Java中是否存在基于8位字节数组的字符串类型?
- MongoDB从BasicDBObject(Java)中提取值
- Glassfish / Hibernate的PermGen空间问题
- 可以将一系列键映射到值的数据结构
- 如何在Servlet中读取文本文件和输出?