Запуск Java-демона с GWT-интерфейсом, обслуживаемым встроенным Jetty - PullRequest
3 голосов
/ 28 марта 2010

Привет, кодеры,

Справочная информация и код

Я пытаюсь создать программу типа демона (например, она работает постоянно, опрашивая, что делать), которая управляется приложением GWT (сервлеты в WAR), которое в свою очередь обслуживается встроенным сервером Jetty ( используя WebAppContext). У меня проблемы с уведомлением приложения GWT об объекте демона.

Для тестирования у меня есть два проекта: демон и встроенный сервер Jetty в одном (EmbJetTest) и приложение GWT в другом (DefaultApp). Это текущее состояние кода:

Сначала EmbJetTest создает такой встроенный сервер Jetty, используя ServletContextListener для внедрения объекта демона в контекст веб-приложения:

    EmbJetTest.server = new Server(8080);

    // Create and start the daemon
    Daemon daemon = new Daemon();
    Thread thread = new Thread(daemon);
    thread.start();

    // war handler
    WebAppContext waContext = new WebAppContext();
    waContext.setContextPath("/webapp");
    waContext.setWar("./apps/DefaultApp.war");
    waContext.addEventListener(new DaemonLoader(daemon));

    // Add it to the server
    EmbJetTest.server.setHandler(waContext);

    EmbJetTest.server.setThreadPool(new QueuedThreadPool(10));

    // Start the server; join() blocks until we shut down
    EmbJetTest.server.start();
    EmbJetTest.server.join();

    // Stop the daemon thread
    daemon.stopLoop();

Daemon на данный момент очень простой объект с парой свойств. DaemonLoader является следующей ServletContextListener реализацией:

private Daemon daemon;

public DaemonLoader(Daemon daemon)
{
    this.daemon = daemon;
}

@Override
public void contextDestroyed(ServletContextEvent arg0) {

}

@Override
public void contextInitialized(ServletContextEvent arg0) {
    arg0.getServletContext().setAttribute("daemon", this.daemon);
}

Затем в одном из моих сервлетов в приложении GWT у меня есть следующий код:

Daemon daemon = (Daemon) this.getServletContext().getAttribute("daemon");

Однако, когда я захожу на localhost: 8080 / webapp / * и вызываю сервлет, этот код выдает ClassCastException, хотя классы одного типа. Этот ответ StackOverflow указывает, что это происходит потому, что два класса загружены разными загрузчиками классов.

Вопрос

У меня двоякий вопрос.

  1. Я даже на правильном пути? Я поступаю об этом совершенно неправильно? Что-то подсказывает мне, но я не могу придумать другой способ сделать демон доступным для обоих приложений. Есть ли лучший способ связи с демоном из приложения GWT? Должно ли приложение GWT владеть демоном и каким-либо образом запускать сам демон? Демон должен работать, даже если никто не посещает один из сервлетов приложения GWT - как я могу это сделать?
  2. Если я нахожусь на правильном пути, как я могу обойти проблему с загрузчиком классов?

Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 28 марта 2010

Почему бы просто не запустить функциональность демона в отдельном потоке в веб-приложении GWT? Таким образом вы избежите всех проблем с загрузкой классов (как вы узнали, приложения в разных .war файлах запускаются в своих собственных загрузчиках классов).

Просто создайте сервлет для своего демона вместе с существующими сервлетами (в том же .war) и запустите / остановите поток при инициализации и уничтожении сервлета.

0 голосов
/ 28 марта 2010

Ну, на случай, если кому-то будет интересно, мне действительно удалось решить проблему с загрузчиком классов - первоначально я поместил скомпилированный Daemon.class в папку WEB-INF / classes приложения GWT. Я удалил этот файл, и теперь кажется, что приложение GWT использует класс Daemon из проекта EmbJetTest.

При этом, я думаю, ответ Брайана гораздо более примечательный. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...