Продолжается подписка на наши издания! Вы не забыли подписаться?

Знакомство с IBM WebSphere Community Edition

Автор: Александр Цимбал
Опубликовано: 17.04.2007

Итак, с лета прошлого года IBM включилась в борьбу на рынке J2EE-серверов с открытым кодом. Впрочем, большого резонанса это тогда не вызвало, так как объявленный под названием Gluecode продукт не был полноценным J2EE-сервером – по сути, это был «расширенный» вариант Tomcat’а. Что касается полноценной версии J2EE-сервера, который сейчас называется Web Sphere Community Edition (WAS CE), то его первая версия стала доступной для загрузки с сайта IBM (http://www.ibm.com/developerworks/downloads/ws/wasce/?S_TACT=105AGX28&S_CMP=DLMAIN) в январе 2006 г.

WAS CE является «близнецом» J2EE-сервера с открытым кодом, создаваемого в рамках консорциума Apache, который называется Geronimo. Отличиями между WAS CE и Geronimo при первом знакомстве с этими продуктами можно пренебречь.

Общие сведения

Формально WAS CE – это очередной J2EE-сервер, сертифицированный на соответствие спецификациям J2EE версии 1.4 (список сертифицированных серверов можно получить по адресу http://java.sun.com/j2ee/compatibility.html). Даже то, что он поставляется вместе с исходным кодом и бесплатно, не является уникальной особенностью – разработчики давно имеют возможность использовать JBoss и JOnAS (JOnAS является основой Red Hat Application Server, RHAS), которые в этом плане – сертификация, бесплатность и доступность исходного кода – ничем не отличаются от WAS CE. Для всех трех серверов осуществляется платная техническая поддержка, и они имеют примерно одинаковые – во всяком случае, вполне сопоставимые – параметры с точки зрения производительности.

Возникает вопрос, почему IBM пошла на этот шаг, и что может получить сообщество разработчиков вследствие появления нового продукта от IBM?

WAS CE отличается от своих конкурентов следующим:

J2EE-сервер, подобно всем другим решениям, относящимся к классу middleware, определяет инфраструктуру информационной системы, т.е. наиболее фундаментальную часть ее архитектуры. Это означает, что выбор J2EE-сервера – очень ответственное решение, которое во многом определит особенности поведения системы в течение долгого времени – как минимум, нескольких лет. Конечно, можно говорить о высоком уровне независимости приложений (на уровне их кода) от конкретной реализации J2EE-сервера, и это действительно так. Тем не менее, каждый из серверов, представленных сегодня в этом сегменте программных решений, имеет свои особенности, которые архитекторы прикладной системы будут принимать во внимание. Другими словами, замена для существующей информационной системы одной J2EE-реализации на другую – на практике процесс долгий, непростой и дорогостоящий. Это, разумеется, не относится к небольшим и простым прикладным системам.

Все это означает, что для потребителя основанного на технологии J2EE решения очень важно быть уверенным, что за используемым программным продуктом – реализацией J2EE-сервера – стоит серьезная компания, которая имеет и возможности, и намерения обеспечивать качественную поддержку и развитие своего продукта в течение долгого времени. IBM есть IBM, и этот аспект действительно важен для многих потенциальных пользователей.

Вторая составляющая потенциального успеха продукта (на который надеется IBM) в конкурентной борьбе с JBoss – это то, что WAS CE входит в семейство серверов приложений WebSphere.

Дело здесь в том, что технология J2EE хорошо подходит для очень широкого круга задач, но эти задачи существенно отличаются по сложности, размерам, предъявляемым к ним критериям оценки. Не надо забывать, что решения этих задач привлекаются совершенно различные ресурсы – это касается не только денег, но и требований к аппаратному обеспечению, времени на реализацию, качеству и количеству привлекаемых специалистов.

Бесплатные сервера с открытым исходным кодом – по крайней мере, в настоящее время и в обозримом будущем – очень сильно уступают своим коммерческим конкурентам по показателям максимальной производительности, масштабируемости, надежности. В этом нет ничего страшного – эти open-source продукты создавались для решения некоторого подмножества задач. Это прекрасные инструменты для обучения специалистов и быстрого создания сравнительно небольших информационных систем (уровень малого и среднего бизнеса – в западном понимании этих терминов). Но если такой продукт не связан тесным образом с более продвинутыми решениями, то в нем неизбежно появляются:

В результате продукт теряет простоту и «легкость», все равно не достигая при этом характеристик своих коммерческих конкурентов.

Эта проблема неактуальна для WAS CE. Его тесная (в ближайшем будущем) интеграция с другими серверами семейства WebSphere позволит использовать стандартные и хорошо работающие возможности этого продукта для небольших задач, а в случае необходимости быстро и легко переносить код на более мощные серверы приложений в рамках одной линейки продуктов.

Наконец, важным аспектом является интеграция сервера с инструментами разработки. Хотя такая интеграция формально является не более чем удобством, она позволяет чрезвычайно сильно сократить время на разработку и повысить производительность труда. IBM – одна из очень небольшого числа компаний, предлагающих продукты для всех этапов цикла жизни приложений, поэтому применение WAS CE гарантирует удобство и быстроту создания программ с его использованием.

Итак, если совсем кратко: IBM предлагает не изолированное решение (подобно JBoss), а элемент комплексной системы разработки, развертывания и контроля самых различных J2EE-приложений.

Технологическая основа

WAS CE построен по технологии, впервые использованной для разработки J2EE-сервера приложений с открытым кодом в проекте Geronimo (Apache Software Foundation). В основу проекта была положена компонентная модель GBeans, реализующая концепцию Inversion of Control (IoC). Часто вместо IoC используется термин «dependency injection», что можно перевести как «включение зависимостей». Для грамотного использования продуктов, построенных на этой основе, необходимо понимать основы этой концепции и компонентной модели GBeans.

Компонентная модель Gbeans

Среда GBeans универсальна, и она никак не связана с J2EE. Как и любая компонентная модель, она включает в себя «Контейнер», т.е. среду управления циклом жизни компонентов (она называется Geronimo Kernel), и собственно компоненты. Компоненты GBeans имеют следующие основные особенности:

«Поля состояния» компонента можно разделить на две группы – атрибуты и связи.

Таким образом, система строится только из GBeans-компонентов. Эти компоненты взаимодействуют друг с другом не непосредственно, а посредством ядра Geronimo. Связи между компонентами, называемые «зависимостями» (dependencies), прописываются на уровне XML-описаний компонентов, которые во многих компонентных моделях, например, EJB, обычно называются «дескрипторами развертывания» (deployment descriptors), а в модели GBeans – «планами развертывания» (deployment plans). Ядро Geronimo, анализируя планы, «узнаёт» о связях компонентов друг с другом и может генерировать динамические proxy-объекты, обеспечивающие связь компонентов, и автоматически в момент создания экземпляра компонента добавлять ссылки на этот компонент во все компоненты, зависящие от данного.

В процессе установки компоненты, логически связанные друг с другом, объединяются в конфигурации. Для кода компонентов, входящих в конфигурацию, выполняется процесс сериализации, и такая сериализованная конфигурация записывается в специально предназначенный для этого каталог. После этого для запуска конфигурации сериализованное представление конфигурации нужно просто загрузить. Для того чтобы компонент GBeans можно было найти, с ним сопоставляется уникальное имя. Регистрация имен и их поиск выполняются с использованием стандартных возможностей JMX.

Чтобы понять, каким именно образом определяются связи между компонентами, удобно рассмотреть план развертывания для конфигурации, состоящей из нескольких компонентов GBeans. В качестве примера возьмем дескриптор стандартной конфигурации System из состава WAS CE:

<configuration
  xmlns="http://geronimo.apache.org/xml/ns/deployment-1.0"
  configId="org/apache/geronimo/System"
  domain="geronimo.server"
  server="geronimo"
>

  <!-- ServerInfo service -->
  <gbean name="ServerInfo"
    class="org.apache.geronimo.system.serverinfo.BasicServerInfo"/>

    <!-- Logging service -->
    <gbean name="Logger"
      class="org.apache.geronimo.system.logging.log4j.Log4jService">
        <attribute name="configFileName">
          var/log/server-log4j.properties
        </attribute>
        <attribute name="refreshPeriodSeconds">60</attribute>
        <reference name="ServerInfo"><name>ServerInfo</name></reference>
    </gbean>

    <!-- Configuration Manager service -->
    <gbean name="ConfigurationManager" 
      class="org.apache.geronimo.kernel.config.ConfigurationManagerImpl">
      <reference name="Stores">
        <gbean-name>*:j2eeType=ConfigurationStore,*</gbean-name>
      </reference>
    </gbean>

        <!-- Repository -->
    <gbean name="Repository" 
      class="org.apache.geronimo.system.repository.ReadOnlyRepository">
        <attribute name="root">repository/</attribute>
        <reference name="ServerInfo"><name>ServerInfo</name></reference>
    </gbean>
    ...
</configuration>

Каждая конфигурация имеет уникальное имя, которое указывается в теге <configId>. Конфигурация в приведенном примере называется System.

В случае «чистого» компонента GBeans его план развертывания содержит всю необходимую на уровне конфигурации информацию. В проектах Geronimo и WAS CE такие компоненты используются очень широко. Например, таким GBeans-компонентом является реализация сервера JMS или координатора объектных транзакций.

Для развертывания GBeans-компонента опять-таки создается план развертывания, например:

<deployment xmlns=http://geronimo.apache.org/xml/ns/deployment
  configId="Scheduler”>
  <dependency>
    <uri>scheduler/jars/scheduler-1.5.jar</uri> 
    </dependency>
  <gbean name="geronimo.server:type=Scheduler"
    class="com.example.SchedulerGBean">
    <attribute name="configDB" type="java.lang.String">
      MySchedulerDatabase
    </attribute>
  </gbean>  
</deployment

Если же рассматривать EJB-компоненты или Web-компоненты, то соответствующие им GBeans-компоненты генерируются на основе кода и дескрипторов, уже существующих для этих сущностей, и план развертывания для GBeans-компонента содержит только дополнительную информацию. Таким образом, при использовании стандартных J2EE-сущностей план развертывания очень удобно трактовать как специфический для реализации J2EE-контейнера дескриптор развертывания, хорошо знакомый всем программистам, имеющим опыт работы с J2EE-серверами (необходимость такого рода дополнительных дескрипторов связана с тем, что спецификации J2EE-дескрипторов просто не оговаривают все необходимые параметры для EJB-компонентов, сервлетов или JSP-документов). Соответственно, планы развертывания будут в чем-то похожи на обычные дескрипторы развертывания для таких J2EE-сущностей, как приложение J2EE (тег <application>), клиентское приложение J2EE (тег <client-application>), web-приложение (тег <web-app>), EJB-компонент (<ejb-jar>) или ресурсный адаптер (тег <connector>). Процедура развертывания таких GBeans-компонентов похожа на процедуру развертывания соответствующих J2EE-элементов.

Существует два вида зависимостей конфигураций и компонентов друг от друга – явная и неявная. Явная (explicit) зависимость задается с помощью тега <parentId>:

<web-app xmlns=http://geronimo.apache.org/xml/ns/web
  configId="MyWebApplication"
  parentId="MyDatabasePool">
  ...

Здесь MyDatabasePool – глобальное имя конфигурации, код компонентов которой необходим для правильной работы описываемого данным дескриптором web-приложения.

Неявные зависимости задаются с помощью ссылок на внешние ресурсы, и соответствующие средства Geronimo узнают о них, анализируя код дескриптора, например:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/web"
  xmlns:naming="http://geronimo.apache.org/xml/ns/naming"
  configId="MyOtherWebApplication"
>
  <context-root>/my_app</context-root>
  <context-priority-classloader>false</context-priority-classloader>

  <naming:resource-ref>
    <naming:ref-name>jdbc/MyDataSource</naming:ref-name>
    <naming:resource-link>SystemDatasource</naming:resource-link>
  </naming:resource-ref>

</web-app> 

Из текста плана видно, что данная конфигурация зависит от ресурса с именем SystemDatasource. Параметры ресурса (в данном случае фабрики соединений JDBC 2) прописаны в стандартном дескрипторе для web-приложения.

Во многих случаях при создании J2EE-приложений можно избежать как явного, так и неявного задания зависимостей, оформив приложения в виде единого EAR-архива с соответствующими стандартным (с тегом <аpplication>) дескриптором, а также дополнительным дескриптором (планом) Geronimo (тег <geronimo-application>).

Иерархия конфигураций и загрузчиков классов

Основной смысл создания иерархии конфигураций в Geronimo – это управление порядком загрузки классов.

Приложения или отдельные модули (т.е. то, что перечисляется в списке модулей в стандартном дескрипторе для J2EE-приложения) образуют отдельные конфигурации, формирующие иерархию за счет явных зависимостей между ними. В Geronimo для каждой конфигурации (кроме случая, когда EAR-архив содержит Web-модуль) используется свой ClassLoader. В книге Малдера «Разработка и развертывание приложений для Apache Geronimo», которая должна выйти в следующем году, приводится следующая диаграмма, показывающая порядок загрузки классов J2EE-приложения в Geronimo (рисунок 1).


Рисунок 1.

Те загрузчики классов, которые работают с сущностями, находящимися в затененных прямоугольниках, создаются Geronimo.

WAS CE и Geronimo

В настоящий момент разработчик может выбрать один из двух очень похожих друг на друга продуктов, созданных на общей технологической базе – Geronimo и WebSphere Application Server Community Edition. Оба бесплатны, оба с открытым кодом, оба обеспечены технической поддержкой IBM – правда, разного уровня.

Проект Geronimo

Работа в рамках проекта Geronimo началась в конце 2003 г. В проекте было широко задействованы созданные к тому времени продукты с открытым кодом. Наиболее важными из них являются следующие:

Перед появлением в декабре 2005 версии 1.0, было выпущено 5 промежуточных версий (milestones) , последняя из которых (1.0-M5) была объявлена 1 ноября 2005 года. M5 – первая версия, прошедшая сертификацию на соответствие спецификации J2EE 1.4. Получить Geronimo можно c сайта www.apache.org.

С проектом Geronimo связаны все достоинства и недостатки проектов, создаваемых данным сообществом разработчиков. С одной стороны, в проект непрерывно добавляются новые возможности, обеспечивается поддержка новых технологий, выпускаются plug-in’ы для средств разработки, обеспечивающие удобную совместную работу. Кроме того, сообщество Geronimo обеспечивает информационную поддержку проекта, характерную для разработок с открытым кодом. Этот подход полностью устраивает разработчиков, пока они изучают возможности продукта и заняты созданием кода, в том числе кода своих приложений. Ситуация меняется, когда возникает необходимость развертывания своих приложений (в том числе коммерческих) для своих заказчиков, особенно на долговременной основе, на различных платформах и с использованием различных баз данных.

WAS CE

Компания IBM является активным участником проекта Geronimo. Вместе с тем, существуют пользователи серверов приложений J2EE, которые нуждаются (или заинтересованы) в систематической поддержке используемых ими программных решений со стороны крупных и надежных производителей ПО.

Нужно учесть еще одно обстоятельство – IBM уже несколько лет предлагает мощную коммерческую реализацию J2EE-сервера – WebSphere. Это продукт, который требует для работы серьезных вычислительных ресурсов и финансовых вложений.

Вследствие всего этого, IBM, продолжая участвовать в проектe Geronimo, решила развивать (на основе и в тесной кооперации с Geronimo) свою собственную версию, несколько отличающуюся от версии консорциума.

Продукт IBM поддерживается на несколько большем числе программных и аппаратных платформ, имеет улучшенную поддержку различных СУБД и сертифицирован с использованием JDK как от Sun, так и от IBM. В ближайшее время (ориентировочно в апреле 2006 г.) должна появиться русскоязычная версия сервера. Главное же отличие состоит в политике лицензирования и поддержки. Пользователь получает поддержку WAS CE на коммерческой основе, и эта поддержка более систематическая, комплексная, гибкая и развитая, нежели поддержка Geronimo.

Поддержка WAS CE

WAS CE в настоящий может выполняться под управлением следующих операционных систем (на 32-битных процессорах Intel):

На этих платформах требуется минимум 120 Mb дискового пространства (не считая JDK) и не менее 128 Mb RAM (желательно 256 Mb).

Поддерживаются JDK 1.4.2 от Sun и IBM.

Предусмотрено 3 уровня технической поддержки (по сравнению с двумя уровнями поддержки IBM для Geronimo) – Entry, Enhanced и Elite. Во всех случаях договор заключается на год. Цены на них указываются из расчета на сервер, а не на 1 процессор сервера (для серверов с числом CPU не более 4). Основные отличия между различными уровнями связаны с доступностью (рабочие дни и часы для Entry и Enhanced, круглосуточно и без выходных для Elite), временем отклика (8 часов для Entry, 4 – для Enhanced и 2 – для Elite), а также максимальным числом возможных технических контактов (1 – для Entry, 2 – для Enhanced и неограниченно – для Elite).

Серьезная поддержка разработчиков с точки зрения возможности получения консультаций экспертов предусмотрена на двух старших уровнях.

С точки зрения доступа к информации, отслеживания ошибок реализаций и предоставления обновлений и исправлений все три уровня равнозначны.

Полную информацию о поддерживаемых аппаратных платформах и условиях технической поддержки можно получить по адресам:

Лицензионная политика

Политика лицензирования применительно к продукту с открытым исходным кодом – важная часть стратегии продвижения этого продукта. Детальное изучение лицензионного соглашения лучше доверить юристам – здесь имеет смысл затронуть только самые основные аспекты. JBoss, Geronimo и WAS CE используют различные лицензионные соглашения.

Для JBoss используется лицензия LGPL (Lesser General Public License). Применительно к Java это означает, что продукты, созданные на основе открытого кода JBoss, также должны поставляться с исходным кодом и соответствовать требованиям LGPL. Правда, здесь юристы могут долго обсуждать, что понимается под продуктом, созданным на основе JBoss, и где проходит грань между «созданием продукта на основе» и просто «его использованием».

Geronimo распространяется на условиях лицензии Apache (http://geronimo.apache.org/license.html). Эта лицензия позволяет делать пользователю продукта практически все, что угодно, требуя от него соблюдения самых минимальных требований – например, включения в собственный продукт, созданный на основе Geronimo, копии лицензионного соглашения Apache, явных указаний о внесенных в исходный продукт изменениях и сохранения сообщений об авторских правах, торговых марках и т.д. Лицензия Apache не имеет географических и временных ограничений и не может быть отозвана. Разработчик продукта на основе Apache Geronimo может для своего продукта устанавливать собственные правила лицензирования.

Для WAS CE используется отдельное лицензионное соглашение. Оно тоже на практике не накладывает на пользователя и разработчика серьезных ограничений – в частности, позволяет на основе WAS CE создавать свои программы и определять для них правила лицензирования. Тем не менее, лицензия жестко сопоставлена с каждым экземпляром и копией программы, при передаче программы пользователь передает вместе с ней и лицензию на нее, теряя права пользования (до получения новой лицензии, разумеется). IBM вправе отозвать лицензию при нарушении пользователем лицензионного соглашения. Вообще, IBM не продает WAS CE, а предоставляет потребителю права пользования ею. При юридически грамотном использовании программы нужно аккуратно соблюдать некоторые условия, не связанные с необходимостью за что-то платить.

Лицензии бесплатные – деньги нужно платить только в случае, если возникает необходимость или желание получить техническую поддержку. Только техническая поддержка оказывается на коммерческой основе.

Запуск и настройка WAS CE

WAS CE и Geronimo могут поставляться (в бинарном формате, а не в виде исходного кода) как в форме дистрибутива, так и обычного архива. Во втором случае архив нужно просто распаковать в выбранный каталог (каталог установки). Выбор одного из двух поддерживаемых вариантов JDK – от IBM или от Sun – остается на усмотрение пользователя.

После установки в указанном каталоге создается подкаталог bin, который содержит исполняемый код сервера (файл server.jar), средства для развертывания приложений (deploy.jar), утилиты для запуска клиентских приложений в формате J2EE (client.jar) и остановки сервера (shutdown.jar), а также командные файлы для платформ Linux и Windows.

Для запуска WAS CE используются командные файлы startup.bat (для Windows) и startup.sh (для Linux), которые выполняют некоторые проверки и вызывают общий командный файл geronimo.bat (geronimo.sh), который выполняет проверки и настройки системных переменных, и запускает сервер в нужном режиме.

В каталоге /bin могут находиться вспомогательные командные файлы, позволяющие настроить значения системных переменных – setenv.bat(sh) и setjavaenv.bat(sh). Скрипт geronimo.bat(sh) проверяет наличие этих вспомогательных файлов в оговоренном месте и, если они найдены, вызывает их – сначала setenv, затем setjavaenv.

Так или иначе, для запуска сервера используются значения следующих основных системных переменных:

При установке WAS CE 1.0 в каталог <install_dir>/bin помещаются файлы setenv.bat(sh) и setjavaenv.bat(sh), и именно они определяют значения переменных среды, переопределяя значения, заданные пользователем на уровне ОС. Это позволяет настраивать некоторые аспекты поведения сервера независимо от значений «общих» переменных среды (например, той же JAVA_HOME).

Поскольку сервер представляет собой набор сериализованных конфигураций, состоящих из GBeans-компонентов (имеющих атрибуты), то поведение сервера можно менять при каждом запуске, изменяя набор конфигураций или задавая различные значения атрибутов компонентов. Список конфигураций и значения атрибутов их компонентов хранятся в файле %GERONIMO_HOME%/var/config/config.xml. Пользователь может менять содержимое этого файла – либо явно, с помощью любого текстового редактора (сервер при этом не должен быть запущен), либо неявно, устанавливая те или иные компоненты с помощью утилиты deploy или работая с консолью администратора.

Изменение атрибутов компонентов в файле config.xml – самый удобный способ менять настройки сервера, например, номера портов, которые используются при работе тех или иных сервисов WAS CE.

В процессе запуска сервер выводит на окно своей текстовой консоли сообщения о загружаемых конфигурациях:


Рисунок 2.

В списке запущенных конфигураций, показанном на рисунке 2, последние две конфигурации созданы пользователем, остальные – стандартные конфигурации WAS CE/Geronimo.

На экране появляется также список сервисов вместе с некоторыми их параметрами, список модулей в том смысле, которое понятие «модуль» имеет в технологии J2EE, а также готовые URL установленных web-приложений:


Рисунок 3.

Сервер приложений готов к работе.

Утилита развертывания компонентов

Для управления конфигурациями сервера используется утилита deploy (загрузчик).

Загрузчик используется для выполнения различных действий, основными из которых являются:

В терминах J2EE под «конфигурацией» часто понимается то, что обычно называют «модулем».

Список и описание команд можно получить с помощью следующей командной строки:

java –jar deployer help [команда]

или просто выполнив командный файл /bin/deploy.bat(sh) без указания параметров.

Для выполнения большинства команд загрузчика необходимо указывать имя пользователя и пароль. По умолчанию используются следующие значения:

user=system
password=manager

Если эти параметры не указаны в командной строке, то они будут запрошены в интерактивном режиме. Для указания этих параметров в командной строке используйте следующие опции:

java –jar deployer –user имя_пользователя –password пароль

Состав групп пользователей и параметры пользователей находятся в файлах groups.properties и users.properties, соответственно, которые размещены в каталоге <install_dir>/var/security.

Команды могут выполняться по-разному – в зависимости от того, запущен сервер или нет. В большинстве случаев требуется, чтобы сервер был запущен.

В общем случае требуется указать сервер, в котором развертывается модуль (или модули), модуль (по его глобальному имени) и план развертывания модуля, если он необходим.

Во многих случаях для выгрузки, запуска и установки модулей удобнее использовать консоль администратора.

Консоль WAS CE

Для управления сервером в процессе работы и управления конфигурациями используется консоль администратора. Консоль является серверным приложением. Она реализована с использованием портлетов, и ее визуальный интерфейс доступен с использованием стандартных Internet-броузеров, сервлетов и протокола http. Для начала работы с консолью нужно в броузере задать следующую строку:

http://<хост>:8080/console

Для доступа к функциональности консоли нужно ввести идентификатор и пароль. Сервер поставляется с готовым вариантом реализации системы безопасности, в том числе процедуры аутентификации, и с «администратором» по умолчанию, идентификатор которого «system», а пароль – «manager».

Начальная страница консоли администратора показана на рисунке 4.


Рисунок 4.

Структура каталогов WAS CE

В процессе установки WAS CE/Geronimo на диске в выбранном каталоге установки создаются следующие наиболее важные подкаталоги:

Примеры создания, развертывания и использования приложений

В качестве простейшего примера лучше всего использовать JSP-документ – это позволяет для демонстрации использования сервера задействовать (помимо средств, входящих в состав WAS CE) только текстовый редактор. Хотя краткость примера производит благоприятное впечатление, полезной информации он дает немного, поэтому в данной статье будут приведены два примера – один с использованием простейшего JSP, второй – более сложный, в рамках которого будет создаваться session EJB-компонент и сервлет, обращающийся к этому компоненту с использованием локальных интерфейсов и формирующий ответ в виде HTML-документа. Приложение будет создано в виде EAR-архива J2EE. В качестве клиента выступает стандартный броузер.

Более подробное рассмотрение вопросов создания web-приложений и EJB-компонентов, работа с базами данных, использование JMS и JMX, создание Java-клиентских приложений, вопросы обеспечения безопасности в WAS CE будут рассмотрены в последующих статьях.

Простейшие web-приложение

Поскольку приложение должно быть простейшим, то, в соответствие со сложившейся (и поросшей мхом традиции) и с упорством, достойным, возможно, лучшего применения, будем в ответ на общение к серверу отображать на экране броузера строку «Hello World!». Строка не хуже любой другой, так что не все так плохо в принципиальном консерватизме.

Для создания такого приложения нужно:

<html>
  <body>
    <h2>Hello World!</h2>
  </body>
</html>
<!DOCTYPE web-app PUBLIC
  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
  "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
</web-app>

Приложение готово. Осталось запустить сервер и выполнить команду установки WAR-архива – т.е. web-приложения – на этот сервер. Команда может выглядить следующим образом (в одну строку):

java -jar D:\AppServerCommunityEdition\bin\deployer.jar --user system --password manager deploy my_first_webapp.war

Теперь можно обратиться к этому web-приложению, задав в броузере следующий URL:

http://localhost:8080/my_first_webapp

В данном случае созданное web-приложение получило имя по имени архива. URL не содержит имени самого JSP-документа, так как его имя – index.jsp – используется по умолчанию.

Пример приложения в виде EAR

Создаваемое приложение позволит складывать два целых числа и отображать результат в окне броузера. Функциональность не слишком интересная, но в этом приложении присутствует два слоя, характерные для «настоящих» J2EE-приложений – слой бизнес-логики (реализуемый с помощью session EJB-компонента) и слой презентационной логики, реализуемой с помощью сервлета, хотя и в простейшем варианте.

Начнем с создания EJB-компонента. При создании реальных приложений разработчики EJB-компонентов всегда используют программные инструменты, которые генерируют большую часть кода и дескрипторов компонентов. Обычно программист определяет прикладные бизнес-методы в классе компонента и делает их доступными для клиентов с помощью component-интерфейсов (локального и удаленного). Спецификация EJB 3.0 делает этот процесс еще более прозрачным и простым для разработчика, хотя суть остается той же самой.

Создаваемый компонент (session stateless-компонент) будет содержать оба вида component-интерфейсов – как локальные, так и удаленные. Локальные интерфейсы будут использованы в данном примере, удаленные – в примере, который показывает, как можно обратиться к EJB-компоненту из удаленного Java-приложения.

Код компонента выглядит так:

package ear_application.ejb;
public class MySSSSession   implements javax.ejb.SessionBean 
{
  public void ejbCreate () {}
  public void ejbActivate() {}
  public void ejbPassivate() {}
  public void setSessionContext(javax.ejb.SessionContext ctx) {}
  public void unsetSessionContext() {}
  public void ejbRemove() {}
  
  public int summa (int op1, int op2) { return op1 + op2; }
}
package ear_application.ejb;
public interface MySSSLocalHome   extends javax.ejb.EJBLocalHome
{
  public MySSSLocal create()  throws javax.ejb.CreateException;
}
package ear_application.ejb;
public interface MySSSLocal extends javax.ejb.EJBLocalObject
{  
  public int summa (int op1, int op2);
}
package ear_application.ejb;
public interface MySSSHome extends javax.ejb.EJBHome
{
  public MySSS create()
    throws javax.ejb.CreateException, java.rmi.RemoteException;
}
package ear_application.ejb;
public interface MySSS extends javax.ejb.EJBObject
{
public int summa (int op1, int op2)
  throws java.rmi.RemoteException;
}
<?xml version="1.0" encoding="UTF-8"?>

<ejb-jar  xmlns=http://java.sun.com/xml/ns/j2ee
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
  http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">

  <display-name>session_bean_project</display-name>
  <enterprise-beans>
    <session >
      <display-name>MySSS</display-name>
      <ejb-name>MySSS</ejb-name>
      <home>ear_application.ejb.MySSSHome</home>
      <remote>ear_application.ejb.MySSS</remote>
      <local-home>ear_application.ejb.MySSSLocalHome</local-home>
      <local>ear_application.ejb.MySSSLocal</local>
      <ejb-class>ear_application.ejb.MySSSSession</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
      </session>
  </enterprise-beans>
</ejb-jar>
<?xml version="1.0" encoding="ASCII"?>
<openejb-jar xmlns="http://www.openejb.org/xml/ns/openejb-jar-2.0"
  xmlns:naming="http://geronimo.apache.org/xml/ns/naming"
      xmlns:security="http://geronimo.apache.org/xml/ns/security"
      xmlns:sys="http://geronimo.apache.org/xml/ns/deployment"
  configId="ear_application/jar_config">
  <enterprise-beans>
    <session>
      <ejb-name>MySSS</ejb-name>
      <jndi-name>ejb/MySSS</jndi-name>
      <local-jndi-name>java:comp/env/ejb/MySSSLocal</local-jndi-name>
    </session>
  </enterprise-beans>
</openejb-jar>

На плане развертывания нашего компонента следует остановиться подробнее. В его дескрипторе заслуживают внимания два параметра. Первый из них – идентификатор конфигурации Geronimo, создаваемой для этого EJB-компонента (атрибут configId). Это значение понадобится нам при создании плана развертывания для web-компонента (сервлета), который будет обращаться к этому EJB-компоненту.

Второй важный параметр – тег <session>. Он позволяет указать для нашего компонента имена, под которыми ссылки на его локальный и удаленный home-интерфейсы будут опубликованы в службе имен JNDI.

Теперь нужно откомпилировать java-код компонента и создать архив с расширением .jar – например, beans.jar – который будет содержать:

Команды для выполнения этих действий могут выглядеть так:

set BC="."
set BC="%BC%;D:\AppServerCommunityEdition\repository\geronimo-spec\jars\geronimo-spec-j2ee-1.4-rc4.jar;"
javac -classpath %BC% ear_application\ejb\*.java

jar -cvf beans.jar .\META-INF\*.* .\ear_application\ejb\*.class

В принципе, созданный архив, содержащий EJB-компонент, можно было бы установить в контейнер EJB-компонентов (входящий в состав WAS CE) в качестве отдельного приложения, но в данном случае гораздо удобнее создавать приложение в виде EAR-архива, поэтому перейдем к созданию web-части нашего примера.

Web-приложение будет состоять из одного web-компонента, а именно, сервлета. Получив запроса от клиента, сервлет начинает сеанс работы с EJB-сервером – создает экземпляр session-компонента. Для этого необходимо предварительно получить объектную ссылку на фабрику таких компонентов – home-интерфейс, для чего используется JNDI. Поскольку ссылку на home-интерфейс при каждом вызове – дело слишком дорогостоящее, используются различные подходы, позволяющие получить эту ссылку через JNDI только один раз. Например, можно кэшировать значение объектной ссылки в специально созданной для этого переменной, и реально обращаться к JNDI только в случае, если эта переменная еще не получила соответствующего значения. В данном примере применяется другой способ: сервлет получает объектную ссылку на home-интерфейс компонента в момент своей инициализации web-контейнером.

В процессе сеанса использования session-компонента сервлет вызывает бизнес-метод этого компонента и тут же завершает сеанс, уничтожая созданный экземпляр EJB-компонента. Поскольку используются локальные интерфейсы (работа происходит под управлением одной виртуальной машины Java), все действия выполняются очень быстро.

Код сервлета (файл MyServlet.java) может выглядеть так:

package ear_application.web;

import javax.naming.*;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

import ear_application.ejb.*;

 public class MyServlet extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

  // Локальный контекст JNDI (“java:comp/env”)
  private Context init_env_context = null;  

  // Объектная ссылка на home-интерфейс
  private MySSSLocalHome local_home = null;

  // Объекная ссылка на component-интерфейс
  private MySSSLocal local_comp = null; 
  
  public MyServlet() { super(); } 
  
  public void destroy() {  super.destroy(); }     

  protected void doGet(HttpServletRequest request, HttpServletResponse response) 
    throws ServletException, IOException 
    {
      response.setContentType("text/html");
      PrintWriter out = response.getWriter();
      
      int sum = 0;
      try 
      {
        String opString = request.getParameter("op1");
        int op1 = Integer.parseInt (opString);

        opString = request.getParameter("op2");
        int op2 = Integer.parseInt (opString);
        
        local_comp = local_home.create();
        sum = local_comp.summa (op1, op2);
        local_comp.remove();
      } 
      catch (NumberFormatException e) 
      {
        ...
      }
      catch (java.lang.Exception e)
      {
    ...
      }
      out.println ("<html><head><title>");
      if (local_home != null)
        out.println ("JNDI Init: Success");
      else
        out.println ("JNDI Init: Failure");
      out.println ("</title></head><body>");
      out.println ("Summa = " + sum);      
      out.println ("</body></html>");
  }
  
  public void init() throws ServletException 
  {
    super.init();  
    try 
    {
      Context init_context = new InitialContext();
      init_env_context  = 
        (Context)init_context.lookup("java:comp/env");
      local_home = (MySSSLocalHome) init_env_context.lookup("ejb/MySSSLocal");

    } 
    catch(java.lang.Exception e) 
    {
      e.printStackTrace();
    }
  }   
}

Для создания web-компонента необходимы еще и xml-дескрипторы.

Стандартный дескриптор J2EE для нашего web-компонента (файл web.xml) выглядит так:

<?xml version="1.0" encoding="UTF-8"?>

<web-app  xmlns="http://java.sun.com/xml/ns/j2ee" 
  xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<distributable/>

  <servlet>
    <description><![CDATA[This is description of my servet]]></description>
    <display-name>MyServlet</display-name>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>ear_application.web.MyServlet</servlet-class>

    <init-param>
      <description><![CDATA[First operand]]></description>
      <param-name>op1</param-name>
      <param-value>1</param-value>
    </init-param>
    <init-param>
      <description><![CDATA[Second operand]]></description>
      <param-name>op2</param-name>
      <param-value>2</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/MyServlet</url-pattern>
  </servlet-mapping>

  <ejb-local-ref>
    <ejb-ref-name>ejb/MySSSLocal</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local-home>ear_application.ejb.MySSSLocalHome</local-home>
    <local>ear_application.ejb.MySSSLocal</local>
    <ejb-link>MySSS</ejb-link>
  </ejb-local-ref>
</web-app>

План развертывания для создаваемого компонента тоже важен для данного примера, хотя он и не содержит дополнительной информации с точки зрения J2EE. Дополнительный дескриптор (файл geronimo-web.xml) влияет на процесс загрузки классов. При этом возникают два вопроса:

  1. Как обеспечить, чтобы к моменту использования сервлета код EJB-компонента, к которому обращается сервлет, был уже загружен?
  2. Что использовать для загрузки сервлета: собственный загрузчик классов (что соответствует спецификации) или один из ранее созданных и используемых загрузчиков?

Первая проблема решается путем задания на уровне плана развертывания фрагмента иерархии конфигураций – указания родительской конфигурации и конфигурации для web-компонента. Для этого используются атрибуты configId и parentId:

<?xml version="1.0" encoding="ASCII"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.0" 
  configId="ear_application/web_config"
  parentId="ear_application/jar_config">
  
  <context-root>/ear_application</context-root>
    <context-priority-classloader>false</context-priority-classloader>
</web-app>

Обратите внимание, что в качестве имени «родительской» конфигурации указано имя конфигурации созданного ранее EJB-компонента. Такой подход гарантирует нужную последовательность загрузки конфигураций.

План развертывания в нашем примере содержит, помимо заголовка, еще два обязательных тега: тег <context-root> определяет имя web-приложения, а тег <context-priority-classloader> – схему использования загрузчиков классов. Значение false говорит, что контейнер должен попытаться сначала использовать загрузчик сервера и «родительских» классов в иерархии конфигураций, и только потом – загрузчик для web-приложения.

Далее необходимо откомпилировать код сервлета и создать архив с расширением .war (например, servlets.war), в корневом каталоге которого ничего нет, в а подкаталоге WEB-INF содержатся xml-файлы дескрипторов. Сам байт-код для сервлета и локальных интерфейсов EJB-компонента находятся, соответственно, в подкаталогах WEB-INF/classes/ear_application/web и WEB-INF/classes/ear_application/ejb, соответственно.

Осталось создать EAR-архив и развернуть его на сервере. Это будет архив с расширением .ear (например, ear_app.ear), который содержит ранее созданные модули (beans.jar и servlets.war), а также два xml-дескриптора в каталоге META-INF – application.xml и geronimo-application.xml. В некоторых случаях может потребоваться также наличие в этом же каталоге файла манифеста (manifest.mf), но в данном примере файл манифеста не нужен.

Стандартный дескриптор приложения содержит список модулей, входящих в приложение:

<?xml version="1.0" encoding="UTF-8"?>
<application id="Application_ID" version="1.4" 
  xmlns="http://java.sun.com/xml/ns/j2ee" 
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance 
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd">
  
<display-name>ear_application</display-name>

  <module>
    <ejb>beans.jar</ejb>
  </module>
  <module>
    <web>
      <web-uri>servlets.war</web-uri>
      <context-root>/ear_application</context-root>
    </web>
  </module>
</application>   

План развертывания Geronimo в этом примере не содержит ничего, кроме заголовка, который определяет имя создаваемой для EAR-приложения конфигурации:

<?xml version="1.0" encoding="ASCII"?>
<application 
  xmlns="http://geronimo.apache.org/xml/ns/j2ee/application-1.0" 
  application-name="ear_application" 
  configId="ear_application/ear_application"/>

Для установки и запуска приложения выполните следующую команду (при работающем сервере WAS CE):

java -jar "<каталог_установки>\bin\deployer.jar" --user system --password manager deploy ear_app.ear

Для выполнения сложения двух целых чисел можно в броузере задать следующий URL:

http://localhost:8080/ear_application/MyServlet?op1=2&op2=3

Заключение

WAS CE является простой в использовании, но достаточно мощной и полностью соответствующей спецификации средой развертывания и выполнения J2EE-приложений, которая прекрасно подходит как для изучения комплекса технологий J2EE, так и для создания реальных информационных систем в интересах малого и среднего бизнеса.


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.

Copyright © 1994-2016 ООО "К-Пресс"