[英]Abort Tomcat start-up
具体来说,我希望Tomcat在我的Web应用无法初始化(由于配置错误)时中止启动。
我试图使用Tomcat关闭端口。 当我的Web应用程序启动时,这还没有准备好。
-Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE = true,不起作用。 Tomcat启动正常。
引发未捕获的异常。 我尝试引发异常。 Tomcat仍然可以正确初始化,但是我的Web应用程序处于无法运行的状态。
使用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。 让侦听器将容器层次结构从服务器导航到上下文[Server-> Service(s)-> Engine-Host(s)-> Context(s)],并检查每个上下文是否处于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
将此侦听器注册到您的服务器组件:
<Server>
...
<Listener className="com.example.lifecycle.StrictStateCheckListener" />
...
</Server>
第一点:您的意思是当您从应用程序中抛出未初始化状态异常时,您正在调用tomcat shutdown.bat文件。您是否尝试过从程序中调用shutdown.bat文件。
我知道这个问题有点老了,但是在这里我要进一步思考,以寻求解决方案。 看来您的要求是在webapp初始化失败时停止tomcat。 这与“中止Tomcat启动”有所不同。 Tomcat本身已经启动,并且将在启动后立即开始部署您的Web应用程序。 根据您的要求,我假设您没有任何其他Webapp。 如果是这样,为什么不只使用Spring Boot? Spring Boot提供了一种部署自包含Web应用程序的方法。 在这种情况下,如果初始化失败,则应用程序将无法启动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.