Московский государственный университет имени М.В.Ломоносова
Опубликован: 18.09.2006 | Доступ: свободный | Студентов: 1868 / 118 | Оценка: 4.32 / 3.36 | Длительность: 27:14:00
ISBN: 978-5-9556-0067-3
Лекция 13:

Компонентные технологии разработки web-приложений

Связь

Связь между компонентами, работающими в разных процессах и на разных машинах, обеспечивается в J2EE, в основном, двумя способами: синхронная связь — с помощью реализации удаленного вызова методов на Java ( Java RMI ), асинхронная — с помощью службы сообщений Java (Java message service, JMS ).

Java RMI [10] является примером реализации общей техники удаленного вызова методов. Базовые интерфейсы для реализации удаленного вызова методов на Java находятся в пакете java.rmi стандартной библиотеки.

Набор методов некоторого класса, доступных для удаленных вызовов, выделяется в специальный интерфейс, называемый удаленным интерфейсом (remote interface) и наследующий java.rmi.Remote. Сам класс, методы объектов которого можно вызвать удаленно, должен реализовывать этот интерфейс. Этот же интерфейс реализуется автоматически создаваемой клиентской заглушкой. Поэтому объекты-клиенты работают только с объектом этого интерфейса, а не с объектом класса, реализующего декларированные в таком интерфейсе операции.

Кроме того, класс, реализующий удаленный интерфейс, должен наследовать класс java.rmi.server.RemoteObject. Этот класс содержит реализации методов hashCode(), equals() и toString(), которые учитывают возможность размещения его объектов в процессах, отличных от того, где они вызываются. Обычно наследуется не сам этот класс, а его подклассы java.rmi.server.UnicastRemoteObject или java.rmi.activation.Activatable. Первый реализует общую функциональность объектов, которые можно вызвать удаленно поверх транспортного протокола TCP, пока работает содержащий их процесс, включая занесение информации о таких объектах в реестр RMI (собственная служба именования в рамках Java RMI ). Второй класс служит для реализации активизируемых объектов (activatable objects), которые создаются системой "по требованию" — как только кто-нибудь вызывает в них какой-нибудь метод. Ссылки на такие объекты могут сохра няться, а обратиться к ним можно спустя долгое время, даже после перезагрузки системы.

Каждый удаленный метод (remote method), т.е. метод, который можно вызвать из другого процесса, должен декларировать в качестве класса возможных исключений java.rmi.RemoteException или его базовые типы java.io.IOException или java.lang.Exception. Этот класс сам служит базовым для классов исключений, представляющих ошибки связи, ошибки маршалинга параметров или результатов и ошибки протоколов, реализующих RMI.

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

Остальные объекты передаются как параметры или результаты удаленных вызовов с помощью сериализации их данных и построения копии такого объекта в другом процессе. Так же передаются и создаваемые удаленным методом исключения. Для этого им необходимо реализовывать интерфейс java.io.Serializable или же быть значениями примитивных типов.

Простой пример Java-классов, взаимодействующих по RMI, приведен ниже.

Код удаленного интерфейса:

package examples.rmi;

public interface Hello extends java.rmi.Remote
{
  public String hello() throws java.rmi.RemoteException;
}

Код реализации удаленного интерфейса.

package examples.rmi;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class HelloImpl extends UnicastRemoteObject implements Hello
{
  public static final String ServerHost = "hostname";
  public static final String ServerURL = "rmi://" + ServerHost + ":2001/SERVER";
  public static final int RegistryPort = 2000;

  public HelloImpl () throws java.rmi.RemoteException { }

  public String hello () throws java.rmi.RemoteException
  { return "Hello!"; }

  public static void main (String[] args)
  {
    try
    {
      Hello stub = new HelloImpl();
      Registry registry = LocateRegistry.getRegistry(RegistryPort);
      registry.rebind(ServerURL, stub);
    }
    catch (Exception e)
    {
      System.out.println("server creation exception");
      e.printStackTrace();
    }
  }
}
13.1.

Код класса-клиента.

package examples.rmi;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class HelloClient
{
  public HelloClient () { }

  public static void main (String[] args)
  {
    try
    {
      Registry registry = LocateRegistry.getRegistry
                          (HelloImpl.ServerHost, HelloImpl.RegistryPort);
      Hello stub = (Hello) registry.lookup(HelloImpl.ServerURL);
      System.out.println("response: " + stub.hello());
    }
    catch (Exception e) 
    {
      System.err.println("Client exception: " + e.toString());
      e.printStackTrace();
    }
  }
}

Для того чтобы запустить этот пример, нужно выполнить следующие действия.

  1. Скомпилировать все классы и интерфейсы. В классе-реализации серверного компонента константа ServerHost должна быть инициализирована именем машины, на которой будет работать сервер.
  2. Создать и скомпилировать заглушки при помощи компилятора Java RMI, запустив его в корневой директории для кода на Java.
    rmic examples.rmi.HelloImpl
  3. Запустить реестр RMI на той машине, на которой будет выполняться серверный компонент HelloImpl. Реестр используется для регистрации серверного объекта и последующего поиска его клиентами и в данном примере принимает сообщения по порту 2000.
    start rmiregistry 2000 &
  4. Запустить сам серверный компонент.
    java examples.rmi.HelloImpl
  5. Запустить клиентский компонент на той же машине или на другой.
    java examples.rmi.HelloClient

Если никаких ошибок не сделано, и порты 2000 и 2001 на серверной машине свободны, клиент выдаст сообщение.

response: Hello!

Поскольку базовые интерфейсы компонентов EJB наследуют java.rmi.Remote, такие компоненты автоматически предоставляют возможность обращаться к некоторым из своих методов удаленно.

Служба сообщений Java ( JMS ) [11] представляет собой спецификацию интерфейсов для поддержки передачи сообщений (в частности, асинхронных) между компонентами в рамках платформы J2EE. Ее базовые библиотеки — пакет javax.JMS — не входят в состав J2SE. Та или иная реализация JMS должна входить в любую реализацию платформы J2EE.

Основные элементы JMS следующие.

  • Сообщение. Все объекты-сообщения реализуют интерфейс javax.JMS.Message.

    Сообщение имеет тело, которое может быть отображением (map) ключей в значения, текстом, объектом, набором байт или потоком значений примитивных типов Java. Каждый из видов сообщений представлен особым подинтерфейсом общего интерфейса Message.

    Сообщение может иметь набор заголовков (headers), большинство из которых определяются автоматически.

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

  • Клиент может передать сообщение, установив соединение с провайдером JMS. Соединения представляются с помощью объектов интерфейса javax.JMS.Connection, а получить соединение можно с помощью фабрики соединений (объект javax.JMS.ConnectionFactory ), найдя ее при помощи службы именования. Передать сообщение можно и воспользовавшись объектом-адресатом (объект javax.JMS.Destination ), который также можно получить через службу именования.
  • JMS поддерживает как связь точка-точка (peer-to-peer, P2P), так и посылку и прием сообщений по схеме подписки/публикации. Основные интерфейсы JMS (соединение, фабрика соединений, адресат, сессия и пр.) имеют специфические подинтерфейсы для каждой из этих двух моделей связи. В клиентских программах рекомендуется всегда использовать общие интерфейсы.
Владислав Нагорный
Владислав Нагорный

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

Спасибо!

Лариса Парфенова
Лариса Парфенова

1) Можно ли экстерном получить второе высшее образование "Программная инженерия" ?

2) Трудоустраиваете ли Вы выпускников?

3) Можно ли с Вашим дипломом поступить в аспирантуру?