Кодирование и компилирование тестового клиента

EJB-объект сам по себе бесполезен; нам нужен хотя бы один простой клиент для пользования им. Пользователем EJB может быть другой EJB-объект, простой JavaBean, JSP-страница, апплет или обычное приложение. В нашем примере, для упрощения, мы закодируем обычное приложение. Это приложение создаст объект класса Interest и выполнит его единственный метод.

Во время установки объекта, выполненной на предыдущем шаге, сервер разместил home-интерфейс EJB-объекта под JNDI-именем "interest/Interest" и экспортировал home-интерфейс, так что он теперь может быть вызван через RMI. Мы собираемся рассказать вам о том, как получить home-интерфейс из клиента при помощи JNDI и вызывать его методы. Пример кода приведен ниже:

Рисунок 1.8. Код тестового клиента, имя файла InterestClient.java

package org.jboss.docs.interest;

import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;

import org.jboss.docs.interest.Interest;
import org.jboss.docs.interest.InterestHome;

/** 
 Это простое приложение проверяет 'Interest' Enterprise JavaBean который 
 имлементирован в пакете 'org.jboss.docs.interest'. Для того, чтобы этот тест заработал
 объект должен быть развернут на EJB-сервере.
 */
class InterestClient
{
   /** Этот метод делает всю работу. Он создает экземпляр объекта Interest EJB на сервере,
    и вызывает его метод `calculateCompoundInterest()', после этого печатает результат вычислений.
    */
   public static void main(String[] args)
   {     
      // Заключение всего процесса в один блок 'try' не самый хороший путь для обработки исключений,
      // но я не хочу усложнять программу множеством блоков 'catch'
      try
      {
         // Получаем контекст имен. (naming context)
         InitialContext jndiContext = new InitialContext();
         System.out.println("Got context");
         
         // Получаем ссылку на объект Interest Bean
         Object ref  = jndiContext.lookup("interest/Interest");
         System.out.println("Got reference");
         
         // Получаем ссылку на его home-интерфейс
         InterestHome home = (InterestHome)
         PortableRemoteObject.narrow(ref, InterestHome.class);
         
         // Создаем объект Interest с помощью home-интерфейса
         Interest interest = home.create();
         
         // вызываем метод calculateCompoundInterest() для того, чтобы выполнить вычисления
         System.out.println("Interest on 1000 units, at 10% per period, compounded over 2 periods is:");
         System.out.println(interest.calculateCompoundInterest(1000, 0.10, 2));
      }
      catch(Exception e)
      {
         System.out.println(e.toString());
      }
   }
}

Заметьте, что клиент ищет интерфейс InterestHome под именем JNDI "interest/Interest". Home-интерфейс вашего объекта должен быть размещен под этим именем если вы сопроводили приложение необходимым файлом jboss.xml. Если это не так, имя JNDI будет "Interest". Соединение с реализацией JNDI от JBoss требует создание объекта InitialContext с правильно настроенным файлом jndi.properties в пути classpath вашего клиентского приложения. В коде, все что необходимо это:

// Get a naming context
InitialContext jndiContext = new InitialContext();
System.out.println("Got context");

Файл jndi.properties который мы будем использовать расположен в файле examples/resources/jndi.properties в вашем каталоге с примерами файлов для этой документации. Его содержимое:

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.provider.url=jnp://localhost:1099
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces

Этот файл определяет класс InitialContextFactory, ссылку на провайдера (provider url) и пакеты для фабрик объектов (object factories) специфичных для JBoss JNDI provider. Provider url может быть сокращен до "localhost" или имени компьютера на котором работает JBoss, в этом случае используется порт по умолчанию 1099.

Комментарии в программе должны объяснить как она работает; один из пункт требует пояснения - рекомендованый путь для получения ссылки на home-интерфейс должен выглядеть следующим образом:

InterestHome home = (InterestHome) 
	PortableRemoteObject.narrow (ref, InterestHome.class);

таким образом вы гарантируете совместимость с различными протоколами RMI (например, RMI/IIOP). Метод 'narrow' гаранитрует, что объект 'ref' может быть сконвертирован в объект класса 'InterestHome'.

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

Для компиляции и запуска InterestClient выполните следующую команду:

bash-2.04$ ant intro-interest-client
Buildfile: build.xml

validate:

fail_if_not_valid:

init:
     [echo] Using JBoss directory=/tmp/JBoss-2.2.2
     [echo] Using base classpath=/tmp/JBoss-2.2.2/client/ejb.jar:/tmp/JBoss-2.2.2/client/jaas.jar:/tmp/JBoss-2.2.2/client/jbosssx-client.jar:/tmp/JBoss-2.2.2/client/jboss-client.jar:/tmp/JBoss-2.2.2/client/jnp-client.jar:/tmp/tomcat/lib/servlet.jar
     [echo] Using Source directory=/tmp/examples
     [echo] Using Build directory=/tmp/examples/build-examples

intro-interest-client:

compile:

interest-client:
     [echo] Using client classpath: /tmp/JBoss-2.2.2/client/ejb.jar:/tmp/JBoss-2.2.2/client/jaas.jar:/tmp/JBoss-2.2.2/client/jbosssx-client.jar:/tmp/JBoss-2.2.2/client/jboss-client.jar:/tmp/JBoss-2.2.2/client/jnp-client.jar:/tmp/tomcat/lib/servlet.jar:/tmp/examples/build-examples/interest/classes:/tmp/examples/resources
     [java] Got context
     [java] Got reference
     [java] Interest on 1000 units, at 10% per period, compounded over 2 periods is:
     [java] 210.00000000000023

BUILD SUCCESSFUL

Total time: 2 seconds


Приведенный вывод - это то, что вы должны увидеть если все пойдет хорошо. Вывод показывет, что classpath использованый для запуска клиента включает несколько jar-файлов, расположенных в клиентской директории JBoss, так же как и директорию, содержащую скомпилированные классы примеров и директорию, содержащую файл jndi.properties. Эти клиентские jar-файлы JBoss содержат стандартные интерфейсы EJB и JNDI, наряду со специфичным для JBoss кодом. Вот эти jar-файлы:

Кроме этого на серверной консоли должен быть вывод от Interest EJB. Он сгенерирован для того, чтобы показать что объект был выполнен на сервере, а не клиенте. Посмотрите на нечто похожее в серверных логах или на консоли:

[Interest] Someone called `calculateCompoundInterest!'

Хорошо, вот он. Мы рассмотрели кодирование, компилирование и развертывание EJB, и закодировали и запустили простой тестовый клиент.

Наши друзья