Подключение приложения Java Swing к серверу Geronimo

Создайте автономное клиентское приложение, способное общаться с EJB-приложением Geronimo

В двух предыдущих статьях developerWorks (смотрите раздел "Ресурсы"), автор Нил Санче использовал простое приложение phonebook для демонстрации того, как подключить сервер приложений Apache Geronimo к базе данных и как использовать Geronimo для создания основанного на Struts Web-приложения, использующего технологию Enterprise Java™Beans (EJB). В этой статье приложение phonebook развивается на шаг дальше, чтобы продемонстрировать, как можно создать автономное клиентское приложение для управления базой данных телефонных номеров. Вы также узнаете, как настроить Geronimo, разрешив безопасный доступ конкретных клиентов.

Нил Санче, Java-разработчик, Pure Technologies

authorНил Санче (Neal Sanche) является Java-разработчиком, примкнувшим к Microsoft® .NET и пытающимся не терять связи со своими старыми предпочтениями. Он имеет опыт разработки нескольких коммерческих J2EE-приложений, а также нескольких автономных Java-приложений. В свободное время он сочиняет музыку, занимается фотографией и пишет технические статьи. Вы можете найти несколько примеров на его Web-сайте. С Нилом можно связаться по адресу neal@nsdev.org.



26.07.2005

Введение

В этой статье будет рассмотрен процесс создания автономного ("толстого") клиентского приложения, способного взаимодействовать с EJB-приложением, выполняющимся внутри сервера приложений Geronimo. В двух моих предыдущих статьях, "Три способа подключения базы данных к серверу приложений Geronimo" (developerWorks, июнь 2005) и "Погружение в EJB Web-приложения с Geronimo" (developerWorks, июль 2005), было рассмотрено основанное на Swing клиентское приложение, которое подключалось к небольшой базе данных телефонных номеров при помощи EJB-приложения Geronimo. Вы прочитаете краткое описание дизайна и информацию о приложениях библиотек, необходимых для запуска. Затем я объясню методологию подключения к серверу и выполнения операций на удаленном сессионном компоненте, расположенном на сервере. В завершение вы узнаете, как разрабатывать, компилировать и запускать клиентское приложение и как настроить сервер для разрешения защищенного доступа конкретных клиентов в вашей сети.

Для лучшего усвоения этой статьи вы должны быть знакомы с Java Swing API для создания настольных Java-приложений и с системой компоновки Apache Maven (ссылка на Web-сайт Maven приведена в разделе "Ресурсы").


Обзор дизайна

Начнем с рассмотрения дизайна простого приложения - UML-диаграммы развертывания, описывающей клиентское приложение phonebook. Диаграмма показана на рисунке 1. Клиентское приложение подключается к Geronimo через его EJB-порт и передает сессионному EJB-компоненту PhoneBook команды управления данными в базе данных через компонент PhoneBook Entry Container-Managed Persistence (CMP) Bean.

Рисунок 1. Диаграмма развертывания клиентского приложения Phonebook
Диаграмма развертывания клиентского приложения Phonebook

Дистрибутивы Geronimo по умолчанию имеют ограничение для EJB-порта. Вы можете подключиться к этому порту только в том случае, если ваше клиентское приложение выполняется на той же самой машине и подключается через loopback-адрес (localhost или 127.0.0.1). В приведенном в данной статье разделе "Настройка EJB-порта Geronimo" детально рассмотрено, как разрешить клиентам обращаться к серверу с других машин.


Клиентские библиотеки для подключения к Geronimo

Для того чтобы ваше клиентское приложение было способно подключаться к EJB-порту Geronimo и взаимодействовать с EJB-уровнем, в вашем classpath должны быть записаны следующие Java-библиотеки:

  • geronimo-spec-j2ee-1.4-rc4.jar
  • geronimo-kernel-1.0-SNAPSHOT.jar
  • geronimo-j2ee-1.0-SNAPSHOT.jar
  • geronimo-security-1.0-SNAPSHOT.jar
  • cglib-nodep-2.1.jar
  • openejb-core-2.0-SNAPSHOT.jar

Замечание по структуре компоновки

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

Если вы компилируете Geronimo из исходных файлов, то эти библиотеки размещаются в вашем локальном репозитории Maven и доступны при использовании сценариев компоновки Maven для компилирования клиентского приложения phonebook. Вы можете просмотреть секцию зависимостей файла project.xml и увидеть, что все эти библиотеки расположены в репозитории Maven.

Некоторые из этих библиотек играют важную роль во взаимодействии между клиентом и сервером. Geronimo использует библиотеку CGLib для генерирования динамического прокси. Это дает возможность серверу генерировать код, вызывающий серверные компоненты удаленно, "на лету". Если вы находитесь в отладчике и исследуете один из объектов, возвращаемых клиенту из метода lookup() объекта InitialContext, вы сможете увидеть, что динамически сгенерированное название класса объекта содержит CGLib. Файл geronimo-spec-j2ee.jar содержит все классы и интерфейсы Sun Java 2 Platform, Enterprise Edition (J2EE). Без этого файла клиентское приложение не сможет понять ни один экземпляр динамического прокси. Файл openejb-core.jar необходим для общения с EJB-портом сервера. В этом .jar-файле находятся классы Java Naming and Directory Interface (JNDI), предназначенные для выполнения удаленного просмотра каталогов на сервере Geronimo. Последние три .jar-файла предоставляют другие вспомогательные классы, например, элементы системы безопасности, для общения с Geronimo.


Просмотр домашнего каталога удаленной сессии

Реализация клиентской части взаимодействия является традиционной. Geronimo не отличается от любого другого сервера J2EE, когда дело касается подключения клиента к серверу, следуя хорошо зарекомендовавшим себя стандартам взаимодействия через JNDI-поиск и удаленный вызов метода (remote method invocation, RMI). JNDI-поиск является стандартным способом получения ссылок на удаленные объекты. Чтобы выполнить подключение через JNDI, вы должны использовать несколько специфичных для Geronimo свойств для создания экземпляра InitialContext, который затем используется для выполнения поиска. В листинге 1 приведен пример создания сессии.

Листинг 1. Создание удаленной сессии с размещенным на Geronimo сессионным компонентом
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

public void Connect() {
      String hostName = getHostName();
      String port = getPort();

      Properties props = new Properties();

      props.setProperty("java.naming.factory.initial",
                  "org.openejb.client.RemoteInitialContextFactory");
      props.setProperty("java.naming.provider.url", hostName+":"+port);
      props.setProperty("java.naming.security.principal", "username");
      props.setProperty("java.naming.security.credentials", "passwd");

      Context ic;
      try {
            ic = new InitialContext(props);
            PhoneBookSessionHome sessionHome = (PhoneBookSessionHome)
                  PortableRemoteObject.narrow(
                  ic.lookup(PhoneBookSessionHome.JNDI_NAME),
                  PhoneBookSessionHome.class);
            phoneBookSession = sessionHome.create();
      } catch (Throwable ex) {
            ex.printStackTrace();
      } finally {
            if (ic != null) {
                  ic.close();
            }
      }
}

Как показано в листинге 1, вы создаете объект Properties и устанавливаете четыре свойства. Первым и самым важным является свойство java.naming.factory.initial, которое должно быть установлено в org.openejb.client.RemoteInitialContextFactory. Остальные свойства указывают URL провайдера, элемент системы безопасности и полномочия. URL провайдера - это имя хоста и порт, разделенные двоеточием.

Как уже упоминалось, EJB-порт в настоящее время принимает соединения только от клиентов, подключающихся к 127.0.0.1 или localhost. Порт по умолчанию равен 4201. Однако имя хоста и порт могут быть настроены. Детали вы найдете в разделе "Настройка EJB-порта Geronimo".

После создания свойств можно приступить к созданию экземпляра InitialContext и его использованию. Сделайте это путем передачи свойств в конструктор. После получения экземпляра вы можете осуществить поиск. Листинг 1 содержит завершенную строку кода, выполняющую поиск, и метод PortableRemoteObject.narrow() с результатом. Это необходимо сделать для сокрытия многих деталей о транспортном протоколе (RMI или, возможно, Internet Inter-ORB Protocol (IIOP)) от пользователя. После всего этого удаленная сессия готова к использованию. В листинге 1 эта строка просто создает новый PhoneBookSession и сохраняет его для дальнейшего использования.

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


Дизайн и разработка клиентского приложения

Теперь вы готовы погрузиться в дизайн и разработку небольшого Swing-приложения для просмотра, создания, удаления и изменения записей базы данных телефонных контактов. Я постараюсь как можно меньше употреблять Swing-жаргон на случай того, если вы больше знакомы с другой GUI-технологией, например Standard Widget Toolkit (SWT). Фактически, архитектура приложения облегчает отделение отображения от внутренней логики приложения и позволяет при необходимости переключиться на другую GUI-технологию.

Архитектура приложения изображена на рисунке 2 в виде UML-диаграммы классов, детально показывая статическую структуру приложения.

Рисунок 2. UML-диаграмма классов клиентского приложения
UML-диаграмма классов клиентского приложения

Классы, изображенные на рисунке 2 зеленым цветом, являются главными классами приложения. Класс Main представляет собой фрейм, содержащий меню и разделенную панель, левой частью которой является PhoneNumberListPanel, а правой - PhoneBookEditorPanel. Меню дает пользователям возможность выбрать сервер для подключения, подключиться к серверу и выйти из программы. Класс Application является единственным классом, выступающим в качестве контроллера для всех операций приложения. Он является единственным классом, в котором выполняются EJB-операции, и хранит ссылку на не сохраняющий состояния сессионный компонент PhoneBookSession.

Два интерфейса, показанные оранжевым цветом, определяют главные события в системе. DataChangeEvent вызывается тогда, когда Application решит, что список телефонных номеров нужно обновить. PhoneNumberListModel регистрирует это событие. Поскольку в PhoneNumberListPanel находится главный вид списка в модели данных, этот список обновляется при изменениях модели. Именно так Swing-приложение и должно быть спроектировано.

Оба класса, PhoneNumberListPanel и PhoneBookEditorPanel, реализуют интерфейсы PhoneBookSelectionListener и регистрируются на события от Application. При получении события они обновляют свои текущие элементы соответствующим образом. Для PhoneBookEditorPanel текущий элемент вызывает заполнение полей Name и Number данными текущей записи базы данных телефонных номеров.

Если вы захотите сберечь время при написании кода пользовательского интерфейса, то всегда можете найти высококачественные, свободно распространяемые инструментальные средства в Интернете. Одним из отличных примеров является JGoodies Forms 1.0.5 и небольшая программа для визуального создания форм под названием FormLayoutMaker (ссылки на эти программы приведены в разделе "Ресурсы"). Программа FormLayoutMaker генерирует XML-файлы, которые содержат уточнения схемы для форм JGoodies. Эти программы помогли мне быстро создать формы для панели "Phone Number editor" и панели "Preferences".


Компоновка приложения

Существует два способа компилирования приложения. Я разрабатывал приложение в Eclipse, используя подключаемый модуль Eclipse Visual Editor (VE) версии 1.2. Он генерирует большую часть исходного кода приложения, но делает это безвредным способом (не помечает код и не затрагивает блоки кода), поэтому вы не должны беспокоиться, если у вас VE не установлен. Вы можете просто загрузить проект и попробовать запустить его.

Вам может понадобиться настроить вашу переменную компоновки MAVEN_REPO, указывающую на локальный репозиторий Maven. Также нужно скомпоновать сервер Geronimo и серверное приложение PhoneBook, включенное в прилагаемый к данной статье исходный код (смотрите раздел "Загрузка"). Причина этого заключается в том, что для компиляции клиентского приложения, .jar-файл, содержащий EJB-интерфейсы из серверного приложения, должен быть опубликован в вашем локальном репозитории Maven. Сценарий компоновки в Maven для PhoneBook выполняет это в следующем фрагменте:

Листинг 2. Фрагмент сценария компоновки в Maven
<goal name="client" prereqs="java:compile">
      <ant:jar destfile="target/${pom.artifactId}-client.jar">
            <fileset dir="target/classes">
                  <include name="**/*.class"/>
            </fileset>
      </ant:jar>
      <artifact:install artifact="target/${pom.artifactId}-client.jar"
            type="jar" project="${pom}"/>
</goal>

Вторым способом компоновки приложения является простое использование Maven. Распакуйте файлы и запустите команду maven в каталоге PhoneBook. Затем сделайте тоже самое в каталоге PhoneBookClient. Если все пройдет нормально, в подкаталоге target будет создан UberJar - JAR-файл, содержащий все необходимое для запуска клиентского приложения.

Два подхода к компиляции должны работать идентично. Преимущество использования Maven заключается в том, что если вы еще не загрузили зависимости, он автоматически загрузит их с удаленного репозитория Maven на Web-сайте ibiblio (ссылка приведена в разделе "Ресурсы"). Поэтому, если у вас есть проблемы в использовании Eclipse, попробуйте запустить Maven, по крайней мере, один раз с проектом для сбора отсутствующих библиотек.


Запуск приложения

Убедитесь, что серверное приложение PhoneBook развернуто и выполняется на вашем сервере Geronimo. Затем введите следующую команду:

java -jar phonebook-client-uber.jar

На экране возникнет приложение, как показано на рисунке 3.

Рисунок 3. Клиентское приложение Geronimo phonebook
Клиентское приложение Geronimo phonebook

Прежде всего, выберите пункт Connect из меню File. Вы должны получить соединение, если подключаетесь к порту localhost:4201; в противном случае в вашем окне консоли отобразится ошибка. Сервер и порт для подключения можно изменить командой меню Edit > Preferences и попытаться подключиться еще раз. После подключения вы можете ввести имя и номер в редакторе телефонных номеров и нажать кнопку Save для создания новой записи. Она появится в списке имен. Удалите запись, выбрав ее в списке и нажав кнопку Delete. Измените запись, выбрав ее в списке, изменив и нажав Save.


Настройка EJB-порта Geronimo

Методология настройки EJB-порта Geronimo в настоящее время требует редактирования XML-файла и перекомпилирования Geronimo. Небольшая статья Тома Маккуинни (Tom McQueeney), находящаяся в отличном блоге Geronimo Live, рассматривает детали изменения порта, используемого Geronimo Jetty, при помощи файла openejb\modules\assembly\src\plan\j2ee-server-plan.xml (ссылка на блог приведена в разделе "Ресурсы"). Этот же файл содержит также информацию и для EJB-порта (смотрите листинг 3).

Листинг 3. Фрагмент файла j2ee-server-plan.xml file
<gbean name="EJBNetworkService" 
class="org.openejb.server.StandardServiceStackGBean">
        <attribute name="name">EJB</attribute>
        <attribute name="port">4201</attribute>
        <attribute name="address">127.0.0.1</attribute>
        <attribute name="allowHosts">127.0.0.1</attribute>
        <attribute name="logOnSuccess">HOST,NAME,THREADID,USERID</attribute>
        <attribute name="logOnFailure">HOST,NAME</attribute>
        <reference name="Executor"><name>DefaultThreadPool</name></reference>
        <reference name="Server">
            <gbean-name>openejb.server:name=EJBServer,*</gbean-name>
        </reference>
</gbean>

Вы должны отредактировать файл j2ee-server-plan.xml и изменить атрибут allowHosts. Geronimo поддерживает несколько различных типов адресов. Вы должны ввести список адресов (разделенных запятыми) по одному из следующих шаблонов:

  • IP-адрес, последняя четверть которого равна 0. Например, 192.168.10.0 разрешает машинам сети 192.168.10 взаимодействовать с сервером.
  • Любой полностью указанный IP-адрес.
  • Факторизированный IP-адрес. Этот специализированный шаблон дает вам возможность указать часть сети адресов и список адресов в фигурных скобках. Например, 192.168.10.{5,6,7} разрешает доступ к серверу трем машинам: 192.168.10.5, 192.168.10.6 и 192.168.10.7.
  • Сетевая маска IP-адресов. Это привычный для администраторов сети тип адреса. IP-адрес соответствует сетевой маске, основываясь на точных правилах совпадения шаблона битов (объяснение выходит за рамки данной статьи). Например, 192.168.255.255 разрешает доступ к серверу адресам сети 192.168.*.
  • Точный IPv6-адрес. Geronimo готов к работе с будущей IP-сетью, разрешая указать конкретные IP-адреса для прослушивания.
  • Сетевая маска IPv6-адресов.

Более детальную информацию о конкретных принимаемых сервером шаблонах можно получить из исходного кода файла ServiceAccessController.java, находящегося в каталоге openejb\modules\core\src\java\org\openejb\server. В нем вы найдете явные регулярные выражения, соответствующие каждому поддерживаемому типу адресов.

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


Резюме

В данной статье был рассмотрен конкретный пример создания автономного ("толстого") клиентского приложения, которое может общаться с EJB-приложением, выполняющимся внутри сервера приложений Geronimo. Группа разработчиков Geronimo тщательно реализовала установленные стандарты, поэтому простой метод JNDI-поиска для получения удаленного соединения к не сохраняющему состояния сессионному компоненту работает так, как и предполагалось. Это хорошие новости, если вы хотите всего лишь запустить простое приложение, поскольку это потребует от вас написания небольшого количества кода.

Следуя показанной мной схеме, вы можете подключить значительно более объемные базы данных к клиентским приложениям, выполняющимся на той же машине, что и сервер Geronimo. Также при помощи приведенных здесь инструкций вы можете настроить ваш EJB-порт сервера Geronimo для других машин, подключенных к вашей сети или Интернету. Идите дальше и пробуйте!


Загрузка

ОписаниеИмяРазмер
Source code for the phonebook applicationPhonebookClient.zip227 KB

Ресурсы

Научиться

Получить продукты и технологии

  • Приобретите JGoodies Forms 1.0.5, свободно распространяемый менеджер схем для создания форм отличного внешнего вида.
  • Приобретите FormLayoutMaker rc7, дизайнер схем форм с функцией "drag-and-drop", который генерирует XML-файлы для использования с JGoodies Forms.
  • Загрузите Gluecode Standard Edition - свободно распространяемый сервер приложений, основанный на Apache Geronimo.
  • Примените в вашем следующем проекте с открытым исходным кодом пробное программное обеспечение IBM, доступное для загрузки или на DVD.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Технология Java
ArticleID=99792
ArticleTitle=Подключение приложения Java Swing к серверу Geronimo
publish-date=07262005