Tomcat - сервлет init () вызывается дважды при запуске - PullRequest
4 голосов
/ 04 сентября 2011

У меня проблема с автономным сервером Tomcat (не связанным с Apache).

Когда Tomcat запускается, метод сервлета init () вызывается дважды, то есть запускаются два сервлета. Еще большее беспокойство вызывает то, что они загружаются разными загрузчиками классов - в командной строке выполняется только один Java-процесс, поэтому это не несколько Tomcats.

фрагмент web.xml (сервлет настраивается только один раз и настраивается только в webapp web.xml):

<servlet>
  <servlet-name>LenderInterfaceServlet</servlet-name>
  <display-name>Lender Interface Servlet</display-name>
  <servlet-class>com.foobar.lender.webservice.server.LenderInterfaceServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

Я поместил некоторые записи в метод init и создал одноэлементный класс RatesPoller, экземпляр которого init пытается получить. Из журналов видно, что экземпляры синглтона отличаются:

LenderInterfaceServlet - [init] Start: com.foobar.lender.webservice.server.LenderInterfaceServlet@56d90453
LenderInterfaceServlet - [init] Starting up the Rates pollers.
LenderInterfaceServlet - [init] Got com.foobar.lender.framework.rates.RatesPoller@ae0e515
LenderInterfaceServlet - [init] Start: com.foobar.lender.webservice.server.LenderInterfaceServlet@1b0c6cfc
LenderInterfaceServlet - [init] Starting up the Rates pollers.
LenderInterfaceServlet - [init] Got com.foobar.lender.framework.rates.RatesPoller@5759780d

Итак, у нас есть два сервлета distince и два отдельных одноэлементных поллера.

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

Если у кого-то есть идеи ...

Код:

public class RatesPoller {

  private static RatesPoller instance;

  private RatesPoller() {}

  public static RatesPoller getInstance() {
    if (instance == null) {
        instance = new RatesPoller();
    }
    return instance;
  }

  public RatesPoller clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException("Singleton. Tsk!");
  }
}

и метод init () в LenderInterfaceServlet:

public class LenderInterfaceServlet extends AxisServlet {
  // ...
  @Override
  public void init() throws ServletException {
    logger.info("[init] Start: " + this);
    super.init();
    logger.info("[init] Starting up the Rates pollers.");
    RatesPoller rp = RatesPoller.getInstance();
    logger.info("[init] Got " + rp);
  }
  // ...
}

Ответы [ 4 ]

4 голосов
/ 23 ноября 2011

Tomcat автоматически развертывает что-либо в веб-приложениях, а также развертывает в соответствии с server.xml. Просто удалите ваше веб-приложение из веб-приложений, чтобы избежать двойной загрузки.

1 голос
/ 07 февраля 2013

В вашем коде есть ошибка. Ваш синглтон не является потокобезопасным. Этот метод getInstance () должен быть синхронизирован. В противном случае вы обязаны создать несколько экземпляров.

0 голосов
/ 07 февраля 2013

Если метод init () завершается ошибкой, он может быть вызван снова при последующем получении. Вы проверяли файл catalina.out, чтобы убедиться, что вызов init () по какой-то причине не прерывается?

0 голосов
/ 05 сентября 2011

Я бы установил точку останова в методе init (), а затем посмотрел на стек, чтобы увидеть, откуда поступают вызовы.

...