Spec-Zone .ru
спецификации, руководства, описания, API
Содержание документации

Java IDL and Java RMI-IIOP Technologies: Используя Переносимые Перехватчики (PI)

Последнее обновление: 25.04.2002

ЗАМЕТЬТЕ: Этот документ предназначается для усовершенствованных разработчиков CORBA.

Посредник запросов к объектам CORBA Java (ШАР) обеспечивает рычаги, или точки перехвата, через которые службы ШАРА могут прервать нормальный поток выполнения ШАРА. Эти Переносимые Перехватчики обеспечивают механизм для того, чтобы он включил дополнительное поведение ШАРА, или, изменяя связь между клиентом и сервером, для того, чтобы изменить поведение ШАРА. Пример, который следует за шоу различные способы использовать Переносимые Перехватчики.

Поддержка Переносимых Перехватчиков является главным недавним дополнением к спецификации CORBA. Используя RequestInterceptors, можно легко записать и присоединить переносимые рычаги ШАРА, которые прервут любой УСТАНОВЛЕННЫЙ ШАРОМ вызов. Используя IORInterceptors, можно записать код, чтобы аннотировать ссылки на объект CORBA.

Это настоятельно рекомендуется это, Вы читаете Переносимую Спецификацию Перехватчиков в ptc/2001-03-04 прежде, чем считать этот документ.

Следующие темы включаются в этот документ:

Типы перехватчика

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

Регистрация ORBInitializers в Java

ORBInitializer интерфейс облегчает регистрацию перехватчика и инициализацию ШАРА.

Перехватчики предназначаются, чтобы быть средством, которым службы ШАРА получают доступ к обработке ШАРА, эффективно становясь частью ШАРА. Так как перехватчики являются частью ШАРА, когда ORB.init возвращает ШАР, перехватчики должны быть зарегистрированы. Перехватчики не могут быть зарегистрированы на ШАРЕ после того, как он был возвращен звонком ORB.init.

ORBInitializers регистрируются через свойства ORB Java. Перехватчик регистрируется, регистрируя связанное ORBInitializer объект, который реализует ORBInitializer интерфейс. Когда ШАР инициализирует, он должен вызвать, каждый зарегистрировался ORBInitializer, передача этого ORBInitInfo объект, который используется, чтобы зарегистрировать его перехватчик.

Имена свойства имеют форму:

org.omg.PortableInterceptor.ORBInitializerClass.<Service>

где <Service> имя строки class, который реализует

org.omg.PortableInterceptor.ORBInitializer
Чтобы избежать коллизий имени, обратное соглашение о присвоении имен DNS должно использоваться. Например, если компания Example имеет три инициализатора, это могло определить следующие свойства:

Отметьте: Любые значения, связанные с ORBInitializerClass свойства игнорируются.

Во время ORB.init, эти свойства ORB, которые начинаются org.omg.PortableInterceptor.ORBInitializerClass буду собран, <Service> часть каждого свойства должна быть извлечена, объект нужно инстанцировать с <Service> представьте в виде строки как его имя class, и pre_init и post_init к методам нужно обратиться тот объект. Если будут какие-либо исключения, то ШАР должен проигнорировать их и продолжиться.

Примечания О Контексте Перехватчиков

Примечания по Порядку Перехватчика

Примечания о Регистрирующихся Перехватчиках

Переносимый Ток Перехватчика (PICurrent)

Объект PortableInterceptor::Current (в дальнейшем именуемый PICurrent) является объектом Current, который используется определенно переносимыми Перехватчиками, чтобы передать контекстную информацию потока контексту запроса. Переносимые Перехватчики не обязаны использовать PICurrent, но если информация от контекста потока клиента запрашивается в точках перехвата Перехватчика, то PICurrent может использоваться, чтобы распространить ту информацию. PICurrent позволяет переносимому служебному коду быть записанным независимо от модели потоков ШАРА.

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

Получение PICurrent

Прежде, чем вызов делается, PICurrent получается через звонок в ORB::resolve_initial_references ( PICurrent ). Изнутри точек перехвата данные на PICurrent, который переместился от контекста потока до контекста запроса, доступны через работу get_slot на объекте RequestInfo. PICurrent может все еще быть получен через resolve_initial_references, но это - контекст потока Перехватчика PICurrent.

Контекст запроса по сравнению с Контекстом Потока

PICurrent контекста потока (TSC) является PICurrent, который существует в пределах контекста потока. Контекстом запроса PICurrent (RSC) является PICurrent, связанный с запросом. На стороне клиента контекст потока PICurrent логически копируется в контекст запроса PICurrent от потока s контекст, когда запрос начинает и присоединен к объекту ClientRequestInfo. На стороне сервера контекст запроса PICurrent присоединен к ServerRequestInfo и следует за обработкой запросов. Это логически копируется в контекст потока PICurrent после того, как список точек перехвата receive_request_service_contexts обрабатывается. См. Обновленную спецификацию Перехватчиков, Раздел, 21.4.4.5, Поток PICurrent между Контекстами для детального обсуждения контекста PICurrent.

Переносимый Пример Перехватчика

Этот раздел содержит пример, регистрирующий сервисное приложение. Пример кода для этого приложения вполне усложняется, потому что это покрывает даже тонкие "угловые случаи". Следующие сценарии покрываются этим примером приложения:

  1. Служба журналирования, которая регистрирует вызовы. Ни клиент, ни сервер явно не используют службу журналирования.
  2. "Пустая" служба, которая передает информацию от клиента к серверу. Клиент и сервер явно использует эту службу, но не знает, что это реализуется, используя перехватчики.

Отметьте: Эти примеры явно регистрируют ORBInitializers, чтобы сделать код легче экспериментировать с и установка. Обычно это не было бы сделано. Вместо этого эту информацию передали бы как свойства -D к виртуальной машине Java, когда приложения запускаются. Тем путем приложения не связываются с фактом, что любой, служба существует (например, служба журналирования) или что служба, которую они явно используют (например, интерфейс AService) реализуется как перехватчик.

Цель примера службы журналирования состоит в том, чтобы показать, как избежать бесконечной рекурсии, делая outcalls (то есть, вызовы на ссылках CORBA) изнутри точек перехвата. Это, оказывается, вполне включается, когда все угловые случаи покрываются.

Цель "пустого" примера службы состоит в том, чтобы показать, как реализовать службы, которые текут контекстная информация от клиента к серверу и назад.

Плавная Контекстная информация между Клиентами и серверами

Типичная служба на основе перехватчика будет течь контекстная информация между клиентами и серверами. Пример AService показывает, как эта информация течется от клиентского потока в клиентские перехватчики, через провод в перехватчики сервера, к потоку слуги и назад.

Важно отметить, что ни клиент, ни слуга не знают, что служба реализуется, используя перехватчики. Вместо этого они взаимодействуют со службой через локальные ссылки на объект (ссылка aService в этом примере).

Схема AService

Схема AService

Описание шагов схемы AService:

  1. Клиент вызывает aService.begin().

    1.a. aService.begin() устанавливает контекстную информацию службы в слоте, который это зарезервировало в PICurrent.

  2. Клиент вызывает метод на некоторую ссылку (то есть, ref.method()). Этот вызов имеет место в контексте службы, так как aService.begin() был вызван.
  3. send_request вводится для ref.method call.
  4. get_effective_component(s) можно вызвать, чтобы определить если ссылка, вызываемая потребности взаимодействовать со службой.
  5. get_slot вызывают, чтобы получить набор контекста в шаге 1a. Набор слотов в PICurrent логически копируется и делается доступный для ClientRequestInfo.
  6. Перехватчик службы добавляет контекст службы, содержащий соответствующий контекст (наиболее вероятно в зависимости от набора контекста в шаге 1a и любых компонентах, полученных в шаге 4). Это использует add_request_service_context, чтобы добавить эту контекстную информацию к запросу, который отправляется по проводу.
  7. ref.method request достигает сервера, активируя точку перехвата receive_request_service_contexts.
  8. get_request_service_context используется, чтобы получить контекст службы, добавленный в шаге 6.
  9. ServerRequestInfo.set_slot используется, чтобы передать контекстную информацию от контекста службы, полученного в шаге 8 к логическим локальным данным потока.
  10. receive_request вводится.
  11. "Касательно" "метода" Слуги вводится.
  12. Метод слуги вызывает aService.verify(), чтобы взаимодействовать со службой.
  13. Служба использует get_slot на PICurrent, чтобы получить контекстную информацию, отправленную от стороны клиента. Служба может также использовать set_slot на PICurrent, чтобы установить любую контекстную информацию возврата.
  14. После того, как Слуга завершается, точка перехвата send_* вводится. Если бы набор службы контекстная информация возврата, это добавило бы контекст службы к возврату. Это не показывают в этом примере.
  15. Когда ответ достигает клиента, точка перехвата receive_* вводится. Если бы набор службы контекстная информация возврата, это было бы получено в этой точке. Это не показывают в этом примере.

Уход от Бесконечной рекурсии Во время Перехватчика Outcalls

Некоторые службы, возможно, должны сделать вызовы на других ссылках на объект CORBA изнутри точек перехвата. Делая outcalls изнутри точек перехвата, шаги должны быть сделаны, чтобы избежать бесконечной рекурсии, так как те outcalls будут течь через точки перехвата. Пример LoggingService иллюстрирует этот случай.

LoggingService example состоит из ClientRequestInterceptors, зарегистрированного в клиентской программе, и ServerRequestInterceptors, зарегистрированном в программе сервера. Эти перехватчики отправляют информацию от клиента и сервера до LoggingService implemenation, который регистрирует эту информацию.

Однако, так как реализация LoggingService является самостоятельно сервером CORBA, мы должны гарантировать, что не регистрируем звонки в регистратор. Следующие схемы иллюстрируют шаги, сделанные, чтобы избежать бесконечной рекурсии.

Следующая схема показывает самый простой случай ухода от рекурсии, вызывая внешний регистратор изнутри перехватчиков. Эти шаги полезны для случая, где клиентский ШАР только содержит ClientRequestInterceptors, ШАР сервера только содержит ServerRequestInterceptors, и LoggingService является внешним обоим ШАРЫ клиента и сервера.

Схема LoggingService

Журналирование схемы Службы

Описание шагов схемы LoggingService:

  1. Клиент вызывает метод на некоторую ссылку.
  2. Клиентский метод send_request перехватчика вводится для метода, вызванного в шаге 1.
  3. Слот, зарезервированный для того, чтобы указать на outcall, устанавливается в true на PICurrent.
  4. Тот же самый слот проверяется на ClientRequestInfo через get_slot. Это значение не будет установлено, так как оно представляет состояние потока клиента в шаге 1. Поэтому звонок в регистратор будет сделан.
  5. send_request рекурсивно вводится для вызова регистратора, сделанного в шаге 4.
  6. Слот, зарезервированный для того, чтобы указать на outcall, устанавливается в true на PICurrent. Отметьте, этот слот всегда безоговорочно устанавливается. Это необходимо, когда есть 2 или больше перехватчика, делающие outcalls. Так как перехватчики не знают о существовании других перехватчиков, мы всегда устанавливаем слот PICurrent.
  7. Слот проверяется на ClientRequestInfo через get_slot. На сей раз значение устанавливается (от шага 3). Поэтому мы не регистрируем этот вызов (который является звонком в регистратор непосредственно). Точка send_request, которая вошла в концах шага 5.
  8. ШАР отправляет вызов журнала, сделанный в шаге 4 к службе журналирования.
  9. Точка send_request для концов шага 2. ШАР отправляет начальный клиентский вызов, сделанный в шаге 1 к серверу для соответствующей ссылки.
  10. Точка receive_request_service_contexts сервера вводится. Это регистрирует входящий запрос. Сервер, который не содержит клиентские перехватчики, которые делают outcalls и которые не содержат реализацию самого регистратора, не должен установить слоты предотвращения рекурсии. Именно это представляет эта схема.
  11. -  13.   Поэтому все серверные точки перехвата вводятся без дальнейшей проверки, и ответ от метода, первоначально вызванного клиентом, возвращается к клиентскому ШАРУ.
  12. Точка receive_* клиента вводится. Шаги, подобные шагам 2 - 9, произойдут, если эта точка должна сделать outcall.

Уход от Рекурсии для Колокэтеда Ауткола Референсеса

Следующая схема иллюстрирует случай, где LoggingService может быть colocated в том же самом ШАРЕ как ссылка, вызываемая клиентом. Вообще, не возможно знать, что определенная ссылка на объект НЕ является colocated с любыми другими объектами, размещенными тем ШАРОМ. Поэтому, чтобы покрыть все угловые случаи, больше шагов должно быть сделано.

Эта схема показывает только сторону сервера. Клиентские шаги идентичны тем в предыдущей схеме.

Схема LoggingServiceColocated

Схема LoggingServiceColocated

Описание шагов схемы LoggingServiceColocated:

  1. Запрос от клиентского ШАРА прибывает, активируя точку перехвата receive_request_service_contexts.
  2. Слот, зарезервированный для того, чтобы указать на outcall, устанавливается в true на PICurrent.
  3. ServerRequestInfo.get_request_service_context используется, чтобы проверить на присутствие контекста службы, указывающего на outcall. Контекст службы не присутствует так, регистратор вызывается изнутри точки перехвата.
  4. Точка перехвата send_request вводится для запроса регистратора.
  5. get_slot проверяет на outcall индикатор.
  6. outcall слот индикатора был установлен (от шага 2), поэтому add_request_service_context привык к контексту службы, указывающему на outcall. Это необходимо, так как нет никакого логического отношения между потоками клиента и сервера.
  7. Вызов регистратора достигает receive_request_service_contexts.
  8. Слот, зарезервированный для того, чтобы указать на outcall, устанавливается в true на PICurrent.
  9. ServerRequestInfo.get_request_service_context используется, чтобы проверить на присутствие контекста службы, указывающего на outcall. Контекст службы присутствует так, никакие дальнейшие меры не предпринимаются. выходы receive_request_service_contexts.
  10. Запрос регистратора продолжается к receive_request. Шаги, подобные тем, которые включенный receive_request_service_context необходим, если регистратор вызывают в receive_request point (это не показывают в схеме (хотя пример кода регистрирует все точки)).
  11. Запрос регистратора достигает Слуги LoggingService, который регистрирует начальный клиентский запрос (не вызов регистратора).
  12. Запрос регистратора продолжается к ServerRequestInterceptor.send_* (наиболее вероятный send_reply).
  13. Запрос регистратора продолжается к ClientRequestInterceptor.receive_* (наиболее вероятный receive_reply).

    После Шага 13 будет обслуживаться исходный запрос, который кончил в Шаге 3.

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

Избегите рекурсии при использовании многократных ШАРОВ

Более простой способ избежать рекурсии состоит в том, чтобы гарантировать, что outcall ссылки связываются с различным ШАРОМ, которому не регистрировали перехватчики журналирования. Тем путем outcall вызовы никогда не проходят через перехватчики.

Это походит на простое решение, но, вообще, перехватчики регистрируются через свойства, которые передают к VM во время запуска. Это означает, что все ШАРЫ, создаваемые, в котором VM будет содержать все перехватчики так это решение, не будут работать.

Это решение будет только работать, где перехватчики явно регистрируются в клиентском коде во время ORB.init. Однако, это не ни типичное, ни рекомендуемый способ зарегистрировать службы на основе перехватчиков.

Пример кода

Следующие файлы содержат код, который иллюстрируют вышеупомянутые схемы. Инструкции для компиляции и выполнения этих примеров следуют за кодом. Файлы, включенные в этот пример:

serviceexample.idl

Это - Язык определения интерфейсов (IDL) файл, который содержит определения произвольного объекта, на котором можно сделать вызовы и две службы, которые обслужат звонки в произвольный объект.


// serviceexample.idl
// Copyright and License 

module pi
{
module serviceexample
{

    // Create some arbitrary object to call.  Those calls
    // will be serviced by the service implemented using interceptors.

    exception ArbitraryObjectException { string reason; };

    interface ArbitraryObject
    {
             string         arbitraryOperation1 ( in string a1 );

        oneway void         arbitraryOperation2 ( in long a1 );

               void         arbitraryOperation3 ( in string a1 )
                                raises (ArbitraryObjectException);
    };


    // This would typically be in a file separate from the "ArbitraryObject"
    // and probably unknown to it.

    interface LoggingService
    {
        void log ( in string a1 );
    };

    // This would also typically be in a file of its own.
    // IMPORTANT: the interface should be a local object to avoid
    // unnecessary overhead.
    
    /*local*/ interface AService
    {
        void begin();
        void end();
        void verify();
    };

    // Tagged component for adding to an IOR to indicate that
    // the AService must be in effect when invocations are made 
    // on the object containing this tagged component.

    // Note: we explicitly declare the tag type rather than using
    // the IOP typedef (commented out) to simplify compiling this
    // example (i.e., to avoid includes and make include path directives).
    //const IOP::ComponentId TAG_ASERVICE_COMPONENT = 2345;
    const unsigned long TAG_ASERVICE_COMPONENT = 2345;

    struct ASERVICE_COMPONENT {
        boolean requiresAService;
    };

}; // module serviceexample

}; // module pi

LoggingServiceClientORBInitializer.java

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


// LoggingServiceClientORBInitializer.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.PortableInterceptor.Current;
import org.omg.PortableInterceptor.CurrentHelper;
import org.omg.PortableInterceptor.ORBInitInfo;

public class LoggingServiceClientORBInitializer 
    extends org.omg.CORBA.LocalObject
    implements org.omg.PortableInterceptor.ORBInitializer
{
    public void pre_init(ORBInitInfo info)
    {
    }

    public void post_init(ORBInitInfo info)
    {
        try {

            // Get a reference to the LoggingService object.

            NamingContext nameService = 
                NamingContextHelper.narrow(
                    info.resolve_initial_references("NameService"));

            NameComponent path[] =
                { new NameComponent("LoggingService", "") };
            LoggingService loggingService = 
                LoggingServiceHelper.narrow(nameService.resolve(path));

            // Get a reference to TSC PICurrent.

            Current piCurrent =
                CurrentHelper.narrow(
                    info.resolve_initial_references("PICurrent"));

            // Allocate a slot id to use for the interceptor to indicate
            // that it is making an outcall.  This is used to avoid
            // infinite recursion.

            int outCallIndicatorSlotId = info.allocate_slot_id();

            // Create (with the above data) and register the client
            // side interceptor.

            LoggingServiceClientInterceptor interceptor =
                new LoggingServiceClientInterceptor(loggingService, 
                                                    piCurrent,
                                                    outCallIndicatorSlotId);

            info.add_client_request_interceptor(interceptor);
        } catch (Throwable t) {
            System.out.println("Exception handling not shown.");
        }
    }
}

LoggingServiceClientInterceptor.java

Этот перехватчик регистрирует клиентские точки перехвата. Это иллюстрирует, как сделать вызовы на других объектах изнутри перехватчика и как избежать бесконечной рекурсии во время тех "outcall" вызовов.


// LoggingServiceClientInterceptor.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CORBA.Any;
import org.omg.CORBA.ORB;
import org.omg.CORBA.TCKind;
import org.omg.IOP.ServiceContext;
import org.omg.PortableInterceptor.ClientRequestInterceptor;
import org.omg.PortableInterceptor.ClientRequestInfo;
import org.omg.PortableInterceptor.Current;
import org.omg.PortableInterceptor.InvalidSlot;

public class LoggingServiceClientInterceptor
    extends org.omg.CORBA.LocalObject
    implements ClientRequestInterceptor
{
    private LoggingService loggingService;
    private Current piCurrent;
    private int outCallIndicatorSlotId;

    public LoggingServiceClientInterceptor(LoggingService loggingService,
                                           Current piCurrent,
                                           int outCallIndicatorSlotId)
    {
        this.loggingService = loggingService;
        this.piCurrent = piCurrent;
        this.outCallIndicatorSlotId = outCallIndicatorSlotId;
    }

    //
    // Interceptor operations
    //

    public String name() 
    {
        return "LoggingServiceClientInterceptor";
    }

    public void destroy() 
    {
    }

    //
    // ClientRequestInterceptor operations
    //

    public void send_request(ClientRequestInfo ri)
    {
        log(ri, "send_request");
    }

    public void send_poll(ClientRequestInfo ri)
    {
        log(ri, "send_poll");
    }

    public void receive_reply(ClientRequestInfo ri)
    {
        log(ri, "receive_reply");
    }

    public void receive_exception(ClientRequestInfo ri)
    {
        log(ri, "receive_exception");
    }

    public void receive_other(ClientRequestInfo ri)
    {
        log(ri, "receive_other");
    }

    //
    // Utilities.
    //

    public void log(ClientRequestInfo ri, String point)
    {
        // IMPORTANT: Always set the TSC out call indicator in case
        // other interceptors make outcalls for this request.
        // Otherwise the outcall will not be set for the other interceptor's
        // outcall resulting in infinite recursion.

        Any indicator = ORB.init().create_any();
        indicator.insert_boolean(true);
        try {
            piCurrent.set_slot(outCallIndicatorSlotId, indicator);
        } catch (InvalidSlot e) { }

        try {
            indicator = ri.get_slot(outCallIndicatorSlotId);

            // If the RSC out call slot is not set then log this invocation.
            // If it is set that indicates the interceptor is servicing the
            // invocation of loggingService itself.  In that case do
            // nothing (to avoid infinite recursion).

            if (indicator.type().kind().equals(TCKind.tk_null)) {
                loggingService.log(ri.operation() + " " + point);
            }
        } catch (InvalidSlot e) {
            System.out.println("Exception handling not shown.");            
        }
    }
}

LoggingServiceServerORBInitializer.java

Этот файл создает и регистрирует перехватчик службы журналирования, используемый объектными серверами. Даже при том, что этот перехватчик предназначается, чтобы только зарегистрировать серверные точки перехвата, это - оба перехватчик клиента и сервера. Код иллюстрирует, как избежать бесконечной рекурсии в случае, где вызываемый объект является colocated в том же самом ШАРЕ, в котором регистрируются перехватчики.

// LoggingServiceServerORBInitializer.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.PortableInterceptor.Current;
import org.omg.PortableInterceptor.CurrentHelper;
import org.omg.PortableInterceptor.ORBInitInfo;

public class LoggingServiceServerORBInitializer 
    extends org.omg.CORBA.LocalObject
    implements org.omg.PortableInterceptor.ORBInitializer
{
    public void pre_init(ORBInitInfo info)
    {
    }

    public void post_init(ORBInitInfo info)
    {
        try {

            // Create and register the logging service interceptor.
            // Give that interceptor references to the NameService and
            // PICurrent to avoid further lookups (i.e., optimization).
            // More importantly, allocate and give the interceptor
            // a slot id which is will use to tell itself not to
            // log calls that the interceptor makes to the logging process.

            NamingContext nameService = 
                NamingContextHelper.narrow(
                    info.resolve_initial_references("NameService"));

            Current piCurrent =
                CurrentHelper.narrow(
                    info.resolve_initial_references("PICurrent"));

            int outCallIndicatorSlotId = info.allocate_slot_id();

            LoggingServiceServerInterceptor interceptor =
                new LoggingServiceServerInterceptor(nameService,
                                                    piCurrent,
                                                    outCallIndicatorSlotId);

            info.add_client_request_interceptor(interceptor);
            info.add_server_request_interceptor(interceptor);
        } catch (Throwable t) {
            System.out.println("Exception handling not shown.");
        }
    }
}

LoggingServiceServerInterceptor.java

Этот перехватчик регистрирует серверные точки перехвата, и реализуется и как ClientRequestInterceptor и как ServerRequestInterceptor, чтобы иллюстрировать потребность установить, некоторые "вызывают" данные контекста службы (в дополнение к установке слот вызова), чтобы избежать бесконечной рекурсии для случая, отмеченного в описании LoggingServiceServerORBInitializer.java.


// LoggingServiceServerInterceptor.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.ORB;
import org.omg.CORBA.TCKind;
import org.omg.IOP.ServiceContext;
import org.omg.PortableInterceptor.ClientRequestInterceptor;
import org.omg.PortableInterceptor.ClientRequestInfo;
import org.omg.PortableInterceptor.Current;
import org.omg.PortableInterceptor.InvalidSlot;
import org.omg.PortableInterceptor.ServerRequestInterceptor;
import org.omg.PortableInterceptor.ServerRequestInfo;

public class LoggingServiceServerInterceptor
    extends org.omg.CORBA.LocalObject
    implements ClientRequestInterceptor,
               ServerRequestInterceptor
{
    private NamingContext nameService;
    private LoggingService loggingService;
    private Current piCurrent;
    private int outCallIndicatorSlotId;
    private static final int serviceContextId = 100001;
    private static final byte[] serviceContextData = {1};

    // Returns a reference to the logging process.

    private LoggingService loggingService()
    {
        if (loggingService == null) {
            NameComponent path[] =
                { new NameComponent("LoggingService", "") };
            try {
                loggingService = 
                    LoggingServiceHelper.narrow(nameService.resolve(path));
            } catch (Throwable t) {
                System.out.println("Exception handling not shown.");
            }
        }
        return loggingService;
    }

    public LoggingServiceServerInterceptor(NamingContext nameService,
                                           Current piCurrent,
                                           int outCallIndicatorSlotId)
    {
        this.nameService = nameService;
        this.piCurrent = piCurrent;
        this.outCallIndicatorSlotId = outCallIndicatorSlotId;
    }

    //
    // Interceptor operations
    //

    public String name() 
    {
        return "LoggingServiceServerInterceptor";
    }

    public void destroy() 
    {
    }

    //
    // ClientRequestInterceptor operations
    //

    public void send_request(ClientRequestInfo ri)
    {

        // If the server interceptor sets the recursion slot then
        // put in the service context so the server doesn't make
        // the call again in the case where the server side interceptor
        // is colocated in the same ORB as the object being invoked.

        try {
            Any indicator = ri.get_slot(outCallIndicatorSlotId);
            if (indicator.type().kind().equals(TCKind.tk_boolean)) {
                ServiceContext serviceContext =
                    new ServiceContext(serviceContextId, serviceContextData);
                ri.add_request_service_context(serviceContext, false);
            }
        } catch (InvalidSlot e) {
            System.out.println("Exception handling not shown.");
        }
    }

    public void send_poll(ClientRequestInfo ri)
    {
    }

    public void receive_reply(ClientRequestInfo ri)
    {
    }

    public void receive_exception(ClientRequestInfo ri)
    {
    }

    public void receive_other(ClientRequestInfo ri)
    {
    }

    //
    // ServerRequestInterceptor operations
    //

    public void receive_request_service_contexts(ServerRequestInfo ri)
    {
        log(ri, "receive_request_service_contexts");
    }

    public void receive_request(ServerRequestInfo ri)
    {
        log(ri, "receive_request");
    }

    public void send_reply(ServerRequestInfo ri)
    {
        log(ri, "send_reply");
    }

    public void send_exception(ServerRequestInfo ri)
    {
        log(ri, "send_exception");
    }

    public void send_other(ServerRequestInfo ri)
    {
        log(ri, "send_other");
    }

    //
    // Utilities.
    //

    public void log(ServerRequestInfo ri, String point)
    {
        // This is only relevant for the colocated example.
        // Do not attempt to log until the logging service object
        // has been bound in naming.  Otherwise the attempt to call
        // rebind on naming will call log which will fail.
        if (! ColocatedServers.colocatedBootstrapDone) {
            return;
        }

        // IMPORTANT:
        // The conditional logging of the invocation is only necessary
        // if there is a chance that the object being invoked is colocated
        // in the same ORB as this interceptor.  Otherwise the outcall to 
        // the logging service can be made unconditionally.

        // Always set the recursion slot.

        Any indicator = ORB.init().create_any();
        indicator.insert_boolean(true);
        try {
            piCurrent.set_slot(outCallIndicatorSlotId, indicator);
        } catch (InvalidSlot e) {
            System.out.println("Exception handling not shown.");
        }

        // Make the out call if you have not already done so.

        try {

            // Only the presence of the service context counts.
            // The data is ignored.

            ri.get_request_service_context(serviceContextId);
        } catch (BAD_PARAM e) {
            // Recursion indicator not set so make the call.
            loggingService().log(ri.operation() + " " + point);
        }
    }
}

LoggingServiceImpl.java

Этот файл является реализацией объекта журналирования, которому перехватчики службы журналирования отправляют свои данные.

// 
// Copyright and License 

package pi.serviceexample;

import org.omg.CORBA.ORB;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.PortableServer.POAHelper;

import java.util.Properties;

class LoggingServiceImpl
    extends LoggingServicePOA
{
    public static ORB orb;

    //
    // The IDL operations.
    //

    public void log(String a1)
    {
        System.out.println(a1);
    }

    //
    // The server.
    //

    public static void main(String[] av)
    {
        try {
            if (orb == null) {
                orb = ORB.init(av, null);
            }
            
            POA rootPOA =  POAHelper.narrow( orb.resolve_initial_references("RootPOA"));
            rootPOA.the_POAManager().activate();
            
            byte[] objectId =
                rootPOA.activate_object(new LoggingServiceImpl());
            org.omg.CORBA.Object ref = rootPOA.id_to_reference(objectId);

            NamingContext nameService = 
                NamingContextHelper.narrow(
                    orb.resolve_initial_references("NameService"));
            NameComponent path[] =
                { new NameComponent("LoggingService", "") };
            nameService.rebind(path, ref);

            // Only relevant for colocated example.
            ColocatedServers.colocatedBootstrapDone = true;

            System.out.println("LoggingService ready.");

            orb.run();

        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
        System.exit(0);
    }
}

AServiceORBInitializer.java

Файл создает и регистрирует AServiceInterceptor и как перехватчик клиента и сервера, создает и регистрирует AServiceIORInterceptor, который помещает TaggedComponent в IORs, и создает локальный объект, который будет использоваться приложениями, чтобы явно управлять услугами, предложенными AService. Этот локальный объект регистрируется как начальная служба с ШАРОМ так, что, это может быть получено клиентами, использующими org.omg.CORBA.ORB.resolve_initial_references.

// AServiceORBInitializer.java
// Copyright and License 

package pi.serviceexample;

import org.omg.IOP.Codec;
import org.omg.IOP.CodecFactory;
import org.omg.IOP.CodecFactoryHelper;
import org.omg.IOP.Encoding;
import org.omg.PortableInterceptor.Current;
import org.omg.PortableInterceptor.CurrentHelper;
import org.omg.PortableInterceptor.ORBInitInfo;


public class AServiceORBInitializer 
    extends org.omg.CORBA.LocalObject
    implements org.omg.PortableInterceptor.ORBInitializer
{
    private AServiceImpl aServiceImpl;
    private AServiceInterceptor aServiceInterceptor;

    public void pre_init(ORBInitInfo info)
    {
        try {
            int id = info.allocate_slot_id();

            aServiceInterceptor = new AServiceInterceptor(id);

            info.add_client_request_interceptor(aServiceInterceptor);
            info.add_server_request_interceptor(aServiceInterceptor);

            // Create and register a reference to the service to be
            // used by client code.

            aServiceImpl = new AServiceImpl(id);

            info.register_initial_reference("AService", aServiceImpl);

        } catch (Throwable t) {
            System.out.println("Exception handling not shown.");
        }
    }

    public void post_init(ORBInitInfo info)
    {
        try {

            Current piCurrent =
                CurrentHelper.narrow(
                    info.resolve_initial_references("PICurrent"));
            aServiceImpl.setPICurrent(piCurrent);

            CodecFactory codecFactory =
                CodecFactoryHelper.narrow(
                    info.resolve_initial_references("CodecFactory"));
            Encoding encoding = new Encoding((short)0, (byte)1, (byte)2);
            Codec codec = codecFactory.create_codec(encoding);
            aServiceInterceptor.setCodec(codec);
            
            AServiceIORInterceptor aServiceIORInterceptor =
                new AServiceIORInterceptor(codec);
            info.add_ior_interceptor(aServiceIORInterceptor);

        } catch (Throwable t) {
            System.out.println("Exception handling not shown.");
        }
    }

}

AServiceImpl.java

Этот файл содержит объект, который явно используется кодом клиента и слуги, чтобы связаться со службой. Когда клиент вызывает begin() на службе, служба заставляет ServiceID, определенный для службы быть помещенным в слот PICurrent TSC, зарезервированный этой службой. Когда клиент вызывает end() на службе, он устанавливает слот TSC в недопустимое значение, чтобы указать, что служба не в действительности. Слуги используют метод verify(), чтобы определить, передали ли ServiceID от стороны клиента до стороны сервера.

// 
// Copyright and License 

package pi.serviceexample;

import org.omg.CORBA.Any;
import org.omg.CORBA.TCKind;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.ORB;
import org.omg.PortableInterceptor.Current;
import org.omg.PortableInterceptor.InvalidSlot;

class AServiceImpl
    extends LocalObject
    implements AService
{
    private int slotId;

    private int currentServiceId = 0;

    private Current piCurrent;

    private Any NOT_IN_EFFECT;

    public AServiceImpl(int slotId)
    {
        this.slotId = slotId;
        NOT_IN_EFFECT = ORB.init().create_any();
    }

    // Package protected so the AService ORBInitializer can access this
    // non-IDL defined method.
    void setPICurrent(Current piCurrent)
    {
        this.piCurrent = piCurrent;
    }

    public void begin()
    {
        Any any = ORB.init().create_any();
        any.insert_long(++currentServiceId);
        setSlot(any);
    }

    public void end()
    {
        setSlot(NOT_IN_EFFECT);
    }

    public void verify()
    {
        try {
            Any any = piCurrent.get_slot(slotId);
            if (any.type().kind().equals(TCKind.tk_long)) {
                System.out.println("Service present: " + any.extract_long());
            } else {
                System.out.println("Service not present");
            }
        } catch (InvalidSlot e) {
            System.out.println("Exception handling not shown.");
        }
    }

    // Synchronized because two threads in the same ORB could be
    // sharing this object.
    synchronized private void setSlot(Any any)
    {
        try {
            piCurrent.set_slot(slotId, any);
        } catch (InvalidSlot e) {
            System.out.println("Exception handling not shown.");
        }
    }
}

AServiceInterceptor.java

Этот перехватчик ответственен за расположение передать сторону клиента информация о AService стороне службы.

На стороне клиента, если AService.begin() вызвали, точка send_request(ri) будет видеть идентификатор службы в слоте RSC. В этом случае это вставляет значение того идентификатора службы в org.omg.CORBA.ServiceContext и добавляет что контекст службы к данным, которые передадут наряду с вызовом.

На стороне сервера receive_request_service_context(ri) ищет присутствие того контекста службы. Когда существующий, это извлекает значение идентификатора службы из ServiceContext и устанавливает слот RSC в то значение. Когда слуга выполняется, значение которого слот RSC доступен в слоте TSC.


// AServiceInterceptor.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CORBA.Any;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.ORB;
import org.omg.CORBA.TCKind;
import org.omg.IOP.Codec;
import org.omg.IOP.CodecPackage.FormatMismatch;
import org.omg.IOP.CodecPackage.TypeMismatch;
import org.omg.IOP.ServiceContext;
import org.omg.IOP.TaggedComponent;
import org.omg.PortableInterceptor.ClientRequestInterceptor;
import org.omg.PortableInterceptor.ClientRequestInfo;
import org.omg.PortableInterceptor.InvalidSlot;
import org.omg.PortableInterceptor.ServerRequestInterceptor;
import org.omg.PortableInterceptor.ServerRequestInfo;

public class AServiceInterceptor
    extends org.omg.CORBA.LocalObject
    implements ClientRequestInterceptor, ServerRequestInterceptor
{
    private int slotId;
    private Codec codec;

    private static final int serviceContextId = 1234;

    public AServiceInterceptor(int slotId)
    {
        this.slotId = slotId;
    }

    void setCodec(Codec codec)
    {
        this.codec = codec;
    }

    //
    // Interceptor operations
    //

    public String name() 
    {
        return "AServiceInterceptor";
    }

    public void destroy() 
    {
    }

    //
    // ClientRequestInterceptor operations
    //

    public void send_request(ClientRequestInfo ri)
    {
        //
        // See if the target object contains an ASERVICE_COMPONENT.
        //

        try {
            TaggedComponent taggedComponent =
                ri.get_effective_component(TAG_ASERVICE_COMPONENT.value);

            Any sAny = null;
            try {
                sAny = codec.decode_value(taggedComponent.component_data,
                                          ASERVICE_COMPONENTHelper.type());
            } catch (TypeMismatch e) {
                System.out.println("Exception handling not shown.");
            } catch (FormatMismatch e) {
                System.out.println("Exception handling not shown.");
            }

            ASERVICE_COMPONENT aServiceComponent =
                ASERVICE_COMPONENTHelper.extract(sAny);

            //
            // Only send the service context if the target object requires it.
            //

            if (aServiceComponent.requiresAService) {
                try {
                    Any any = ri.get_slot(slotId);
                    if (any.type().kind().equals(TCKind.tk_long)) {
                        int serviceId = any.extract_long();
                        byte[] serviceContextData = {
                            // Little endian to make it
                            // easier to see in debugger.
                            (byte)((serviceId >>>  0) &  0xFF),
                            (byte)((serviceId >>>  8) &  0xFF),
                            (byte)((serviceId >>> 16) &  0xFF),
                            (byte)((serviceId >>> 24) &  0xFF)
                        };
                        ri.add_request_service_context(
                            new ServiceContext(serviceContextId,
                                               serviceContextData),
                            false);
                    }
                } catch (InvalidSlot e) {
                    System.out.println("Exception handling not shown.");
                }
            }
        } catch (BAD_PARAM e) {
            // If it is not present, do nothing.
            ;
        }
    }

    public void send_poll(ClientRequestInfo ri)
    {
    }

    public void receive_reply(ClientRequestInfo ri)
    {
    }

    public void receive_exception(ClientRequestInfo ri)
    {
    }

    public void receive_other(ClientRequestInfo ri)
    {
    }

    //
    // ServerRequestInterceptor operations
    //

    public void receive_request_service_contexts(ServerRequestInfo ri)
    {
        try {
            ServiceContext serviceContext =
                ri.get_request_service_context(serviceContextId);
            byte[] data = serviceContext.context_data;
            int b1, b2, b3, b4;
            b4 = (data[0] <<  0) & 0x000000FF;
            b3 = (data[1] <<  8) & 0x0000FF00;
            b2 = (data[2] << 16) & 0x00FF0000;
            b1 = (data[3] << 24) & 0xFF000000;
            int serviceId = (b1 | b2 | b3 | b4);
            Any any = ORB.init().create_any();
            any.insert_long(serviceId);
            ri.set_slot(slotId, any);
        } catch (BAD_PARAM e) {
            // Not present means service is not in effect.
            // Do nothing.
            ;
        } catch (InvalidSlot e) {
            System.out.println("Exception handling not shown.");
        }
    }

    public void receive_request(ServerRequestInfo ri)
    {
    }

    public void send_reply(ServerRequestInfo ri)
    {
    }

    public void send_exception(ServerRequestInfo ri)
    {
    }

    public void send_other(ServerRequestInfo ri)
    {
    }
}

AServiceIORInterceptor.java

Этот файл добавляет TaggedComponent к IORs.

// AServiceIORInterceptor.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CORBA.Any;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.ORB;
import org.omg.IOP.TaggedComponent;
import org.omg.IOP.Codec;
import org.omg.IOP.CodecPackage.InvalidTypeForEncoding;
import org.omg.PortableInterceptor.IORInfo;
import org.omg.PortableInterceptor.IORInterceptor;

public class AServiceIORInterceptor
    extends org.omg.CORBA.LocalObject
    implements IORInterceptor
{
    private Codec codec;

    public AServiceIORInterceptor(Codec codec)
    {
        this.codec = codec;
    }

    //
    // Interceptor operations
    //

    public String name() 
    {
        return "AServiceInterceptor";
    }

    public void destroy() 
    {
    }

    //
    // IOR Interceptor operations
    //

    public void establish_components(IORInfo info)
    {
        //
        // Note: typically, rather than just inserting a tagged component
        // this interceptor would check info.get_effective_policy(int)
        // to determine if a tagged component reflecting that policy
        // should be added to the IOR.  That is not shown in this example.
        // 

        ASERVICE_COMPONENT aServiceComponent = new ASERVICE_COMPONENT(true);
        Any any = ORB.init().create_any();
        ASERVICE_COMPONENTHelper.insert(any, aServiceComponent);
        byte[] value = null;
        try {
            value = codec.encode_value(any);
        } catch (InvalidTypeForEncoding e) {
            System.out.println("Exception handling not shown.");
        }
        TaggedComponent taggedComponent =
            new TaggedComponent(TAG_ASERVICE_COMPONENT.value, value);
        info.add_ior_component(taggedComponent);
    }

}

ArbitaryObjectImpl.java

Этот файл является реализацией и сервером для интерфейса IDL ArbitraryObject. Реализации операций интерфейса IDL явно вызывают метод AServiceImpl.verify(), чтобы иллюстрировать непрерывную передачу данных от клиента (через AService.begin()) слуге.


// ArbitaryObjectImpl.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CORBA.ORB;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.PortableServer.POAHelper;

import java.util.Properties;

class ArbitraryObjectImpl
    extends ArbitraryObjectPOA
{
    public static ORB orb;

    private AService aService;

    //
    // The IDL operations.
    //

    public String arbitraryOperation1(String a1)
    {
        verifyService();
        return "I got this from the client: " + a1;
    }

    public void arbitraryOperation2 (int a1)
    {
        verifyService();
    }

    public void arbitraryOperation3(String a1)
        throws ArbitraryObjectException
    {
        verifyService();
        if (a1.equals("throw exception")) {
            throw new ArbitraryObjectException("because you told me to");
        }
    }

    private void verifyService()
    {
        getAService().verify();
    }

    private AService getAService()
    {
        // Only look up the service once, then cache it.

        if (aService == null) {
            try {
                aService =      
                    AServiceHelper.narrow(
                        orb.resolve_initial_references("AService"));
            } catch (InvalidName e) {
                System.out.println("Exception handling not shown.");
            }
        }
        return aService;
    }

    //
    // The server.
    //

    public static void main(String[] av)
    {
        try {
            if (orb == null) {
                Properties props = new Properties();
                props.put("org.omg.PortableInterceptor.ORBInitializerClass."
                          + "pi.serviceexample.AServiceORBInitializer",
                          "");
                props.put("org.omg.PortableInterceptor.ORBInitializerClass."
                          + "pi.serviceexample.LoggingServiceServerORBInitializer",
                          "");
                orb = ORB.init(av, props);
            }
            
            POA rootPOA =  POAHelper.narrow( orb.resolve_initial_references("RootPOA"));
            // Create a POA so the IOR interceptor executes.
            POA childPOA = rootPOA.create_POA("childPOA", null, null);
            childPOA.the_POAManager().activate();
            
            byte[] objectId =
                childPOA.activate_object(new ArbitraryObjectImpl());
            org.omg.CORBA.Object ref = childPOA.id_to_reference(objectId);

            NamingContext nameService = 
                NamingContextHelper.narrow(
                    orb.resolve_initial_references("NameService"));
            NameComponent path[] =
                { new NameComponent("ArbitraryObject", "") };
            nameService.rebind(path, ref);

            System.out.println("ArbitaryObject ready.");

            orb.run();

        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
        System.exit(0);
    }
}

Client.java

Это - клиент, который вызывает методы на ArbitraryObject. Это выполняет некоторые из тех вызовов в пределах контекста AService и некоторых за пределами его контекста. Это не сознает существование перехватчика журналирования (за исключением того, что это явно регистрирует LoggingServerClientORBInitializer как отмечено выше).


// Client.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CORBA.ORB;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;

import java.util.Properties;

public class Client 
{
    public static void main(String av[])
    {
        try {
            Properties props = new Properties();
            props.put("org.omg.PortableInterceptor.ORBInitializerClass."
                      + "pi.serviceexample.AServiceORBInitializer",
                      "");
            props.put("org.omg.PortableInterceptor.ORBInitializerClass."
                      + "pi.serviceexample.LoggingServiceClientORBInitializer",
                      "");
            ORB orb = ORB.init(av, props);

            //
            // The client obtains a reference to a service.
            // The client does not know the service is implemented
            // using interceptors.
            //

            AService aService = 
                AServiceHelper.narrow(
                    orb.resolve_initial_references("AService"));

            //
            // The client obtains a reference to some object that
            // it will invoke.
            //

            NamingContext nameService = 
                NamingContextHelper.narrow(
                    orb.resolve_initial_references("NameService"));
            NameComponent arbitraryObjectPath[] =
                { new NameComponent("ArbitraryObject", "") };
            ArbitraryObject arbitraryObject =
                ArbitraryObjectHelper.narrow(nameService.resolve(arbitraryObjectPath));

            //
            // The client begins the service so that invocations of
            // any object will be done with that service in effect.
            //

            aService.begin();
            
            arbitraryObject.arbitraryOperation1("one");
            arbitraryObject.arbitraryOperation2(2);

            //
            // The client ends the service so that further invocations
            // of any object will not be done with that service in effect.
            //

            aService.end();

            // This invocation is not serviced by aService since
            // it is outside the begin/end.
            arbitraryObject.arbitraryOperation3("just return");


            aService.begin();
            try {
                arbitraryObject.arbitraryOperation3("throw exception");
                throw new RuntimeException("should not see this");
            } catch (ArbitraryObjectException e) {
                // Expected in this example, so do nothing.
            }
            aService.end();

        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
        System.out.println("Client done.");
        System.exit(0);
    }
}

ColocatedServers.java

Это - сервер, который выполняет и ArbitraryObject и LoggingService в том же самом ШАРЕ. Это означает, что эти объекты являются colocated.

Сервер создается этот путь, чтобы осуществить код в LoggingServiceServerInterceptor, который иллюстрирует, когда перехватчики разбирают звонки в объекты colocated в том же самом ШАРЕ, дополнительные шаги должны быть сделаны, чтобы избежать бесконечной рекурсии.


// ColocatedServers.java
// Copyright and License 

package pi.serviceexample;

import org.omg.CORBA.ORB;
import java.util.Properties;

public class ColocatedServers
{
    public static ORB orb;

    public static boolean colocatedBootstrapDone = false;

    public static void main (String[] av)
    {
        try {

            //
            // Share an ORB between objects servers.
            //

            Properties props = new Properties();
            props.put("org.omg.PortableInterceptor.ORBInitializerClass."
                      + "pi.serviceexample.AServiceORBInitializer",
                      "");
            props.put("org.omg.PortableInterceptor.ORBInitializerClass."
                      + "pi.serviceexample.LoggingServiceServerORBInitializer",
                      "");
            ORB orb = ORB.init(av, props);
            ArbitraryObjectImpl.orb = orb;
            LoggingServiceImpl.orb = orb;

            //
            // Start both object servers.
            //

            ServerThread ServerThread = new ServerThread(av);
            ServerThread.start();
            ArbitraryObjectImpl.main(av);
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

class ServerThread extends Thread
{
    String[] av;
    ServerThread (String[] av)
    {
        this.av = av;
    }
    public void run ()
    {
        LoggingServiceImpl.main(av);
    }
}

Компиляция и запущение приложения

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


# Makefile for the Example Files
# Copyright and License 

JAVA_HOME=/path_to_J2SE_installation

CLASSPATH=.

JAVAC=$(JAVA_HOME)/bin/javac
JAVA=$(JAVA_HOME)/bin/java

ORB_INITIAL_PORT=1050

IDLJ=$(JAVA_HOME)/bin/idlj
IDLJ_FLAGS=-fall -td $(CLASSPATH) -verbose

ORBD=${JAVA_HOME}/bin/orbd -ORBInitialPort ${ORB_INITIAL_PORT}

build:
        $(IDLJ) $(IDLJ_FLAGS) serviceexample.idl
        $(JAVAC) -d $(CLASSPATH) *.java
        $(JAVAC) pi/serviceexample/*.java

runorbd:
        $(ORBD)

runloggingservice:
        $(JAVA) -classpath $(CLASSPATH) pi.serviceexample.LoggingServiceImpl \
                -ORBInitialPort ${ORB_INITIAL_PORT}

runarbitraryobject:
        $(JAVA) -classpath $(CLASSPATH) pi.serviceexample.ArbitraryObjectImpl \
                -ORBInitialPort ${ORB_INITIAL_PORT}

runcolocatedservers:
        $(JAVA) -classpath $(CLASSPATH) pi.serviceexample.ColocatedServers \
                -ORBInitialPort ${ORB_INITIAL_PORT}

runclient:
        $(JAVA) -classpath $(CLASSPATH) pi.serviceexample.Client \
                -ORBInitialPort ${ORB_INITIAL_PORT}
        
clean: 
        rm -rf pi
        rm -rf orb.db

# Order of steps:
# Build:     clean build
# Remote:    runorbd runloggingservice runarbitraryobjectimpl runclient
# Colocated: runorbd runcolocatedservers runclient

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

  1. % make clean
  2. % make build
  3. % make runorbd &
  4. % make runloggingservice &
  5. % make runarbitraryobject &
  6. % make runclient

    После этого шага Вы будете видеть, выводит, такие как это:

    resolve send_request
    resolve receive_reply
    arbitraryOperation1 send_request
    Service present: 1
    arbitraryOperation1 receive_reply
    arbitraryOperation2 send_request
    Service present: 1
    arbitraryOperation2 receive_other
    arbitraryOperation3 send_request
    Service not present
    arbitraryOperation3 receive_reply
    arbitraryOperation3 send_request
    Service present: 2
    arbitraryOperation3 receive_exception
    Client done.
    
  7. % jobs

    После этого шага Вы будете видеть, выводит, такие как это:

    [1]   Running                 make runorbd &
    [2]-  Running                 make runloggingservice &
    [3]+  Running                 make runarbitraryobject &
    
  8. % kill %2 %3
  9. % make runcolocatedservers &
  10. % make runclient

    После этого шага Вы будете видеть, выводит, такие как это:

    log receive_request_service_contexts
    log receive_request
    resolve send_request
    log send_reply
    log receive_request_service_contexts
    log receive_request
    resolve receive_reply
    log send_reply
    log receive_request_service_contexts
    log receive_request
    arbitraryOperation1 send_request
    log send_reply
    arbitraryOperation1 receive_request_service_contexts
    arbitraryOperation1 receive_request
    Service present: 1
    arbitraryOperation1 send_reply
    log receive_request_service_contexts
    log receive_request
    arbitraryOperation1 receive_reply
    log send_reply
    log receive_request_service_contexts
    log receive_request
    arbitraryOperation2 send_request
    log send_reply
    arbitraryOperation2 receive_request_service_contexts
    arbitraryOperation2 receive_request
    log receive_request_service_contexts
    Service present: 1
    arbitraryOperation2 send_reply
    log receive_request
    arbitraryOperation2 receive_other
    log send_reply
    log receive_request_service_contexts
    log receive_request
    arbitraryOperation3 send_request
    log send_reply
    arbitraryOperation3 receive_request_service_contexts
    arbitraryOperation3 receive_request
    Service not present
    arbitraryOperation3 send_reply
    log receive_request_service_contexts
    log receive_request
    arbitraryOperation3 receive_reply
    log send_reply
    log receive_request_service_contexts
    log receive_request
    arbitraryOperation3 send_request
    log send_reply
    arbitraryOperation3 receive_request_service_contexts
    arbitraryOperation3 receive_request
    Service present: 2
    arbitraryOperation3 send_exception
    log receive_request_service_contexts
    log receive_request
    arbitraryOperation3 receive_exception
    log send_reply
    Client done.
    
  11. % jobs

    После этого шага Вы будете видеть, выводит, такие как это:

    [1]-  Running                 make runorbd &
    [4]+  Running                 make runcolocatedservers &
    
  12. % kill %1 %4
  13. % make clean
См. Также:
ORBInitInfo
Пакет org.omg.PortableInterceptor.
Переносимая Спецификация Перехватчиков в ptc/2001-08-31

Oracle и/или его филиалы Авторское право © 1993, 2012, Oracle и/или его филиалы. Все права защищены.
Свяжитесь с Нами