Как построить распределенный апплет Java, имеющий доступ к серверным объектам с помощью CORBA

Существует целый ряд технологий, позволяющих создавать для Web распределенные клиент-серверные приложения. Для приложений, которые должны обслуживать большое количество пользователей, самый лучший выбор - стандарт CORBA. С его помощью можно строить масштабируемые программы, и он широко поддерживается производителями. Сочетание возможностей языка Java с устойчивостью CORBA позволит разработчикам программ на Java строить мощные промышленные приложения с использованием стандартных технологий. Статья начинается с краткого обзора CORBA, а потом дается пример построения многослойного клиент-серверного приложения. Кроме того, проводится сравнение технологий CORBA, RMI и DCOM.

Всем нам приходилось сталкиваться с ситуациями, когда для работы со сценариями Web-сервера используются формы HTML или CGI (Common Gateway Interface). В частности, эта техника часто используется для запроса имени пользователя и пароля для входа в систему. Значения переменных Username и Password передаются в сценарий, отвечающий за допуск пользователей только к тем областям Web-сервера, к которым они имеют право обращаться. Для этого используется протокол HTTP, в котором (как читатель, наверное, хорошо знает, а может, и нет) отсутствует понятие состояния (stateless protocol). Каждый раз при загрузке новой страницы пользователь фактически отключается от сервера, который, в свою очередь, не имеет представления, кто пользователь такой и что он в данный момент делает. Поэтому даже после входа на сервер, при пересылке каждой страницы браузер пользователя должен отправлять на сервер имя пользователя и пароль, чтобы можно было проверить, законно ли обращение к данной странице. Иными словами, ни клиентская, ни серверная части приложения (т.е. ни Web-браузер, ни Web-сервер) не могут оперировать такими понятиями, как локальные переменные, локальные вызовы метода или локальные объекты.

На протяжении десятилетий программистское сообщество пыталось научиться представлять программный код в виде объектов. И вот, когда победа, казалось бы, уже одержана, мы оказываемся отброшены назад, в эпоху пакетного режима обработки заданий.

Тем не менее, не все так плохо. Технология Web принесла с собой революционное новшество - стандартные, открытые протоколы и независимость от платформы. В настоящее время HTTP и CGI используются на десятках тысяч серверов - с их помощью можно получать информацию о пользователе, запускать сценарий на сервере и даже отправлять информацию пользователю в ответ на его запросы. И все же эти серверы не похожи на приложения в традиционном смысле этого слова. Кроме того, все программы для этих узлов приходится писать "с нуля", поскольку там используются новые технологии (HTTP или CGI). Для того, чтобы перевести существующие приложения на Web или построить мощные новые приложения на коммуникационной основе Internet/intranet, нужна технология, обладающая следующими свойствами:

  • Поддержка существующего программного кода на C, C++ и COBOL (а также других языках).
  • Поддержка Java - это позволит строить мобильные объектно-ориентированные приложения, не зависящие от платформы.
  • Отсутствие ориентации на конкретного производителя, чтобы приложения можно было поддерживать в течение продолжительного времени.
  • Масштабируемость для поддержки большого числа пользователей.
  • Поддержка большого числа платформ (чтобы избежать "привязки к платформе").
  • Использование объектно-ориентированного программирования (оно имеет множество достоинств).
  • Сквозная защита данных.
  • Широкая отраслевая поддержка.

    Знакомьтесь: CORBA. Вся наша статья нацелена на доказательство того, что только одна технология, CORBA, реально может удовлетворить всем требованиям из списка (и кое-каким еще). Кроме того, читатель увидит, что поскольку Java и CORBA - взаимно-дополняющие технологии, то в среде Java можно быстро и без больших затрат начать использовать CORBA.

    Краткое введение в CORBA

    CORBA - это спецификация, описывающая взаимодействие распределенных объектов. До того момента, как начался взрывообразный рост популярности World Wide Web вообще и языка программирования Java в частности, CORBA был просто высокоуровневым решением для поддержки распределенных объектов, ориентированным в основном на разработчиков программ на C++.

    Спецификация CORBA находится в ведении Object Management Group (OMG), открытого консорциума более чем 700 компаний, совместно работающих над выработкой открытых стандартов для объектно-ориентированных вычислений. Объекты CORBA могут быть написаны на любом языке, в частности, на С, С++, Java, Ada или Smalltalk. Эти объекты могут работать на любой платформе, поддерживаемой одним из производителей ПО на CORBA, например, на Solaris, Windows 95/NT, OpenVMS, Digital Unix, HP-UX, или AIX. Это означает, что приложение на Java, работающее под Windows 95, может динамически, через Internet, загружать объекты на C++, хранимые на Web-сервере, работающем под Unix.

    Независимость от языка обеспечивается построением интерфейсов с объектами на языке IDL (Interface Description Language). Благодаря ему, все объекты CORBA можно описывать сходным образом; единственное требование - наличие "мостика" между исходным языком разработки (C/C++, COBOL, Java) и IDL. Объекты CORBA взаимодействуют между собой через посредника, называемого Object Request Broker (ORB); они могут обмениваться данными через различные популярные сетевые протоколы (например, TCP/IP или IPX/SPX). ORB от разных производителей взаимодействуют друг с другом с использованием протокола IIOP (Internet Inter-Orb Protocol), работающего поверх TCP/IP; IIOP является частью стандарта CORBA 2.0 (это его новейшая модификация).

    К настоящему времени разработаны ORB для многих популярных языков программирования (в частности, C++, Smalltalk, Java и Ada95). По мере роста популярности других языков, производители, несомненно, разработают ORB и для этих языков.

    В 1990 году OMG разработала архитектуру OMA (Object Management Architecture), изначально предназначенную для обмена данными между приложениями. При этом, в частности, понадобился стандарт, определяющий взаимодействие составных частей приложения, или объектов. Это и была CORBA. В OMA описаны четыре основных части любой реализации CORBA:

    1. Object Request Broker представляет собой нечто вроде программной "шины", через которую объекты обмениваются данными.

    2. В CORBAServices описаны системные сервисы, добавляемые к ORB, например, Security (защита), Naming (наименование) и Transactions (транзакции).

    3. В CORBAFacilities описаны сервисы уровня приложения, например, для построения сложных документов.

    4. На уровне Business Objects описаны реальные объекты и приложения, например, Airplane (самолет) или BankAccount (банковский счет).

    Практическое занятие: разработка модуля CORBA на Java

    Для построения распределенного апплета Java, имеющего доступ к серверным объектам с помощью CORBA, мы применим один из популярных ORB и воспользуемся IDL для определения интерфейсов с нашими объектами. В разделе "Источники информации" в конце нашей статьи указаны способы связи с несколькими известными производителями средств CORBA. Для нашего апплета я выбрал средство Visigenic VisiBroker for Java. Лицензии на этот ORB купили ряд компаний, в частности, Oracle, Netscape, и Novell; он входит в комплект поставки Netscape Navigator 4.0.

    Примечание: Наш апплет можно использовать не только с Netscape Navigator 4.0, но и с другими браузерами. При этом на запуск апплета потребуется несколько больше времени, поскольку потребуется загрузка несколько дополнительных классов Java.

    Мы построим простой апплет Java, обеспечивающий создание экземпляра серверного объекта на базе CORBA. Для простоты, наш серверный объект тоже написан на Java; в нем содержится массив информации о разных производителях ORB для CORBA и их продукции. Клиентский апплет создает экземпляр объекта и обращается с запросом к массиву, после чего обновляет содержимое экрана. Более серьезным упражнением (очень рекомендую вам этим заняться) было бы обеспечить хранение информации для ORB в реляционной базе данных на сервере, откуда она извлекалась бы с использованием JDBC или какого-нибудь другого средства доступа к базам данных. При этом у нас получилось бы настоящее трехслойное приложение с использованием CORBA.

    Прежде чем углубляться в построение приложения, рассмотрим ORB и IDL более подробно.

    Object Request Broker: подробности

    Наиболее важной частью архитектуры OMA является Object Request Broker. ORB - единственный компонент CORBA, который обязательно должен присутствовать для создания CORBA-совместимого приложения. Многие ORB поставляются без модулей CORBAServices или CORBAFacilities; Business Objects всегда приходится либо докупать, либо разрабатывать самостоятельно. Но без ORB приложение CORBA работать не может.

    Наиболее заметной функцией ORB является реакция на запросы пользовательского приложения или другого ORB. Во время работы приложения CORBA, модуль ORB может делать и массу других полезных вещей, в частности:

  • Находить объекты и создавать их экземпляры на удаленных машинах.
  • Передавать параметры из одного языка программирования (например, C++) в другой (например, Java).
  • Обеспечивать защиту информации на границе локальной машины.
  • Извлекать и публиковать метаданные об объектах на локальной системе, после чего эти данные может использовать другой ORB.
  • Запускать методы удаленного объекта с использованием статического механизма запуска, описанного в загруженной ранее "заглушке" (stub).
  • Запускать методы удаленного объекта с использованием динамического механизма запуска.
  • Автоматически запускать объекты.
  • Направлять методы обратного вызова на тот локальный объект, который ими управляет.

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

    Описание объектов с использованием IDL

    Чтобы обеспечить независимость CORBA от производителя и языка программирования, необходимо предусмотреть какой-то мостик между, например, серверной программой CORBA на C++ и клиентским приложением CORBA на Java. Как вы уже знаете, этим мостиком служит IDL. Он позволяет группировать все методы и свойства, поддерживаемые объектом, в один интерфейс. После построения интерфейса IDL, его можно компилировать на любой нужный разработчику язык в форме кода "заглушки" или скелетного кода. Компиляторы IDL входят в комплект поставки всех ORB. Например, ORB под названием Visigenic VisiBroker for Java поставляется с компилятором Java/IDL, а Visigenic VisiBroker for C++ - с компилятором C++/IDL.

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

    Ознакомившись с данным разделом, читатель получит знания, достаточные для понимания примеров из нашей статьи. Для более подробного изучения этого вопроса можно обратиться к Web-узлу OMG (см. раздел "Источники информации").

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

    В Листинге 1 приведен простой модуль IDL под названием TheModule, содержащий базовый интерфейс TheInterface. В интерфейсе имеется одна целочисленная переменная (TheVariable).

    Листинг 1. Самый простой модуль IDL

    {
         interface TheInterface
         {
              long TheVariable;
         };
    };

    Скомпилировав данный модуль с использованием транслятора IDL-Java (например, idl2java компании Visigenic), получим интерфейс Java, приведенный в Листинге 2.

    Листинг 2. Эквивалент модуля TheModule на языке Java

    package TheModule;
    public interface TheInterface
    {
         public int TheVariable;
    }

    Апплет ORBQuery

    Вооружившись знанием основ ORB и IDL, мы можем заняться конструированием нашего первого апплета ORBQuery. Клиентская часть апплета будет состоять из стандартного графического интерфейса Java и обеспечивать создание экземпляра объекта CORBA на удаленной машине. По окончании этой операции, можно будет обращаться к методам этого объекта, чтобы задавать информацию о каких-то определенных ORB под CORBA. Чтобы извлечь информацию о необходимом ORB, на сервере надо задать пять методов: Name (название), Vendor (поставщик), Operating System (операционная система), Languages (языки) и URL. Таким образом, нам придется построить интерфейс IDL, где будут описаны пять методов. Именно такой интерфейс, ORBInfo, приведен в Листинге 3.

    Листинг 3. IDL-интерфейс ORBInfo

    module ORBQuery
    {
         interface ORBInfo
         {
              string GetName(in long index);
              string GetVendor(in long  index);
              string GetOS(in long index);
              string GetLanguages(in long  index);
              string GetURL(in long  index);
         };
    };

    Установив VisiBroker, пользователь получает в свое распоряжение idl2java - компилятор IDL, с помощью которого можно генерировать программный код на языке Java, реализующий данный интерфейс. После установки пакета, для генерации кода достаточно ввести следующую команду:

    idl2java ORBInfo.idl

    При этом будет создан подкаталог ORBQuery (по названию Java-пакета ORBQuery). В этом каталоге имеются восемь файлов: ORBInfo.java, ORBInfoHolder.java, ORBInfoHelper.java, _st_ORBInfo.java, _sk_ORBInfo.java, ORBInfoOperations.java, _tie_ORBInfo.java и _example_ORBInfo.java. Как вы, наверное, догадываетесь, в файле ORBInfo.java содержится Java-версия описания интерфейса ORBInfo. Но зачем нужны остальные классы? В файле ORBInfoHolder.java находится класс-контейнер (holder class), используемый при передаче параметров. В классе ORBInfoHelper определяются ряд полезных утилит, в классе _st_ORBInfo - заглушка для клиентской программы, а в классе _sk_ORBInfo - скелетный класс для сервера. Классы ORBInfoOperations и _tie_ORBInfo нужны для реализации механизма связей VisiBroker, в результате действия которого класс реализации может осуществлять наследование не только от скелетных классов. Наконец, _example_ORBInfo содержит пример серверного объекта, на основании которого можно построить приложение для сервера.

    Короче говоря, получившиеся восемь классов Java дают каркас (утилиты, заглушку, скелет и интерфейс) для построения своего собственного клиент-серверного приложения под CORBA на языке Java.

    Строим серверное приложение

    Далее, надо создать серверное приложение, которое будет регистрировать объект ORBInfo с серверным ORB. Этот новый объект служит расширением скелетного класса и также обеспечивает реализацию интерфейса ORBInfo. Итак, на сервере требуются два новых класса: один из них будет задавать серверный объект и обеспечивать реализацию интерфейса ORBInfo, а другой - регистрировать этот объект в серверном ORB. Класс ORBQuery содержит стандартный код Java, обеспечивающий извлечение элемента из массива и передачу его в вызывающую программу. Класс Server поддерживает функции, настроенные на работу с CORBA.

    В приведенном ниже примере вначале инициализируется ORB. Далее наш класс регистрируется в ORB; при этом там запоминается строка ORBInfo, которая впоследствии будет использоваться клиентским ПО при извлечении объекта. По завершении этих операций, мы сообщаем ORB о своей готовности, вызвав boa.obj_is_ready().

    В Листинге 4 описывается класс Server, обеспечивающий регистрацию объекта ORBInfo в ORB.

    Листинг 4. Класс Server.

    public static void main(String[] args) {
        try {
          // Инициализируем ORB.
          org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
          // Инициализируем BOA.
          org.omg.CORBA.BOA boa = orb.BOA_init();
          // Создаем ORBQuery.
          ORBQuery serverQuery = new ORBQuery("ORBInfo");
          // Экспортируем вновь созданный объект.
          boa.obj_is_ready(serverQuery);
          System.out.println(serverQuery + " is ready.");
          // Ждем запросов.
          boa.impl_is_ready();
        }
        catch(org.omg.CORBA.SystemException e) {
          System.err.println(e);
        }
      }
    }

    В Листинге 5 описывается класс ORBQuery, обеспечивающий реализацию интерфейса и пять методов-утилит.

    Листинг 5. Класс ORBQuery

    public static void main(String[] args) {
        try {
          // Инициализируем ORB.
          org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init();
          // Инициализируем BOA.
          org.omg.CORBA.BOA boa = orb.BOA_init();
          // Создаем ORBQuery.
          ORBQuery serverQuery = new ORBQuery("ORBInfo");
          // Экспортируем вновь созданный объект.
          boa.obj_is_ready(serverQuery);
          System.out.println(serverQuery + " is ready.");
          // Ждем запросов.
          boa.impl_is_ready();
        }
        catch(org.omg.CORBA.SystemException e) {
          System.err.println(e);
        }
      }
    }

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

    Создание апплета CORBA

    Точно так же, как серверный объект надо регистрировать в серверном ORB, клиентские апплеты и приложения должны пройти регистрацию в клиентском ORB. Когда клиенту понадобиться вызвать хранящиеся на удаленном компьютере объекты CORBA, он не сможет сделать это напрямую. Напротив, он должен будет сообщить клиентскому ORB, экземпляр какого объекта надо создать, а затем этот ORB запустит механизм взаимодействия между ORB. Запрос содержится в двух строчках (если работать с VisiBroker for Java):

    // Инициализируем ORB (с использованием апплета).
    org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(this);
    // Вызываем интерфейсный объект ORBInfo,
    который будет использоваться апплетом ORBInfoQuery= ORBQuery.ORBInfoHelper.bind(orb, "ORBInfo");

    После вызова метода bind() наша локальная переменная ORBInfoQuery оказывается "связанной" с серверным объектом ORBINfo. По окончании этой операции, мы можем вызывать утилиты для "заселения" нашего апплета. Напомним, что хотя в нашем примере мы пользовались только Java, серверный объект мог бы быть написан и на COBOL, C++, Ada или Smalltalk.

    При более детальном знакомстве с CORBA мы должны были бы еще рассказать о CORBAServices и о других схемах активизации объектов, которые согласуются со стандартом CORBA. Более детальную информацию можно получить на Web-узле OMG и в документах, перечисленных в разделе "Источники информации".

    Заключение

    Как мы видели, разработка апплетов Java для использования CORBA - дело несколько более сложное, чем построение простого апплета Java. На самом деле, это даже сложнее, чем создание "чистого" распределенного объектного приложения Java с использованием RMI. Тем не менее, применение Java в сочетании с CORBA дает возможность строить более масштабируемые и мощные приложения, чем те, что получаются при использовании одного JDK. Кроме того, в настоящее время имеется не так много приложений Java масштаба предприятия. Возможность использования (и надстройки) старого кода с использованием CORBA поможет разработчикам сохранить уже имеющийся код, не отказываясь при этом от использования полезных свойств языка Java.


    Брайан Морган (Bryan Morgan) - старший инженер компании TASC (http://www.tasc.com). Он применяет CORBA и Java для построения распределенных приложений обработки запросов в рамках внутреннего исследовательского проекта. Брайан - соавтор ряда книг, выпущенных издательством Sams, в частности, "Visual J++ Unleashed" и "Java Developer's Reference". С ним можно связаться по адресу bryan.morgan@javaworld.com

    Источники информации

  • Object Management Group дает исчерпывающую информацию о CORBA и IDL.
    http://www.omg.org
  • Подробную информацию о CORBA можно почерпнуть в книге Йона Зигеля "CORBA Fundamentals and Programming" (Wiley Computer Publishing Group, ISBN: 0-471-12148-7)
  • "Client/Server Programming With Java and CORBA" - великолепный справочник по CORBA и Java Роберта Орфэли и Дэна Харки (Wiley Computer Publishing Group, ISBN: 0-471-16351-1)
  • Visigenic VisiBroker for Java
    http://www.visigenic.com/
  • IONA Technologies OrbixWeb
    http://www.iona.com/
  • Sun Microsystems Neo
    http://www.sun.com/
  • Expersoft PowerBroker
    http://www.expersoft.com
  • IBM ComponentBroker
    http://www.software.ibm.com/ad/cb
  • Майкл Шофнер, обозреватель JawaWorld, излагает свой взгляд на то, как используется RMI для связи между сетями
    http://www.javaworld.com/javaworld/jw-10-1997/jw-10-step.html
  • Данную статью (на английском языке) и полный исходный текст программы можно получить в виде zip-файла по адресу:
    http://www.javaworld.com/javaworld/jw-10-1997/corbajava/jw-10-corbajava.zip

    Альтернативы распределенных объектов: DCOM и RMI

    Как правило, разработчики программ на Java больше знакомы с основными конкурентами CORBA - DCOM и RMI. Рассмотрим поподробнее каждую их этих технологий.

    CORBA: независимость и поддержка

    У этой технологии есть несколько важных достоинств, в частности, независимость от языка, производителя и операционной системы. ORB для CORBA в настоящее время имеются практически для любой серьезной операционной системы (например, CORBA может быть использован в большем числе операционных систем производства Microsoft, чем ее "родной" DCOM!). Существуют также CORBA ORB для организации взаимодействия между приложениями на различных языках, в частности, C++, Ada, COBOL, Smalltalk, Java. Использование IIOP позволяет ORB, разработанным одним производителем (например, Visigenic), получать объекты (и затем манипулировать ими) от удаленного ORB, созданного другим производителем (скажем, IONA). ORB на Java позволяют создавать Java- клиенты, не устанавливая какое бы то ни было специальное ПО на клиентской станции. (Классы Java ORB либо динамически загружаются вместе с апплетом, либо входят в состав браузера.)

    DCOM: скрытое преимущество Microsoft

    Разработанная Microsoft технология DCOM (Distributed Component Object Model) в настоящее время реализована только для двух операционных систем, Windows 95 и Windows NT. В сотрудничестве с рядом сторонних компаний Microsoft сейчас работает над переносом DCOM на другие операционные системы (в частности, на некоторые версии Unix и MVS). DCOM, как и CORBA, не зависит от языка; все объекты в нем описываются через интерфейсы, написанные на предложенном Microsoft языке ODL (Object Description Language).

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

    Разработчик, написавший апплет или приложение Java для обращения к объектам DCOM на сервере, автоматически ограничивает область применения клиентского ПО браузером Internet Explorer от Microsoft и платформами Windows 95/NT. Данное ограничение, безусловно, обедняет возможности использования приложений, размещаемых на Web. Однако у DCOM есть и одно серьезное достоинство: эта технология бесплатна для всех пользователей Windows 95/NT. Как мы не раз имели возможность убедиться, подобные маркетинговые приемы делают Microsoft очень трудным конкурентом.

    RMI: решение Sun на основе Java

    Технология RMI (Remote Method Invocation) - составная часть последней версии комплекта разработки JDK 1.1. RMI позволяет клиентам Java создавать экземпляры объектов, находящихся на удаленном сервере. Не правда ли, похоже на CORBA? А вот и нет. Штука в том, что серверное приложение тоже должно быть написано на Java, и в нем должны использоваться инструментальные средства, входящие в комплект поставки JDK 1.1. Помимо невозможности использовать существующий программный код, у RMI есть и другие ограничения.

    В отличие от CORBA, в RMI нет понятия сервиса. Кроме того, серверные объекты, написанные на Java с использованием RMI, дают низкую производительность из-за ограничений, связанных с использованием виртуальной машины Java. (проверено, что серверные приложения CORBA на Java работают быстрее, чем аналогичные приложения, использующие RMI.) Кроме того, RMI не дает возможности устанавливать правила активизации объектов, как это делается в ORB.

    На самом деле, скорее всего RMI и соответствующие части технологии Java будут мигрировать в сторону стандартов OMG, а не наоборот. Sun уже объявила, что Java Transaction Service будет строиться на основе технологии Object Transaction Service, разработанной OMG. Кроме того, Sun публично объявила, что будет стремиться к обеспечению возможности для объектов RMI взаимодействовать через IIOP.

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