До этого
все примеры, которые мы рассматривали,
были локальными EJB бинами,
которые запускались на одной виртуальной
java машине (jvm), и из под сервера wildfly. Часто
так бывает, что клиентский код находиться на другом компьютере и нам нужно порой работать с ejb бинами удаленно, т. е. вызвать методы ejb удаленно и получить результат. Что бы
позволить такую роскошь, мы должны описать интерфейс с аннотаций @Remote и
реализовать его в нашем ejb бине. Давайте посмотрим на код интерфейса:
package com.vit.fly.ejb;
import
javax.ejb.Remote;
import
java.util.concurrent.Future;
@Remote
public
interface Calculator {
Future<Integer> add(int x, int y);
void longRun(int x, int y);
}
Он
описывает два метода, первый метод будет складывать 2 целых числа и возвращать
нам сумму, второй будет выполнять “долгую” по времени операцию. Опишем сам ejb и реализуем интерфейс Calculator:
package com.vit.fly.remoteejb;
import
org.jboss.logging.Logger;
import
javax.annotation.Resource;
import
javax.ejb.AsyncResult;
import
javax.ejb.Asynchronous;
import
javax.ejb.SessionContext;
import
javax.ejb.Stateless;
import
java.util.concurrent.Future;
import
java.util.concurrent.TimeUnit;
@Stateless(name
= "calculator")
public class
CalculatorBean implements Calculator {
private static Logger log =
Logger.getLogger(CalculatorBean.class.getName());
@Resource
private SessionContext context;
@Override
@Asynchronous
public Future<Integer> add(int x, int
y) {
try {
TimeUnit.SECONDS.sleep(1L);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AsyncResult<Integer>(x + y); //складываем 2 числа
}
@Override
//@Asynchronous
public void longRun(int x, int y) {
try {
TimeUnit.SECONDS.sleep(10L);//имитируем
долгую работу, приостанавливаем поток на 10 секунд
log.info("longRun method complete!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Собираем
все в jar файл и
помещаем его в каталог JBOSS_HOME/Standalone/deployments, после деплоя, в логах
сервера wildfly
появятся строчки примерно такого вида:
2015-08-27
21:41:36,160 INFO
[org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor]
(MSC service thread 1-2) JNDI bindings for session bean named calculator in
deployment unit deployment "ejb-remote-example-server.jar" are as
follows:
java:global/ejb-remote-example-server/calculator!com.vit.fly.remoteejb.Calculator
java:app/ejb-remote-example-server/calculator!com.vit.fly.remoteejb.Calculator
java:module/calculator!com.vit.fly.remoteejb.Calculator
java:jboss/exported/ejb-remote-example-server/calculator!com.vit.fly.remoteejb.Calculator
java:global/ejb-remote-example-server/calculator
java:app/ejb-remote-example-server/calculator
java:module/calculator
2015-08-27
21:41:36,236 INFO
[org.jboss.weld.deployer] (MSC service thread 1-4) JBAS016005: Starting
Services for CDI deployment: ejb-remote-example-server.jar
Перейдем к
написанию клиента, который будет вызывать наш ejb бин удаленно:
package
com.vit.fly;
import
com.vit.fly.remoteejb.Calculator;
import
com.vit.fly.remoteejb.CalculatorBean;
import
javax.naming.Context;
import
javax.naming.InitialContext;
import
javax.naming.NamingException;
import
java.util.Properties;
import
java.util.concurrent.Future;
import
java.util.concurrent.TimeUnit;
public class
Main {
private static Context context = null;
public static void main(String[] args)
throws Exception {
try {
Properties prop = new
Properties();
prop.put(Context.INITIAL_CONTEXT_FACTORY,"org.jboss.naming.remote.client.InitialContextFactory");
prop.put(Context.PROVIDER_URL,
"http-remoting://127.0.0.1:8080");
context = new InitialContext(prop);
Calculator calculator =
(Calculator) context.lookup("/ejb-remote-example-server/calculator!com.vit.fly.remoteejb.Calculator");
System.out.println(calculator);
Future<Integer> result =
calculator.add(1, 4);
calculator.longRun(1,
2);
System.out.println(result.get(2,
TimeUnit.SECONDS));
} finally {
context.close();
}
}
}
Вам понадобится
еще файл с настройками jboss-ejb-client.properties, положите его в classpath:
endpoint.name=client-endpoint
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.username=my-username-here
remote.connection.default.password=my-password-here
remote.connection.default.host=localhost
remote.connection.default.port=8080
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
Запустим
на выполнение наш пример, и получим результат работы метода:
авг 28, 2015 7:59:38 PM
org.jboss.ejb.client.remoting.RemotingConnectionEJBReceiver associate
INFO:
EJBCLIENT000013: Successful version handshake completed for receiver context
EJBReceiverContext{clientContext=org.jboss.ejb.client.EJBClientContext@9df6e3,
receiver=Remoting connection EJB receiver
[connection=org.jboss.ejb.client.remoting.ConnectionPool$PooledConnection@bbe4b0,channel=jboss.ejb,nodename=kamaz1-pc]}
on channel Channel ID b371683b (outbound) of Remoting connection 00eebce6 to
localhost/127.0.0.1:8080
5
Как вы
можете заметить, нам пришлось ждать результата окончания работы программы 11
секунд. Метод longRun отработал с задержкой в 10 секунд, если вы сделаете его асинхронным, вам будет не нужно ждать,
пока метод завершит свою работу, то задержка у основной программы будет
приблизительно около 1 секунды. И после запуска из программы метода, 10
секунд метод longRun будет автономно работать
вне зависимости от нашей основной программы, автономно. Для этого нужно, просто раскоментировать
аннотацию @Asynchronous
у
метода longRun и он станет асинхронным. Здесь я вам
показываю работу еще одного асинхронного
метода add, который возвращает результат посредством интерфейса Future. У этого интерфейса есть метод .get(2, TimeUnit.SECONDS) который принимает два параметра время,
в течение которого ожидается результат, и в чем первый параметр измеряется, в
моем случае в секундах. И на последок клиентской программе нужна библиотека jboss-client.jar, которая находиться в дистрибутиве wildfly, вообще-то не хватающие библиотеки я устанавливаю из
установленного мной дистрибутива. Просто организовываю поиск нужного мне класса, нахожу библиотеку jar инсталирую её в .m2 репозитарий и подсовываю её maven’y как
зависимость. Вот мои pom.xml:
<?xml
version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.vit.fly.remoteejb</groupId>
<artifactId>jboss_ejb1</artifactId>
<version>1.0</version>
<name>ejb remote server</name>
<packaging>ejb</packaging>
<repositories>
<repository>
<id>jboss-public-repository-group</id>
<name>JBoss Public Maven
Repository Group</name>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jboss.spec.javax.ejb</groupId>
<artifactId>jboss-ejb-api_3.2_spec</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.annotation</artifactId>
<version>3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.9.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.9.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jboss-annotations-api_1.2_spec</artifactId>
<version>1.0.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.4</version>
<configuration>
<ejbVersion>3.2</ejbVersion>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<finalName>ejb-remote-example-server</finalName>
</build>
</project>
Комментариев нет:
Отправить комментарий