2013-05-04 2 views
2

В частности, я хочу, чтобы Tomcat прекратил запуск, когда мое веб-приложение не может инициализироваться (из-за ошибки конфигурации).Abort Tomcat start-up

  1. Я пытаюсь использовать порт отключения Tomcat. Это не готово, когда мое веб-приложение запускается.

  2. -Dorg.apache.catalina.startup.EXIT_ON_INIT_FAILURE = true, не работает. Томкат начинает отлично.

  3. Бросьте неиспользуемое исключение. Я попытался сделать исключение. Tomcat все еще правильно инициализируется, но мое веб-приложение находится в нефункциональном состоянии.

  4. Используйте API Tomcat JMX. Ни один из методов отключения не приведет к отключению Tomcat.

Пока что у меня есть только другой вариант: System.exit(-1). Это действительно работает, но я обеспокоен тем, что для Tomcat это вызовет проблемы.

+2

контратип http://stackoverflow.com/q/13932746/422353? – madth3

+0

Нет, это не обман. Мое приложение не реализует ServletContextListener –

ответ

5

Tomcat предназначен для защиты от плохо написанных приложений, которые не запускаются.

org.apache.catalina.startup.EXIT_ON_INIT_FAILURE предназначен для остановки Tomcat, если один из компонентов Tomcat, например один из разъемов, не запускается (например, поскольку порт используется).

System.exit() является уродливым, но он будет работать, и он безопасен, насколько это касается Tomcat (так как это убивает -9). Это приложения, которым может не понравиться этот довольно жестокий подход к завершению работы.

Существует особый способ Tomcat сделать это более чисто. Добавьте пользовательский LifecycleListener к серверному компоненту и ответьте ему на AFTER_START_EVENT. Попросите слушателя перейти по иерархии контейнеров с сервера на Контексты [Server-> Service (s) -> Engine-Host (s) -> Контекст (ы)] и проверить, что каждый контекст находится в состоянии STARTED. Если нет, вызовите stop(), а затем destroy() на сервере.

+0

, который звучит так, как будто это может быть то, что я ищу! –

+0

Не могли бы вы привести пример? – sp00m

+0

@ sp00m, основанная на инструкциях, приведенных в этом ответе: https://gist.github.com/xkr47/9088839 - отлично работал как для «адреса, уже используемого», так и для отказа от запуска универсального веб-приложения –

0

Ваш вопрос № 1 Вы имеете в виду, когда исключительное исключение из инициализации выбрасывается из приложения, вы вызываете файл tomcat shutdown.bat. Вы пытались вызвать файл shutdown.bat из своей программы.

0

Я знаю, что этот вопрос немного устарел, но я собираюсь еще немного подумать, чтобы найти решение, которое вы ищете. Похоже, ваше требование состоит в том, чтобы остановить tomcat, когда ваш webapp не сможет инициализировать. Это немного отличается от «прекращения запуска Tomcat». Сам Tomcat уже запущен и начнет развертывать ваш webapp сразу после его запуска. Исходя из вашего требования, я предполагаю, что у вас нет другого webapp. Если это так, почему бы вам просто не использовать Spring Boot? Spring boot обеспечивает способ развертывания автономного веб-приложения. В этом случае при сбое инициализации приложение не запускается.

0

Вот реализация слушателя, который прерывает запуск 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> 
Смежные вопросы