Опубликован: 10.10.2010 | Уровень: специалист | Доступ: платный
Лекция 9:

CORBA. Третий пример. DII и DSI

< Лекция 8 || Лекция 9: 12 || Лекция 10 >

Класс BillingServiceServer

Класс BillingServiceServer служит для создания экземпляра BillingServiceImpl и его регистрации в сервисе имен. Он ничем не отличается от подобных классов, рассмотренных нами ранее.

1  package com.asw.corba.ex3;
2  
3  import org.omg.CosNaming.*;
4  import org.omg.CORBA.*;
5  
6  public class BillingServiceServer {
7  
8    public static void main(String args[]) {
9      try {
10        // create and initialize the ORB
11        ORB orb = ORB.init(args, null);
12        // create servant and register it with the ORB
13        BillingServiceImpl BSRef = new BillingServiceImpl(orb);
14        orb.connect(BSRef);
15        System.out.println(BSRef);
16  org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
17        NamingContext ncRef = NamingContextHelper.narrow(objRef);
18        // bind the Object Reference in Naming
19        NameComponent nc = new NameComponent("BillingService", "");
20        NameComponent path[] = { nc };
21        ncRef.rebind(path, BSRef);
22        java.lang.Object sync = new java.lang.Object();
23        synchronized (sync) { sync.wait(); }
24      } catch (Exception e) {
25        System.err.println("ERROR: " + e);
26        e.printStackTrace(System.out);
27      }
28    }
29  }
Листинг 9.2. Класс BillingServiceServer

Класс BillingServiceClient

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

1  package com.asw.corba.ex3;
2  
3  import org.omg.CosNaming.*;
4  import org.omg.CORBA.*;
5  
6  public class BillingServiceClient {
7    org.omg.CORBA.Object BSImpl;
8  
9    ORB orb;
10  
11    void testAddNewCard(String personName, String card) {
12      org.omg.CORBA.Request r2 = BSImpl._request("addNewCard");
13      r2.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_void));
14      org.omg.CORBA.Any inc = r2.add_in_arg();
15      inc.insert_string(personName);
16      org.omg.CORBA.Any inc2 = r2.add_in_arg();
17      inc2.insert_string(card);
18      r2.invoke();
19      java.lang.Exception ex = r2.env().exception();
20      if (ex instanceof org.omg.CORBA.UnknownUserException) {
21  org.omg.CORBA.UnknownUserException userEx = (org.omg.CORBA.UnknownUserException) ex;
22      }
23    }
24  
25    void testAddMoney(String card, double amount) {
26      org.omg.CORBA.Request r2 = BSImpl._request("addMoney");
27      r2.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_void));
28      org.omg.CORBA.Any inc = r2.add_in_arg();
29      inc.insert_string(card);
30      org.omg.CORBA.Any inc2 = r2.add_in_arg();
31      inc2.insert_double(amount);
32      r2.invoke();
33      java.lang.Exception ex = r2.env().exception();
34      if (ex instanceof org.omg.CORBA.UnknownUserException) {
35  org.omg.CORBA.UnknownUserException userEx = (org.omg.CORBA.UnknownUserException) ex;
36      }
37      String result;
38    }
39  
40    void testSubMoney(String card, double amount) {
41      org.omg.CORBA.Request r2 = BSImpl._request("subMoney");
42      r2.set_return_type(orb.get_primitive_tc(org.omg.CORBA.TCKind.tk_void));
43      org.omg.CORBA.Any inc = r2.add_in_arg();
44      inc.insert_string(card);
45      org.omg.CORBA.Any inc2 = r2.add_in_arg();
46      inc2.insert_double(amount);
47      r2.invoke();
48      java.lang.Exception ex = r2.env().exception();
49      if (ex instanceof org.omg.CORBA.UnknownUserException) {
50  org.omg.CORBA.UnknownUserException userEx = (org.omg.CORBA.UnknownUserException) ex;
51      }
52      String result;
53    }
54  
55    double testGetCardBalance(String card) {
56      org.omg.CORBA.Request r2 = BSImpl._request("getCardBalance");
57  r2.set_return_type(orb.get_primitive_tc (org.omg.CORBA.TCKind.tk_double));
58      org.omg.CORBA.Any inc = r2.add_in_arg();
59      inc.insert_string(card);
60      r2.invoke();
61      java.lang.Exception ex = r2.env().exception();
62      if (ex instanceof org.omg.CORBA.UnknownUserException) {
63  org.omg.CORBA.UnknownUserException userEx = (org.omg.CORBA.UnknownUserException) ex;
64      }
65      double result;
66      result = r2.return_value().extract_double();
67      System.out.println("Balance= " + result);
68      return result;
69    }
70  
71    public void doTest(String args[]) throws Exception {
72      orb = ORB.init(args, null);
73  org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
74      NamingContext ncRef = NamingContextHelper.narrow(objRef);
75      // resolve the Object Reference in Naming
76      NameComponent nc = new NameComponent("BillingService", "");
77      NameComponent path[] = { nc };
78      BSImpl = ncRef.resolve(path);
79      System.out.println(BSImpl);
80      this.testAddNewCard("Ivan", "1");
81      this.testAddMoney("1", 10.2);
82      this.testGetCardBalance("1");
83      this.testSubMoney("1", 8.1);
84      this.testGetCardBalance("1");
85    }
86  
87    public static void main(String args[]) {
88      try {
89        BillingServiceClient bsc = new BillingServiceClient();
90        bsc.doTest(args);
91      } catch (Exception e) {
92        System.out.println("ERROR : " + e);
93        e.printStackTrace(System.out);
94      }
95    }
96  }
Листинг 9.3. Класс BillingServiceClient

Формирование динамического вызова метода сервера осуществляется следующим образом.

У полученной у сервиса имен объектной ссылки (она имеет тип org.omg.CORBA.Object) вызовом метода request (в качестве аргумента этому методу передается имя вызываемого метода сервера) получаем org.omg.CORBA.Request - объект, который используется для осуществления запросов к серверу.

Первое, что необходимо указать, - тип возвращаемого методом значения:

r2.set_return_type(orb.get_primitive_tc 
(org.omg.CORBA.TCKind.tk_double));

Затем необходимо поместить в запрос передаваемые аргументы:

Заorg.omg.CORBA.Any inc = r2.add_in_arg();
inc.insert_string(card); 
org.omg.CORBA.Any inc2 = r2.add_in_arg(); 
inc2.insert_double(amount);

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

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

r2.invoke();

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

java.lang.Exception ex = r2.env().exception();

Для извлечения результата, возвращенного серверным методом, снова нужно обратиться к org.omg.CORBA.Request.

double result = r2.return_value().extract_double();

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

Компиляция и выполнение примера

Компиляция приложений, использующих DII или DSI, ничем не отличается от компиляции ранее рассмотренных примеров.

Так же как для запуска других приложений CORBA, использующих сервис имен, требуется запуск этого сервиса:

tnameserv

Запуск компонентов приложения также не имеет особенностей:

G:\java com.asw.corba.ex3.BillingServiceServer
IOR:000000000000002249444c3a4a61766149444c2f44534942696c6c696e6753 
6572766963653a312e3000000000000001000000000000006e000102000000000c 
3139322e3136382e312e3100134d000000000019afabcb0000000002b42a5d5400 
000008000000000000000014000000000000020000000100000020000000000001
000100000002050100010001002000010109000000010001010000000026000000
020002
DSI:  invoke called,  op = addNewCard
DSI:  invoke called,  op = addMoney
DSI:  invoke called,  op = getCardBalance
DSI:  invoke called,  op = subMoney
DSI:  invoke called,  op = getCardBalance

G:\java com.asw.corba.ex3.BillingServiceClient
IOR:000000000000002249444c3a4a61766149444c2f44534942696c6c696e6753 
6572766963653a312e3000000000000001000000000000006e000102000000000c
3139322e3136382e312e3100134d000000000019afabcb0000000002b42a5d5400
000008000000000000000014000000000000020000000100000020000000000001 
000100000002050100010001002000010109000000010001010000000026000000 
020002
Balance= 10.2
Balance= 2.0999999999999996
< Лекция 8 || Лекция 9: 12 || Лекция 10 >
Алмаз Мурзабеков
Алмаз Мурзабеков
Прохожу курс "Построение распределенных систем на Java" в третьей лекции где описывается TCPServer вылетает эта ошибка
"Connection cannot be resolved to a type"


Java version 1.7.0_05
Александр Хвостов
Александр Хвостов
Россия
Максим Лютов
Максим Лютов
Россия, СПб, Политех, 2012