Перейти к основному содержимому

Руководство по настройке EJB

· 8 мин. чтения

1. Обзор

В этой статье мы собираемся обсудить, как начать разработку Enterprise JavaBean (EJB).

Enterprise JavaBeans используются для разработки масштабируемых распределенных серверных компонентов и обычно инкапсулируют бизнес-логику приложения.

Мы будем использовать WildFly 10.1.0 в качестве предпочтительного серверного решения, однако вы можете использовать любой сервер приложений Java Enterprise по своему выбору.

2. Настройка

Начнем с обсуждения зависимостей Maven, необходимых для разработки EJB 3.2, и того, как настроить сервер приложений WildFly с помощью подключаемого модуля Maven Cargo или вручную.

2.1. Зависимость от Maven

Чтобы использовать EJB 3.2 , убедитесь, что вы добавили последнюю версию в раздел зависимостей вашего файла pom.xml :

<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>

Вы найдете последнюю зависимость в репозитории Maven . Эта зависимость гарантирует, что все API Java EE 7 будут доступны во время компиляции. Предоставленная область гарантирует, что после развертывания зависимость будет предоставлена контейнером, в котором она была развернута .

2.2. Настройка WildFly с помощью Maven Cargo

Давайте поговорим о том, как использовать плагин Maven Cargo для настройки сервера.

Вот код профиля Maven, который инициализирует сервер WildFly:

<profile>
<id>wildfly-standalone</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>${cargo-maven2-plugin.version</version>
<configuration>
<container>
<containerId>wildfly10x</containerId>
<zipUrlInstaller>
<url>
http://download.jboss.org/
wildfly/10.1.0.Final/
wildfly-10.1.0.Final.zip
</url>
</zipUrlInstaller>
</container>
<configuration>
<properties>
<cargo.hostname>127.0.0.0</cargo.hostname>
<cargo.jboss.management-http.port>
9990
</cargo.jboss.management-http.port>
<cargo.servlet.users>
testUser:admin1234!
</cargo.servlet.users>
</properties>
</configuration>
</configuration>
</plugin>
</plugins>
</build>
</profile>

Мы используем плагин для загрузки ZIP-файла WildFly 10.1 непосредственно с веб-сайта WildFly. Который затем настраивается, удостоверяясь, что имя хоста 127.0.0.1 и установка порта 9990.

Затем мы создаем тестового пользователя, используя свойство cargo.servlet.users , с идентификатором пользователя testUser и паролем admin1234!.

Теперь, когда настройка плагина завершена, мы можем вызвать цель Maven и загрузить, установить, запустить сервер и развернуть приложение.

Для этого перейдите в каталог ejb-remote и выполните следующую команду:

mvn clean package cargo:run

Когда вы запускаете эту команду в первый раз, она загружает zip-файл WildFly 10.1, извлекает его и выполняет установку, а затем запускает ее. Это также добавит тестового пользователя, о котором говорилось выше. Любые дальнейшие выполнения не будут снова загружать zip-файл.

2.3. Ручная настройка WildFly

Чтобы настроить WildFly вручную, вы должны сами загрузить установочный zip-файл с веб-сайта wildfly.org . Следующие шаги представляют собой высокоуровневое представление процесса установки сервера WildFly:

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

JBOSS_HOME=/Users/$USER/../wildfly.x.x.Final
JAVA_HOME=`/usr/libexec/java_home -v 1.8`

Затем в каталоге bin запустите ./standalone.sh для операционных систем на базе Linux или ./standalone.bat для Windows.

После этого вам нужно будет добавить пользователя. Этот пользователь будет использоваться для подключения к удаленному компоненту EJB. Чтобы узнать, как добавить пользователя, обратитесь к документации по добавлению пользователя .

Подробные инструкции по настройке см. в документации по началу работы WildFly .

POM проекта был настроен для работы с плагином Cargo и ручной конфигурацией сервера путем установки двух профилей. По умолчанию выбран плагин Cargo. Однако для развертывания приложения на уже установленном, настроенном и работающем сервере Wildfly выполните следующую команду в каталоге ejb-remote :

mvn clean install wildfly:deploy -Pwildfly-runtime

3. Удаленный против локального

Бизнес-интерфейс для компонента может быть как локальным , так и удаленным.

Доступ к аннотированному @Local bean - компоненту возможен только в том случае, если он находится в том же приложении, что и bean-компонент, выполняющий вызов, т. е. если они находятся в одном и том же .ear или .war .

Доступ к аннотированному @Remote bean - компоненту можно получить из другого приложения, т. е. из приложения, находящегося на другом JVM или сервере приложений.

Есть несколько важных моментов, которые следует учитывать при разработке решения, включающего EJB:

  • java.io.Serializable , java.io.Externalizable и интерфейсы, определенные пакетом javax.ejb , всегда исключаются, когда bean-компонент объявлен с @Local или @Remote
  • Если класс компонента является удаленным, то все реализованные интерфейсы должны быть удаленными.
  • Если класс bean-компонента не содержит аннотации или указана аннотация @Local , то все реализованные интерфейсы считаются локальными .
  • Любой интерфейс, явно определенный для bean-компонента, который не содержит интерфейса, должен быть объявлен как @Local.
  • Версия EJB 3.2, как правило, обеспечивает большую степень детализации для ситуаций, когда локальные и удаленные интерфейсы должны быть явно определены.

4. Создание удаленного EJB

Давайте сначала создадим интерфейс бина и назовем его HelloWorld:

@Remote
public interface HelloWorld {
String getHelloWorld();
}

Теперь мы реализуем вышеуказанный интерфейс и назовем конкретную реализацию HelloWorldBean:

@Stateless(name = "HelloWorld")
public class HelloWorldBean implements HelloWorld {

@Resource
private SessionContext context;

@Override
public String getHelloWorld() {
return "Welcome to EJB Tutorial!";
}
}

Обратите внимание на аннотацию @Stateless в объявлении класса. Это означает, что этот компонент является сеансовым компонентом без сохранения состояния. Этот тип bean-компонента не имеет никакого связанного состояния клиента , но может сохранять свое состояние экземпляра и обычно используется для выполнения независимых операций.

Аннотация @Resource вводит контекст сеанса в удаленный компонент.

Интерфейс SessionContext обеспечивает доступ к контексту сеанса времени выполнения, который контейнер предоставляет для экземпляра сеансового компонента . Затем контейнер передает интерфейс SessionContext экземпляру после создания экземпляра. Контекст сеанса остается связанным с этим экземпляром на протяжении всего времени его существования.

Контейнер EJB обычно создает пул объектов bean-компонентов без сохранения состояния и использует эти объекты для обработки клиентских запросов. В результате этого механизма пула не гарантируется сохранение значений переменных экземпляра при вызовах методов поиска.

5. Удаленная настройка

В этом разделе мы обсудим, как настроить Maven для сборки и запуска приложения на сервере.

Давайте рассмотрим плагины один за другим.

5.1. EJB-плагин

Приведенный ниже подключаемый модуль EJB используется для упаковки модуля EJB. Мы указали версию EJB как 3.2.

Следующая конфигурация подключаемого модуля используется для настройки целевого JAR-файла для bean-компонента:

<plugin>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.4</version>
<configuration>
<ejbVersion>3.2</ejbVersion>
</configuration>
</plugin>

5.2. Разверните удаленный EJB

Чтобы развернуть компонент на сервере WildFly, убедитесь, что сервер запущен и работает.

Затем, чтобы выполнить удаленную настройку, нам нужно будет запустить следующие команды Maven для файла pom в проекте ejb-remote :

mvn clean install

Затем мы должны запустить:

mvn wildfly:deploy

В качестве альтернативы мы можем развернуть его вручную как пользователь- администратор из административной консоли сервера приложений .

6. Настройка клиента

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

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

6.1. Настройка Maven на стороне клиента

Чтобы запустить клиент EJB3, нам нужно добавить следующие зависимости:

<dependency>
<groupId>org.wildfly</groupId>
<artifactId>wildfly-ejb-client-bom</artifactId>
<type>pom</type>
<scope>import</scope>
</dependency>

Мы зависим от удаленных бизнес-интерфейсов EJB этого приложения для запуска клиента. Поэтому нам нужно указать зависимость JAR клиента EJB. Мы добавляем следующее в родительский pom:

<dependency>
<groupId>com.foreach.ejb</groupId>
<artifactId>ejb-remote</artifactId>
<type>ejb</type>
</dependency>

<type> указывается как ejb .

6.2. Доступ к удаленному компоненту

Нам нужно создать файл в папке src/main/resources и назвать его jboss-ejb-client.properties , который будет содержать все свойства, необходимые для доступа к развернутому компоненту:

remote.connections=default
remote.connection.default.host=127.0.0.1
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options
.SASL_POLICY_NOANONYMOUS = false
remote.connection.default.connect.options.org.xnio.Options
.SASL_POLICY_NOPLAINTEXT = false
remote.connection.default.connect.options.org.xnio.Options
.SASL_DISALLOWED_MECHANISMS = ${host.auth:JBOSS-LOCAL-USER}
remote.connection.default.username=testUser
remote.connection.default.password=admin1234!

7. Создание клиента

Класс, который будет обращаться к удаленному bean-компоненту HelloWorld и использовать его , был создан в EJBClient.java , который находится в пакете com.foreach.ejb.client .

7.1. URL-адрес удаленного компонента

Удаленный компонент находится по URL-адресу, соответствующему следующему формату:

ejb:${appName}/${moduleName}/${distinctName}/${beanName}!${viewClassName}
  • ${appName} — это имя приложения для развертывания. Здесь мы не использовали какой-либо файл EAR, а простое развертывание JAR или WAR, поэтому имя приложения будет пустым.
  • ${moduleName} — это имя, которое мы установили для нашего развертывания ранее, так что это ejb-remote .
  • ${distinctName} — это конкретное имя, которое можно дополнительно назначить развертываниям, развернутым на сервере. Если развертывание не использует отличное имя , мы можем использовать пустую строку в имени JNDI для отдельного имени , как мы сделали в нашем примере .
  • Переменная ${beanName} — это простое имя класса реализации EJB, поэтому в нашем примере это HelloWorld.
  • ${viewClassName} обозначает полное имя интерфейса удаленного интерфейса.

7.2. Логика поиска

Далее, давайте посмотрим на нашу простую логику поиска:

public HelloWorld lookup() throws NamingException { 
String appName = "";
String moduleName = "remote";
String distinctName = "";
String beanName = "HelloWorld";
String viewClassName = HelloWorld.class.getName();
String toLookup = String.format("ejb:%s/%s/%s/%s!%s",
appName, moduleName, distinctName, beanName, viewClassName);
return (HelloWorld) context.lookup(toLookup);
}

Чтобы подключиться к только что созданному bean -компоненту , нам понадобится URL-адрес, который мы можем передать в контексте.

7.3. Исходный контекст

Теперь мы создадим/инициализируем контекст сеанса:

public void createInitialContext() throws NamingException {
Properties prop = new Properties();
prop.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
prop.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.naming.remote.client.InitialContextFacto[ERROR]
prop.put(Context.PROVIDER_URL, "http-remoting://127.0.0.1:8080");
prop.put(Context.SECURITY_PRINCIPAL, "testUser");
prop.put(Context.SECURITY_CREDENTIALS, "admin1234!");
prop.put("jboss.naming.client.ejb.context", false);
context = new InitialContext(prop);
}

Для подключения к удаленному компоненту нам нужен контекст JNDI. Фабрика контекста предоставляется артефактом Maven org.jboss:jboss-remote-naming, и это создает контекст JNDI, который преобразует URL-адрес, созданный в методе поиска , в прокси для процесса удаленного сервера приложений.

7.4. Определить параметры поиска

Мы определяем класс фабрики с параметром Context.INITIAL_CONTEXT_FACTORY.

Context.URL_PKG_PREFIXES используется для определения пакета для сканирования дополнительного контекста именования.

Параметр org.jboss.ejb.client.scoped.context = false сообщает контексту, что параметры подключения (такие как узел подключения и порт) следует читать из предоставленной карты, а не из файла конфигурации пути к классам. Это особенно полезно, если мы хотим создать пакет JAR, который должен иметь возможность подключаться к разным хостам.

Параметр Context.PROVIDER_URL определяет схему соединения и должен начинаться с http-remoting:// .

8. Тестирование

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

@Test
public void testEJBClient() {
EJBClient ejbClient = new EJBClient();
HelloWorldBean bean = new HelloWorldBean();

assertEquals(bean.getHelloWorld(), ejbClient.getEJBRemoteMessage());
}

Теперь, когда тест пройден, мы можем быть уверены, что все работает так, как ожидалось.

9. Заключение

Итак, мы создали сервер EJB и клиент, который вызывает метод на удаленном EJB. Проект можно запустить на любом сервере приложений, правильно добавив зависимости для этого сервера.

Весь проект можно найти на GitHub .