中止Tomcat初创公司

问题描述 投票:2回答:4

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

  1. 我试图使用Tomcat关闭端口。当我的网络应用程序启动时,这还没有准备好。
  2. -Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE = true,不起作用。 Tomcat启动就好了。
  3. 抛出未被捕获的异常。我试过抛出异常。 Tomcat仍然正确初始化,但我的Web应用程序处于非功能状态。
  4. 使用Tomcat JMX API。没有任何关闭方法会导致Tomcat关闭。

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

java tomcat
4个回答
5
投票

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()。


1
投票

正如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>

0
投票

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.