Embedded fever

Рубрика: Java | 26 May 2008, 08:46 | juriy

Не все веб приложения одинаковые: одни большие, даже монстроидные: работают на кластерах веб-серверов и общаются с ордами баз данных и сервисов. Другие поменьше и поскромнее – работают, как правило на одном выделенном сервере, иногда ненавязчиво беседуя с сервером баз данных. Есть еще и третьи – совсем маленькие странички, которые выполняют очень узкий круг задач и обслуживают небольшое количество пользователей: они зачастую запущены на той же машине что и СУБД.

В этой заметке я уделю внимание третьему типу приложений – совсем маленьким системам. Их функционал ограничен небольшим набором вспомогательных функций, которые, к примеру, могут поддерживать основное приложение. Давайте на секунду представим, что нам потребовалось написать такое приложение. Какие будут первые действия? Конечно, установка Tomcat и MySQL. Вам не кажется неправильным, что ради запуска пары сервлетов вам нужно установить две достаточно больших и тяжеловесных системы? Что уж говорить о поставке такого “монстра” пользователям.

В этой заметке я покажу как быстро создать приложение с встроенным веб сервером и СУБД. Для начала нужно скачать 2 продукта: HSQLDB (как ясно из названия, это сервер баз данных) и Jetty (веб-сервер). Обе системы обладают невероятно полезным свойством: их легко запустить в режиме in-process: то есть в той же виртуальной машине, что и основное приложение. Для работы нам потребуется 4 jar файла: hsqldb.jar, jetty-xxxx.jar, jetty-util-xxxx.jar и servlet-api-2.5-xxxx.jar. Вместо xxxx в названиях архивов будет указана версия jetty.

Код для запуска прост настолько, что я не смог придумать, как еще его можно прокомментировать:

import org.mortbay.jetty.Connector;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.webapp.WebAppContext;

public class Main {
  public static void main(String[] args) {
    org.hsqldb.Server databaseServer = new org.hsqldb.Server();

    databaseServer.setDatabaseName(0, "xdb");
    databaseServer.setDatabasePath(0, "../data/mydb");
    databaseServer.setLogWriter(null);
    databaseServer.setErrWriter(null);
    databaseServer.start();
    System.out.println("HSQLDB started");

    new Thread(new Runnable() {
      public void run() {
        org.mortbay.jetty.Server webServer = new org.mortbay.jetty.Server();

        Connector connector = new SelectChannelConnector();
        connector.setPort(8080);
        webServer.setConnectors(new Connector[] { connector });

        WebAppContext webapp = new WebAppContext();
        webapp.setContextPath("/");
        webapp.setWar("../webapp/yourapp.war");

        webServer.setHandler(webapp);

        try {
          webServer.start();
          webServer.join();
        } catch (Exception e) {
          System.out.println("Problems while starting jetty");
          e.printStackTrace();
        }
      }
    }).start();
    System.out.println("Done");
  }
}

Суммарный размер библиотек составляет меньше полутора мегабайт. Приложение запускается в одной виртуальной машине и уже содердит веб-сервер и СУБД. Что может быть проще?

Комментариев: 9

9 Responses to “Embedded fever”

Комментарии:

  1. wheleph

    Замечание насчет использования Jetty.
    На самом деле не достаточно просто включить jetty-xxx.jar и jetty-util-xxx.jar. В это случае он не способен обрабатывать jsp и tld.
    Вопрос обсуждался тут:
    http://forum.jug.com.ua/index.php?showtopic=1625
    и тут
    http://forum.jug.com.ua/index.php?showtopic=1852

  2. juriy

    Да, в таком формате jetty работает только с сервлетами. Я в качестве “движка” для страниц использовал freemarker. Jetty этим и хорош – можно подключать только то, что реально необходимо.

  3. Farcaller

    Что касается последнего вопроса – я бы ответил “python+sqlite”. Но это оффтопик :)

  4. Vadim Voituk

    Farcaller: только ты забыл упомянуть о том, что кроме голого Python+SQLite прийдется ещё тянуть как-минимум какой-то WebFramework со встроенным HTTP-сервером.

  5. Andrey

    А томкат разве с сервлетами не в одном процессе запускается? То есть в приведенном примере просто поменялась очередность запуска — в класическом подходе сервлет контейнер запускает приложение, а здесь наоборот. Ну а по поводу хиперсоник, то не разумнее работать с ним через связку HSQL JDBC Driver -> Data Source что в будущем легко позволит при необходимости сменить вендора БД?
    Да, кстати питон уже содержит встроенный хттп сервер в стандартных библиотеках.

  6. wheleph

    Кстати, сегодня исследовал систему функционального тестирования web-приложений Selenium (http://selenium.openqa.org/). Одним из ее компонентов есть proxy-сервер, который как раз построен на основе Jetty:

    C:\bin\selenium-remote-control-1.0-beta-1\selenium-server-1.0-beta-1>java -jar selenium-server.jar
    14:14:20.793 INFO – Java: Sun Microsystems Inc. 1.5.0_08-b03
    14:14:20.824 INFO – OS: Windows XP 5.1 x86
    14:14:20.824 INFO – v1.0-beta-1 [2201], with Core v1.0-beta-1 [1994]
    14:14:21.277 INFO – Version Jetty/5.1.x
    14:14:21.277 INFO – Started HttpContext[/,/]
    14:14:21.277 INFO – Started HttpContext[/selenium-server,/selenium-server]
    14:14:21.277 INFO – Started HttpContext[/selenium-server/driver,/selenium-server/driver]
    14:14:21.434 INFO – Started SocketListener on 0.0.0.0:4444
    14:14:21.434 INFO – Started org.mortbay.jetty.Server@12ac982

  7. Vadim Voituk

    Если уж на то пошло, но Jetty встроен в огромное количество приложений. К примеру в Grails :)

  8. Smudgy

    2 Andrey: Опять же, для легковесного приложения ты предлагаешь взять томкот и законфигурировать подключение к БД. Автор предлагает быстрое решение и в принципе его вариант даже очень хороший.

Leave a Reply