Рабочий каталог расположен в
Следующий пример будет отличаться от предыдущего тем, что в нем будут реализованы методы, оперирующие объектными ссылками. В отличие от предыдущего примера, определим Card как интерфейс, обладающий методами изменения баланса. Объекты типа Card будут создаваться в процессе работы системы, и ссылки на них будут возвращаться клиенту соответствующими методами.
Таким образом, доступ к объектам этого типа будет осуществляться не посредством обращения к сервису имен, а посредством получения объектной ссылки.
Файл BillingService.idl
Файл BillingService.idl содержит описание двух интерфейсов: Card и BillingService.Интерфейс Card содержит три метода: addMoney (добавляет денежные средства на карту), subMoney (снимает денежные средства с карты), getCardBalance (показывает текущий баланс карты). Интерфейс BillingService включает два метода: addNewCard (добавляет новую карту) и getCard (возвращает объектную ссылку на карту с указанным номером).
В примере 8.1 приведено IDL -описание сервера BillingService.
1 // BillingService.idl
2 // IDL-описание BillingService
3 module BillingServiceModule
4 {
5 interface Card
6 {
7 void addMoney(in double money);
8 void subMoney(in double money);
9 double getBalance();
10 };
11 interface BillingService
12 {
13 Card getCard(in string card);
14 Card addNewCard(in string personName, in string card);
15 };
16 };
Следующим шагом в реализации нашего приложения будет генерация из IDL -определения вспомогательных классов.
После компиляции файла BillingService.idl компилятор Java-IDL создает следующие файлы на стороне сервера в вновь созданной директории BillingServiceModule:
BillingService.java, BillingServiceHelper.java, BillingServiceHolder.java, BillingServiceOperations.java, BillingServicePOA.java, _BillingServiceStub.java, Card.java, CardHelper.java, CardHolder.java, CardOperations.java, CardPOA.java, _CardStub.java.
Рассмотрим подробнее эти файлы (в этих файлах определены классы и интерфейсы языка java ) и то, как мы можем их использовать при создании нашего приложения.
BillingService.java и BillingServiceOperations.java - интерфейсы. BillingService.java (пример 8.2) представляет собой интерфейс BillingService.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/BillingService.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июль 2006 г. 15:01:11 MSD
9 */
10
11 public interface BillingService extends BillingServiceOperations,
12 org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity
13 {
14 } // interface BillingService
В строках 11 и 12 объявлены интерфейс BillingService и три интерфейса, от которых наследует BillingService.Как уже говорилось, два из этих трех интерфейсов являются определенными в CORBA типами, от которых должны наследовать все CORBA -совместимые объекты, org.omg.CORBA.Object и org.omg.CORBA.portable.IDLEntity.Третий интерфейс - BillingServiceOperations (пример 8.3) - создается на основе IDL -описания и объявляет открытые операции данного сервера. BillingService определяет базовый класс, который наследует от BillingServiceOperations и от CORBA -интерфейсов, упомянутых ранее. BillingServiceOperations объявляет два метода, изначально определенные в IDL.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/BillingServiceOperations.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июль 2006 г. 15:01:11 MSD
9 */
10
11 // определение CORBA-совместимого сервиса
12 public interface BillingServiceOperations
13 {
14 com.asw.corba.ex2.BillingServiceModule.Card getCard (String card);
15 com.asw.corba.ex2.BillingServiceModule.Card addNewCard
(String personName, String card);
16 } // interface BillingServiceOperations
Файлы BillingServiceHelper.java (пример 8.4) и BillingServiceHolder.java (пример 8.5) содержат методы приведения типов и методы маршаллинга/демаршаллинга сообщений.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/BillingServiceHelper.java
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июля 2006 г. 15:01:11 MSD
9 */
10
11 // определение класса BillingServiceHelper
12 abstract public class BillingServiceHelper
13 {
14 private static String _id =
"IDL:BillingServiceModule/BillingService:1.0";
15
16 public static void insert (org.omg.CORBA.Any a,
com.asw.corba.ex2.BillingServiceModule.BillingService that)
17 {
18 org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();
19 a.type (type ());
20 write (out, that);
21 a.read_value (out.create_input_stream (), type ());
22 }
23
24 public static com.asw.corba.ex2.BillingServiceModule.BillingService
extract (org.omg.CORBA.Any a)
25 {
26 return read (a.create_input_stream ());
27 }
28
29 private static org.omg.CORBA.TypeCode__typeCode = null;
30
31 synchronized public static org.omg.CORBA.TypeCode type ()
32 {
33 if (__typeCode == null)
34 {
35 __typeCode = org.omg.CORBA.ORB.init ().create_interface_tc
(com.asw.corba.ex2.BillingServiceModule.BillingServiceHelper.id (),
"BillingService");
36 }
37 return __typeCode;
38 }
39
40 public static String id ()
41 {
42 return _id;
43 }
44
45 public static com.asw.corba.ex2.BillingServiceModule.BillingService
read (org.omg.CORBA.portable.InputStream istream)
46 {
47 return narrow (istream.read_Object (_BillingServiceStub.class));
48 }
49
50 public static void write (org.omg.CORBA.portable.OutputStream ostream,
com.asw.corba.ex2.BillingServiceModule.BillingService value)
51 {
52 ostream.write_Object ((org.omg.CORBA.Object) value);
53 }
54
55 public static com.asw.corba.ex2.BillingServiceModule.BillingService
narrow (org.omg.CORBA.Object obj)
56 {
57 if (obj == null)
58 return null;
59 else if (obj instanceof
com.asw.corba.ex2.BillingServiceModule.BillingService)
60 return (com.asw.corba.ex2.BillingServiceModule.BillingService)obj;
61 else if (!obj._is_a (id ()))
62 throw new org.omg.CORBA.BAD_PARAM ();
63 else
64 {
65 org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();
66 com.asw.corba.ex2.BillingServiceModule._BillingServiceStub stub =
new com.asw.corba.ex2.BillingServiceModule._BillingServiceStub ();
67 stub._set_delegate(delegate);
68 return stub;
69 }
70 }
71 }
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/BillingServiceHolder.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса BillingServiceHolder
11 public final class BillingServiceHolder implements
org.omg.CORBA.portable.Streamable
12 {
13 public com.asw.corba.ex2.BillingServiceModule.BillingService value
= null;
14
15 public BillingServiceHolder ()
16 {
17 }
18
19 public BillingServiceHolder
(com.asw.corba.ex2.BillingServiceModule.BillingService initialValue)
20 {
21 value = initialValue;
22 }
23
24 public void _read (org.omg.CORBA.portable.InputStream i)
25 {
26 value =
com.asw.corba.ex2.BillingServiceModule.BillingServiceHelper.read (i);
27 }
28
29 public void _write (org.omg.CORBA.portable.OutputStream o)
30 {
31 com.asw.corba.ex2.BillingServiceModule.BillingServiceHelper.write
(o, value);
32 }
33
34 public org.omg.CORBA.TypeCode _type ()
35 {
36 return
com.asw.corba.ex2.BillingServiceModule.BillingServiceHelper.type ();
37 }
38 }
Файл _BillingServiceStub.java (пример 8.6) содержит клиентскую заглушку. Класс BillingServiceStub наследует от org.omg.CORBA.portable. ObjectImpl и реализует интерфейс BillingService.При вызове клиентом методов этого класса происходит упаковка вызова (и параметров) и их передача по сети серверному классу.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/_BillingServiceStub.java.
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса _BillingServiceStub
11 public class _BillingServiceStub extends org.omg.CORBA.
portable.ObjectImpl implements
com.asw.corba.ex2.BillingServiceModule.BillingService
12 {
13 public com.asw.corba.ex2.BillingServiceModule.Card getCard (String card)
14 {
15 org.omg.CORBA.portable.InputStream $in = null;
16 try {
17 org.omg.CORBA.portable.OutputStream $out =
_request ("getCard", true);
18 $out.write_string (card);
19 $in = _invoke ($out);
20 com.asw.corba.ex2.BillingServiceModule.Card $result =
com.asw.corba.ex2.BillingServiceModule.CardHelper.read ($in);
21 return $result;
22 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
23 $in = $ex.getInputStream ();
24 String _id = $ex.getId ();
25 throw new org.omg.CORBA.MARSHAL (_id);
26 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
27 return getCard (card );
28 } finally {
29 _releaseReply ($in);
30 }
31 } // getCard
32
33 public com.asw.corba.ex2.BillingServiceModule.Card addNewCard
(String personName, String card)
34 {
35 org.omg.CORBA.portable.InputStream $in = null;
36 try {
37 org.omg.CORBA.portable.OutputStream $out =
_request ("addNewCard", true);
38 $out.write_string (personName);
39 $out.write_string (card);
40 $in = _invoke ($out);
41 com.asw.corba.ex2.BillingServiceModule.Card $result =
com.asw.corba.ex2.BillingServiceModule.CardHelper.read ($in);
42 return $result;
43 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
44 $in = $ex.getInputStream ();
45 String _id = $ex.getId ();
46 throw new org.omg.CORBA.MARSHAL (_id);
47 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
48 return addNewCard (personName, card );
49 } finally {
50 _releaseReply ($in);
51 }
52 } // addNewCard
53
54 // Type-specific CORBA::Object operations
55 private static String[]__ids = {
56 "IDL:BillingServiceModule/BillingService:1.0"};
57 public String[] _ids ()
58 {
59 return (String[])__ids.clone ();
60 }
61
62 private void readObject (java.io.ObjectInputStream s)
throws java.io.IOException
63 {
64 String str = s.readUTF ();
65 String[] args = null;
66 java.util.Properties props = null;
67 org.omg.CORBA.Object obj = org.omg.CORBA.ORB.init
(args, props).string_to_object (str);
68 org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate ();
69 _set_delegate (delegate);
70 }
71
72 private void writeObject (java.io.ObjectOutputStream s)
throws java.io.IOException
73 {
74 String[] args = null;
75 java.util.Properties props = null;
76 String str = org.omg.CORBA.ORB.init (args, props).object_to_string
(this);
77 s.writeUTF (str);
78 }
79 } // class _BillingServiceStub
И последний файл BillingServicePOA.java (пример 8.7) содержит класс, выполняющий всю техническую работу по диспетчеризации сообщений клиента, - этот класс будет являться предком для нашего серверного класса, в котором мы переопределим методы, выполняющие содержательные CORBA -интерфейс (InvokeHandler) и интерфейс BillingServiceOperations.Интерфейс InvokeHandler объявляет метод , который является реализацией BillingServicePOA.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/BillingServicePOA.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса BillingServicePOA
11 public abstract class BillingServicePOA extends
org.omg.PortableServer.Servant
12 implements
com.asw.corba.ex2.BillingServiceModule.BillingServiceOperations,
org.omg.CORBA.portable.InvokeHandler
13 {
14 // Constructors
15 private static java.util.Hashtable _methods = new java.util.Hashtable ();
16 static
17 {
18 _methods.put ("getCard", new java.lang.Integer (0));
19 _methods.put ("addNewCard", new java.lang.Integer (1));
20 }
21
22 public org.omg.CORBA.portable.OutputStream _invoke (String $method,
23 org.omg.CORBA.portable.InputStream in,
24 org.omg.CORBA.portable.ResponseHandler $rh)
25 {
26 org.omg.CORBA.portable.OutputStream out = null;
27 java.lang.Integer __method = (java.lang.Integer)_methods.get ($method);
28 if (__method == null)
29 throw new org.omg.CORBA.BAD_OPERATION (0,
org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
30
31 switch __method.intValue ())
32 {
33 case 0: // BillingServiceModule/BillingService/getCard
34 {
35 String card = in.read_string ();
36 com.asw.corba.ex2.BillingServiceModule.Card $result = null;
37 $result = this.getCard (card);
38 out = $rh.createReply();
39 com.asw.corba.ex2.BillingServiceModule.CardHelper.write (out, $result);
40 break;
41 }
42
43 case 1: // BillingServiceModule/BillingService/addNewCard
44 {
45 String personName = in.read_string ();
46 String card = in.read_string ();
47 com.asw.corba.ex2.BillingServiceModule.Card $result = null;
48 $result = this.addNewCard (personName, card);
49 out = $rh.createReply();
50 com.asw.corba.ex2.BillingServiceModule.CardHelper.write (out, $result);
51 break;
52 }
53
54 default:
55 throw new org.omg.CORBA.BAD_OPERATION
(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
56 }
57 return out;
58 } // _invoke
59
60 // Type-specific CORBA::Object operations
61 private static String[] __ids =
{"IDL:BillingServiceModule/BillingService:1.0"};
62
63 public String[] _all_interfaces
(org.omg.PortableServer.POA poa, byte[] objectId)
64 {
65 return (String[]) __ids.clone ();
66 }
67
68 public BillingService _this()
69 {
70 return BillingServiceHelper.narrow(super._this_object());
71 }
72
73 public BillingService _this(org.omg.CORBA.ORB orb)
74 {
75 return BillingServiceHelper.narrow(super._this_object(orb));
76 }
77
78 } // class BillingServicePOA
Теперь перейдем к рассмотрению интерфейса Card.В файле Card.java (пример 8.8) определен интерфейс Card, наследующий от созданного idlj интерфейса CardOperations (пример 8.9) и двух интерфейсов - они являются определенными в CORBA типами, от которых должны наследовать все CORBA -совместимые объекты, - org.omg.CORBA.Object и org.omg.CORBA.portable.IDLEntity.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/Card.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июль 2006 г. 15:01:11 MSD
9 */
10
11 public interface Card extends CardOperations,
12 org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity
13 {
14 } // interface Card
CardOperations, ни от кого не наследуя, объявляет три метода, изначально определенные в IDL.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/CardOperations.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июль 2006 г. 15:01:11 MSD
9 */
10
11 // определение CORBA-совместимого сервиса
12 public interface CardOperations
13 {
14 void addMoney (double money);
15 void subMoney (double money);
16 double getBalance ();
17 } // interface CardOperations
Файлы CardHelper.java (пример 8.10) и CardHolder.java (пример 8.11) содержат вспомогательные классы.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/CardHelper.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июля 2006 г. 15:01:11 MSD
9 */
10
11 // определение класса CardHelper
12 abstract public class CardHelper
13 {
14 private static String _id = "IDL:BillingServiceModule/Card:1.0";
15
16 public static void insert (org.omg.CORBA.Any a,
com.asw.corba.ex2.BillingServiceModule.Card that)
17 {
18 org.omg.CORBA.portable.OutputStream out = a.create_output_stream();
19 a.type (type ());
20 write (out, that);
21 a.read_value (out.create_input_stream (), type ());
22 }
23
24 public static com.asw.corba.ex2.BillingServiceModule.Card extract
(org.omg.CORBA.Any a)
25 {
26 return read (a.create_input_stream ());
27 }
28
29 private static org.omg.CORBA.TypeCode __typeCode = null;
30 synchronized public static org.omg.CORBA.TypeCode type ()
31 {
32 if (__typeCode == null)
33 {
34 __typeCode = org.omg.CORBA.ORB.init ().create_interface_tc
(com.asw.corba.ex2.BillingServiceModule.CardHelper.id (),
"Card");
35 }
36 return __typeCode;
37 }
38
39 public static String id ()
40 {
41 return _id;
42 }
43
44 public static com.asw.corba.ex2.BillingServiceModule.Card read
(org.omg.CORBA.portable.InputStream istream)
45 {
46 return narrow (istream.read_Object (_CardStub.class));
47 }
48
49 public static void write (org.omg.CORBA.portable.OutputStream ostream,
com.asw.corba.ex2.BillingServiceModule.Card value)
50 {
51 ostream.write_Object ((org.omg.CORBA.Object) value);
52 }
53
54 public static com.asw.corba.ex2.BillingServiceModule.Card
narrow (org.omg.CORBA.Object obj)
55 {
56 if (obj == null)
57 return null;
58 else if (obj instanceof com.asw.corba.ex2.BillingServiceModule.Card)
59 return (com.asw.corba.ex2.BillingServiceModule.Card)obj;
60 else if (!obj._is_a (id ()))
61 throw new org.omg.CORBA.BAD_PARAM ();
62 else
63 {
64 org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();
65 com.asw.corba.ex2.BillingServiceModule._CardStub stub =
new com.asw.corba.ex2.BillingServiceModule._CardStub ();
66 stub._set_delegate(delegate);
67 return stub;
68 }
69 }
70 }
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/CardHolder.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса CardHolder
11 public final class CardHolder implements org.omg.CORBA.
portable.Streamable
12 {
13 public com.asw.corba.ex2.BillingServiceModule.Card value = null;
14
15 public CardHolder ()
16 {
17 }
18
19 public CardHolder (com.asw.corba.ex2.BillingServiceModule.Card
initialValue)
20 {
21 value = initialValue;
22 }
23
24 public void _read (org.omg.CORBA.portable.InputStream i)
25 {
26 value = com.asw.corba.ex2.BillingServiceModule.CardHelper.read (i);
27 }
28
29 public void _write (org.omg.CORBA.portable.OutputStream o)
30 {
31 com.asw.corba.ex2.BillingServiceModule.CardHelper.write (o, value);
32 }
33
34 public org.omg.CORBA.TypeCode _type ()
35 {
36 return com.asw.corba.ex2.BillingServiceModule.CardHelper.type ();
37 }
38 }
Файл _CardStub.java (пример 8.12) содержит клиентскую заглушку. Класс CardStub наследует от org.omg.CORBA.portable.ObjectImpl и реализует интерфейс Card.При вызове клиентом методов этого класса происходит упаковка вызова (и параметров) и их передача по сети серверному классу.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/_CardStub.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса _CardStub
11 public class _CardStub extends org.omg.CORBA.portable.ObjectImpl
implements com.asw.corba.ex2.BillingServiceModule.Card
12 {
13 public void addMoney (double money)
14 {
15 org.omg.CORBA.portable.InputStream $in = null;
16 try {
17 org.omg.CORBA.portable.OutputStream $out =
_request ("addMoney", true);
18 $out.write_double (money);
19 $in = _invoke ($out);
20 return;
21 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
22 $in = $ex.getInputStream ();
23 String _id = $ex.getId ();
24 throw new org.omg.CORBA.MARSHAL (_id);
25 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
26 addMoney (money );
27 } finally {
28 _releaseReply ($in);
29 }
30 } // addMoney
31
32 public void subMoney (double money)
33 {
34 org.omg.CORBA.portable.InputStream $in = null;
35 try {
36 org.omg.CORBA.portable.OutputStream $out =
_request ("subMoney", true);
37 $out.write_double (money);
38 $in = _invoke ($out);
39 return;
40 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
41 $in = $ex.getInputStream ();
42 String _id = $ex.getId ();
43 throw new org.omg.CORBA.MARSHAL (_id);
44 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
45 subMoney (money );
46 } finally {
47 _releaseReply ($in);
48 }
49 } // subMoney
50
51 public double getBalance ()
52 {
53 org.omg.CORBA.portable.InputStream $in = null;
54 try {
55 org.omg.CORBA.portable.OutputStream $out =
_request ("getBalance", true);
56 $in = _invoke ($out);
57 double $result = $in.read_double ();
58 return $result;
59 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
60 $in = $ex.getInputStream ();
61 String _id = $ex.getId ();
62 throw new org.omg.CORBA.MARSHAL (_id);
63 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
64 return getBalance ( );
65 } finally {
66 _releaseReply ($in);
67 }
68 } // getBalance
69
70 // Type-specific CORBA::Object operations
71 private static String[] __ids =
{"IDL:BillingServiceModule/Card:1.0"};
72
73 public String[] __ids ()
74 {
75 return (String[]) __ids.clone ();
76 }
77
78 private void readObject (java.io.ObjectInputStream s)
throws java.io.IOException
79 {
80 String str = s.readUTF ();
81 String[] args = null;
82 java.util.Properties props = null;
83 org.omg.CORBA.Object obj =
org.omg.CORBA.ORB.init (args, props).string_to_object (str);
84 org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate ();
85 _set_delegate (delegate);
86 }
87
88 private void writeObject (java.io.ObjectOutputStream s)
throws java.io.IOException
89 {
90 String[] args = null;
91 java.util.Properties props = null;
92 String str = org.omg.CORBA.ORB.init (args, props).object_to_string
(this);
93 s.writeUTF (str);
94 }
95 } // class _CardStub
И, наконец, файл CardPOA.java (пример 8.13) содержит класс, выполняющий всю рутинную работу по диспетчеризации сообщений клиента, - этот класс будет являться предком для нашего серверного класса, в котором мы переопределим нужные методы. Класс CardPOA наследует от org. и реализует CORBA -интерфейс InvokeHandler и интерфейс CardOperations.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/CardPOA.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса CardPOA
11 public abstract class CardPOA extends org.omg.PortableServer.Servant
12 implements com.asw.corba.ex2.BillingServiceModule.CardOperations,
org.omg.CORBA.portable.InvokeHandler
13 {
14 // Constructors
15 private static java.util.Hashtable _methods =
new java.util.Hashtable ();
16 static
17 {
18 _methods.put ("addMoney", new java.lang.Integer (0));
19 _methods.put ("subMoney", new java.lang.Integer (1));
20 _methods.put ("getBalance", new java.lang.Integer (2));
21 }
22
23 public org.omg.CORBA.portable.OutputStream _invoke (String $method,
24 org.omg.CORBA.portable.InputStream in,
25 org.omg.CORBA.portable.ResponseHandler $rh)
26 {
27 org.omg.CORBA.portable.OutputStream out = null;
28 java.lang.Integer __method = (java.lang.Integer)_methods.get
($method);
29 if (__method == null)
30 throw new org.omg.CORBA.BAD_OPERATION
(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
31
32 switch __method.intValue ())
33 {
34 case 0: // BillingServiceModule/Card/addMoney
35 {
36 double money = in.read_double ();
37 this.addMoney (money);
38 out = $rh.createReply();
39 break;
40 }
41
42 case 1: // BillingServiceModule/Card/subMoney
43 {
44 double money = in.read_double ();
45 this.subMoney (money);
46 out = $rh.createReply();
47 break;
48 }
49
50 case 2: // BillingServiceModule/Card/getBalance
51 {
52 double $result = (double)0;
53 $result = this.getBalance ();
54 out = $rh.createReply();
55 out.write_double ($result);
56 break;
57 }
58
59 default:
60 throw new org.omg.CORBA.BAD_OPERATION
(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
61 }
62 return out;
63 } // _invoke
64
65 // Type-specific CORBA::Object operations
66 private static String[] __ids =
{"IDL:BillingServiceModule/Card:1.0"};
67
68 public String[] _all_interfaces
(org.omg.PortableServer.POA poa, byte[] objectId)
69 {
70 return (String[])__ids.clone ();
71 }
72
73 public Card _this()
74 {
75 return CardHelper.narrow(super._this_object());
76 }
77
78 public Card _this(org.omg.CORBA.ORB orb)
79 {
80 return CardHelper.narrow(super._this_object(orb));
81 }
82
83 } // class CardPOA
Файлы BillingServiceImpl.java, CardImpl.java и BillingServiceServer.java
Следующим шагом после генерации необходимых вспомогательных файлов будет реализация
BillingServiceImpl (пример 8.14) является BillingService. Этот класс не объявляет метод main, этот метод объявляется в файле BillingServiceServer.java.
1 // BillingServiceImpl.java
2 package com.asw.corba.ex2;
3
4 //AccountManagerImpl.java
5 import com.asw.corba.ex2.BillingServiceModule.*;
6 // базовые пакеты Java
7 import java.util.*;
8
9 public class BillingServiceImpl extends BillingServicePOA {
10 public synchronized Card addNewCard
(String personName, String cardCode) {
11 // Lookup the account in the account dictionary.
12 Card card = (Card) _cards.get(cardCode);
13 // If there was no account in the dictionary, create one.
14 if(card == null) {
15 // Make up the account's balance, between 0 and 1000 dollars.
16 // Create the account implementation, given the balance.
17 CardImpl cardServant = new CardImpl(personName,0.0);
18 try {
19 // Activate it on the default POA which is root POA for this servant
20 card = CardHelper.narrow(_default_POA().servant_to_reference
(cardServant));
21 } catch (Exception e) {
22 e.printStackTrace();
23 }
24 // Print out the new account.
25 System.out.println("Created " + cardCode +
"'s account: " + card);
26 // Save the account in the account dictionary
27 _cards.put(cardCode, card);
28 }
29 // Return the account.
30 return card;
31 }
32 private Dictionary _cards = new Hashtable();
33 private Random _random = new Random();
34 public Card getCard(String cardCode) {
35 // TODO Auto-generated method stub
36 Card card = (Card) _cards.get(cardCode);
37 return card;
38 }
39 }
Класс BillingServiceImpl является наследником класса BillingServicePOA (который был построен автоматически) и, таким образом, уже обладает всей базовой функциональностью серверного класса. Все, что мы должны сделать, - определить реализацию методов addNewCard и getCard.
Класс BillingServiceImpl реализует методы сервера, а запуск сервера производится классом BillingServiceServer (пример 8.16).
Прежде чем рассматривать класс BillingServiceServer,рассмотрим реализацию класса CardImpl (пример 8.15). Класс CardImpl наследует от класса CardPOA (построен автоматически) и реализует методы addMoney, subMoney и getBalance.
1 // CardImpl.java
2 package com.asw.corba.ex2;
3
4 import com.asw.corba.ex2.BillingServiceModule.*;
5
6 //AccountImpl.java
7 public class CardImpl extends CardPOA {
8 public CardImpl(String personName,double balance) {
9 _personName = personName;
10 _balance = balance;
11 }
12
13 private double _balance;
14 private String _personName;
15
16 public void addMoney(double money) {
17 _balance += money;
18 }
19
20 public void subMoney(double money) {
21 _balance -= money;
22 }
23
24 public double getBalance() {
25 // TODO Auto-generated method stub
26 return _balance;
27 }
28 }
И наконец, класс BillingServiceServer содержит метод main, являющийся точкой
1 // BillingServiceServer.java
2 package com.asw.corba.ex2;
3
4 // пакеты OMG CORBA
5 import org.omg.CosNaming.*;
6 import org.omg.PortableServer.*;
7
8 public class BillingServiceServer {
9 public static void main(String args[]) {
10 try{
11 // Initialize the ORB.
12 org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
13 // get a reference to the root POA
14 POA rootPOA = POAHelper.narrow(orb.resolve_initial_references
("RootPOA"));
15 // get a reference to the Naming Service root_context
16 org.omg.CORBA.Object rootObj =
orb.resolve_initial_references ("NameService");
17 NamingContextExt root = NamingContextExtHelper.narrow(rootObj);
18
19 // Create policies for our persistent POA
20 org.omg.CORBA.Policy[] policies = {
21 rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)
22 };
23 // Create myPOA with the right policies
24 POA myPOA = rootPOA.create_POA( "billing_agent_poa",
rootPOA.the_POAManager(), policies );
25 // Create the servant
26 BillingServiceImpl managerServant = new BillingServiceImpl();
27 // Decide on the ID for the servant
28 byte[] managerId = "BillingService".getBytes();
29 // Activate the servant with the ID on myPOA
30 myPOA.activate_object_with_id(managerId, managerServant);
31
32 // Activate the POA manager
33 rootPOA.the_POAManager().activate();
34
35 // Associate the bank manager with the name at the root context
36 // Note that casting is needed as a workaround for a JDK 1.1.x bug.
37 ((NamingContext)root).bind(root.to_name("BillingService"),
myPOA.servant_to_reference(managerServant));
38
39 System.out.println(myPOA.servant_to_reference(managerServant) +
40 " is ready.");
41 // Wait for incoming requests
42 orb.run();
43 }
44 catch (Exception e) {
45 e.printStackTrace();
46 }
47 }
48 }
Первое, что делает это класс, - создает ссылку на (null.
Затем идут несколько строчек (строки 14-17), отвечающих за получение и активизацию ссылки на корневой POA ( ). Строка "RootPOA" является стандартным именем, определенным в спецификации CORBA (вместе со списком других имен). Статический метод narrow класса POAHelper используется для преобразования возвращенной объектной ссылки в объект нужного типа.
В строке 26 создается экземпляр нашего класса BillingServiceImpl.
Затем задается имя для нашего объекта, и метод bind (строка 37) вводит NameComponent в сервисе имен.
Вызов orb.run (строка 42) переводит объект в состояние ожидания запросов от клиентов, более того, этот вызов является блокирующим.
Таким образом, мы создали
Следует обратить внимание на то, что при создании объекта он был определен как персистентный (строка 20), что приведет к особенностям при его запуске.
Персистентным называется такой объект, получив ссылку на который, клиент может воспользоваться им независимо от того, активен этот объект в настоящий момент или нет (загружен он в память или нет); к тому же, независимо от того, сколько циклов загрузки/выгрузки пережил персистентный объект, объектная ссылка изменяться не будет. Для клиента это выглядит следующим образом: клиент получает объектную ссылку, вызывает метод объекта, и если объект присутствует в памяти (активен), все происходит обычным образом, а вот если объекта в памяти нет - система его загружает, инициирует и после этого передает ему запрос клиента.
В противном случае (если объект на персистентный, а транзиентный), объектная ссылка является действительной лишь до тех пор, пока объект присутствует в памяти. В случае завершения работы объекта клиент, обратившийся к объекту, по его объектной ссылке получит сообщение об ошибке.
Файл BillingServiceClient.java
BillingServiceClient (пример 8.17) представляет собой клиент, который соединяется с BillingService. Клиент содержит один метод main, который добавляет денежные средства на карту с номером 1 и затем выводит текущий баланс этой карты (строки 29-30).
1 // BillingServiceClient.java
2 package com.asw.corba.ex2;
3
4 // пакеты OMG CORBA
5 import org.omg.CORBA.ORB;
6 import org.omg.CosNaming.NamingContextExt;
7 import org.omg.CosNaming.NamingContextExtHelper;
8
9 import com.asw.corba.ex2.BillingServiceModule.*;;
10
11 public class BillingServiceClient {
12 static BillingService BSImpl;
13
14 public static void main(String args[])
15 {
16 try{
17 // create and initialize the ORB
18 ORB orb = ORB.init(args, null);
19
20 // get the root naming context
21 org.omg.CORBA.Object objRef =
22 orb.resolve_initial_references("NameService");
23
24 // Use NamingContextExt instead of NamingContext. This is
25 // part of the Interoperable naming Service.
26 NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
27
28 // resolve the Object Reference in Naming
29 String name = "BillingService";
30 System.out.println("1");
31 BSImpl = BillingServiceHelper.narrow(ncRef.resolve_str(name));
32
33 System.out.println("Obtained a handle on server object: " + BSImpl);
34 Card card = BSImpl.addNewCard("Ivan","1");
35 card.addMoney(10);
36 System.out.println(card.getBalance());
37 } catch (Exception e) {
38 System.out.println("ERROR : " + e) ;
39 e.printStackTrace(System.out);
40 }
41 }
42 }
В строке 18 вызывается статический метод init класса для создания , в строках 21-22 вызывается метод resolve_initial_references этого
Клиент должен запросить у сервиса имен объектную ссылку на сервис, который он разыскивает, - сервис BillingService,имеющий имя "BillingService" (объявлен в классе BillingServiceServer).Статический метод BillingServiceHelper.narrow осуществляет приведение объектной ссылки к требуемому типу
Выполнение примера
Если исходный код находится в каталоге C:\src,командная строка будет выглядеть следующим образом (исходя из IDL -описания, представленного в примере 8.1):
idlj -td c:\src -pkgPrefix BillingServiceModule com.asw.corba.ex2 -fall BillingService.idl
Эта командная строка создает и серверные, и клиентские файлы CORBA-Java. После реализации сервера и клиента следует скомпилировать серверный и клиентский код. При компиляции никаких особенностей нет:
javac *.java
Так же как и в предыдущем примере, необходимо проследить, чтобы пакет org.omg.*,содержащий реализацию поддержки CORBA, присутствовал в путях classpath.
Поскольку созданное нами приложение является персистентным объектом, для его функционирования потребуется сервис orbd,который предоставляет клиентам CORBA возможность прозрачной работы с персистентными объектами. Этот сервис, будучи запущенным, автоматически запускает сервис имен.
Запуск сервиса orbd по умолчанию не требует указания дополнительных параметров и выглядит следующим образом:
G:\jdk\bin\orbd
После запуска сервер создает в текущем каталоге файлы внутренней базы данных и служебную структуру директорий, в которой, в частности, будут находиться файлы с выводом нашего сервиса.
(рис 8.1) Работа утилиты servertoolДля первоначальной регистрации объектов используется утилита servertool.
Утилита servertool способна выполнять различные команды, полный список которых можно получить, набрав команду help в появившемся после ее запуска приглашении. Для нас сейчас наибольшую ценность представляет команда регистрации
servertool > register -server com.asw.corba.ex2.BillingServiceServer -classpath h:\servers\BS
где ключ - server определяет название запускающего класса (в данном случае - com.asw.corba.ex2.BillingServiceServer),а параметр -classpath указывает, где этот класс следует искать.
Список зарегистрированных объектов может быть получен с помощью команды list.Ниже приведен пример вывода утилиты servertool.
После регистрации объект готов к работе.
Далее мы запускаем клиента:
G:\ BillingService>java com.asw.corba.ex2.BillingServiceClient2
Выполнение команды приводит к следующему результату:
1 Obtained a handle on server object: IOR:000000000000002c49444c3a42696c6c696e67536572766963654d6f64756c 652f42696c6c696e67536572766963653a312e30000000000100000000000000a2 000102000000000c3139322e3136382e312e3100041900000000004fafabcb0000 0000220000010100000001000000000000000200000008526f6f74504f41000000 001262696c6c696e675f6167656e745f706f610000000000000e42696c6c696e67 536572766963651400000000020000000100000020000000000001000100000002 050100010001002000010109000000010001010000000026000000020002 10.0
Клиент получает объектную ссылку, распечатывает ее, вызывает метод addNewCard,который создает новую карту и возвращает объектную ссылку на вновь созданный объект. Полученная объектная ссылка может быть использована самым обычным образом - в данном случае клиент вызывает методы addMoney и getBalance и распечатывает баланс карты после выполнения операции, после чего прекращает работу.
Вывод сервера перехватывается orbd и перенаправляется в файлы <serverid>.err и <serverid>.out,располагающиеся в директории logs структуры файлов orbd.
В нашем случае файл 259.out будет иметь следующий вид:
[Sat Dec 30 17:09:15 MSK 2005] Server started [Sat Dec 30 17:09:16 MSK 2005] Install starting [Sat Dec 30 17:09:16 MSK 2005] Install completed IOR:000000000000002c49444c3a42696c6c696e67536572766963654d6f64756c6 52f42696c6c696e67536572766963653a312e30000000000100000000000000a200 0102000000000c3139322e3136382e312e3100041900000000004fafabcb0000000 0220000010100000001000000000000000200000008526f6f74504f410000000012 62696c6c696e675f6167656e745f706f610000000000000e42696c6c696e6753657 2766963651400000000020000000100000020000000000001000100000002050100 010001002000010109000000010001010000000026000000020002 is ready. Created 1's account: IOR:000000000000002249444c3a42696c6c696e67536572766963654d6f64756c 652f436172643a312e30000000000000010000000000000086000102000000000c 3139322e3136382e312e31000f58000000000031afabcb0000000020d3b1664d00 000001000000000000000100000008526f6f74504f410000000008000000010000 000014000000000000020000000100000020000000000001000100000002050100 010001002000010109000000010001010000000026000000020002
Рабочий каталог расположен в
Следующий пример будет отличаться от предыдущего тем, что в нем будут реализованы методы, оперирующие объектными ссылками. В отличие от предыдущего примера, определим Card как интерфейс, обладающий методами изменения баланса. Объекты типа Card будут создаваться в процессе работы системы, и ссылки на них будут возвращаться клиенту соответствующими методами.
Таким образом, доступ к объектам этого типа будет осуществляться не посредством обращения к сервису имен, а посредством получения объектной ссылки.
Файл BillingService.idl
Файл BillingService.idl содержит описание двух интерфейсов: Card и BillingService.Интерфейс Card содержит три метода: addMoney (добавляет денежные средства на карту), subMoney (снимает денежные средства с карты), getCardBalance (показывает текущий баланс карты). Интерфейс BillingService включает два метода: addNewCard (добавляет новую карту) и getCard (возвращает объектную ссылку на карту с указанным номером).
В примере 8.1 приведено IDL -описание сервера BillingService.
1 // BillingService.idl
2 // IDL-описание BillingService
3 module BillingServiceModule
4 {
5 interface Card
6 {
7 void addMoney(in double money);
8 void subMoney(in double money);
9 double getBalance();
10 };
11 interface BillingService
12 {
13 Card getCard(in string card);
14 Card addNewCard(in string personName, in string card);
15 };
16 };
Следующим шагом в реализации нашего приложения будет генерация из IDL -определения вспомогательных классов.
После компиляции файла BillingService.idl компилятор Java-IDL создает следующие файлы на стороне сервера в вновь созданной директории BillingServiceModule:
BillingService.java, BillingServiceHelper.java, BillingServiceHolder.java, BillingServiceOperations.java, BillingServicePOA.java, _BillingServiceStub.java, Card.java, CardHelper.java, CardHolder.java, CardOperations.java, CardPOA.java, _CardStub.java.
Рассмотрим подробнее эти файлы (в этих файлах определены классы и интерфейсы языка java ) и то, как мы можем их использовать при создании нашего приложения.
BillingService.java и BillingServiceOperations.java - интерфейсы. BillingService.java (пример 8.2) представляет собой интерфейс BillingService.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/BillingService.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июль 2006 г. 15:01:11 MSD
9 */
10
11 public interface BillingService extends BillingServiceOperations,
12 org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity
13 {
14 } // interface BillingService
В строках 11 и 12 объявлены интерфейс BillingService и три интерфейса, от которых наследует BillingService.Как уже говорилось, два из этих трех интерфейсов являются определенными в CORBA типами, от которых должны наследовать все CORBA -совместимые объекты, org.omg.CORBA.Object и org.omg.CORBA.portable.IDLEntity.Третий интерфейс - BillingServiceOperations (пример 8.3) - создается на основе IDL -описания и объявляет открытые операции данного сервера. BillingService определяет базовый класс, который наследует от BillingServiceOperations и от CORBA -интерфейсов, упомянутых ранее. BillingServiceOperations объявляет два метода, изначально определенные в IDL.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/BillingServiceOperations.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июль 2006 г. 15:01:11 MSD
9 */
10
11 // определение CORBA-совместимого сервиса
12 public interface BillingServiceOperations
13 {
14 com.asw.corba.ex2.BillingServiceModule.Card getCard (String card);
15 com.asw.corba.ex2.BillingServiceModule.Card addNewCard
(String personName, String card);
16 } // interface BillingServiceOperations
Файлы BillingServiceHelper.java (пример 8.4) и BillingServiceHolder.java (пример 8.5) содержат методы приведения типов и методы маршаллинга/демаршаллинга сообщений.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/BillingServiceHelper.java
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июля 2006 г. 15:01:11 MSD
9 */
10
11 // определение класса BillingServiceHelper
12 abstract public class BillingServiceHelper
13 {
14 private static String _id =
"IDL:BillingServiceModule/BillingService:1.0";
15
16 public static void insert (org.omg.CORBA.Any a,
com.asw.corba.ex2.BillingServiceModule.BillingService that)
17 {
18 org.omg.CORBA.portable.OutputStream out = a.create_output_stream ();
19 a.type (type ());
20 write (out, that);
21 a.read_value (out.create_input_stream (), type ());
22 }
23
24 public static com.asw.corba.ex2.BillingServiceModule.BillingService
extract (org.omg.CORBA.Any a)
25 {
26 return read (a.create_input_stream ());
27 }
28
29 private static org.omg.CORBA.TypeCode__typeCode = null;
30
31 synchronized public static org.omg.CORBA.TypeCode type ()
32 {
33 if (__typeCode == null)
34 {
35 __typeCode = org.omg.CORBA.ORB.init ().create_interface_tc
(com.asw.corba.ex2.BillingServiceModule.BillingServiceHelper.id (),
"BillingService");
36 }
37 return __typeCode;
38 }
39
40 public static String id ()
41 {
42 return _id;
43 }
44
45 public static com.asw.corba.ex2.BillingServiceModule.BillingService
read (org.omg.CORBA.portable.InputStream istream)
46 {
47 return narrow (istream.read_Object (_BillingServiceStub.class));
48 }
49
50 public static void write (org.omg.CORBA.portable.OutputStream ostream,
com.asw.corba.ex2.BillingServiceModule.BillingService value)
51 {
52 ostream.write_Object ((org.omg.CORBA.Object) value);
53 }
54
55 public static com.asw.corba.ex2.BillingServiceModule.BillingService
narrow (org.omg.CORBA.Object obj)
56 {
57 if (obj == null)
58 return null;
59 else if (obj instanceof
com.asw.corba.ex2.BillingServiceModule.BillingService)
60 return (com.asw.corba.ex2.BillingServiceModule.BillingService)obj;
61 else if (!obj._is_a (id ()))
62 throw new org.omg.CORBA.BAD_PARAM ();
63 else
64 {
65 org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();
66 com.asw.corba.ex2.BillingServiceModule._BillingServiceStub stub =
new com.asw.corba.ex2.BillingServiceModule._BillingServiceStub ();
67 stub._set_delegate(delegate);
68 return stub;
69 }
70 }
71 }
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/BillingServiceHolder.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса BillingServiceHolder
11 public final class BillingServiceHolder implements
org.omg.CORBA.portable.Streamable
12 {
13 public com.asw.corba.ex2.BillingServiceModule.BillingService value
= null;
14
15 public BillingServiceHolder ()
16 {
17 }
18
19 public BillingServiceHolder
(com.asw.corba.ex2.BillingServiceModule.BillingService initialValue)
20 {
21 value = initialValue;
22 }
23
24 public void _read (org.omg.CORBA.portable.InputStream i)
25 {
26 value =
com.asw.corba.ex2.BillingServiceModule.BillingServiceHelper.read (i);
27 }
28
29 public void _write (org.omg.CORBA.portable.OutputStream o)
30 {
31 com.asw.corba.ex2.BillingServiceModule.BillingServiceHelper.write
(o, value);
32 }
33
34 public org.omg.CORBA.TypeCode _type ()
35 {
36 return
com.asw.corba.ex2.BillingServiceModule.BillingServiceHelper.type ();
37 }
38 }
Файл _BillingServiceStub.java (пример 8.6) содержит клиентскую заглушку. Класс BillingServiceStub наследует от org.omg.CORBA.portable. ObjectImpl и реализует интерфейс BillingService.При вызове клиентом методов этого класса происходит упаковка вызова (и параметров) и их передача по сети серверному классу.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/_BillingServiceStub.java.
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса _BillingServiceStub
11 public class _BillingServiceStub extends org.omg.CORBA.
portable.ObjectImpl implements
com.asw.corba.ex2.BillingServiceModule.BillingService
12 {
13 public com.asw.corba.ex2.BillingServiceModule.Card getCard (String card)
14 {
15 org.omg.CORBA.portable.InputStream $in = null;
16 try {
17 org.omg.CORBA.portable.OutputStream $out =
_request ("getCard", true);
18 $out.write_string (card);
19 $in = _invoke ($out);
20 com.asw.corba.ex2.BillingServiceModule.Card $result =
com.asw.corba.ex2.BillingServiceModule.CardHelper.read ($in);
21 return $result;
22 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
23 $in = $ex.getInputStream ();
24 String _id = $ex.getId ();
25 throw new org.omg.CORBA.MARSHAL (_id);
26 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
27 return getCard (card );
28 } finally {
29 _releaseReply ($in);
30 }
31 } // getCard
32
33 public com.asw.corba.ex2.BillingServiceModule.Card addNewCard
(String personName, String card)
34 {
35 org.omg.CORBA.portable.InputStream $in = null;
36 try {
37 org.omg.CORBA.portable.OutputStream $out =
_request ("addNewCard", true);
38 $out.write_string (personName);
39 $out.write_string (card);
40 $in = _invoke ($out);
41 com.asw.corba.ex2.BillingServiceModule.Card $result =
com.asw.corba.ex2.BillingServiceModule.CardHelper.read ($in);
42 return $result;
43 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
44 $in = $ex.getInputStream ();
45 String _id = $ex.getId ();
46 throw new org.omg.CORBA.MARSHAL (_id);
47 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
48 return addNewCard (personName, card );
49 } finally {
50 _releaseReply ($in);
51 }
52 } // addNewCard
53
54 // Type-specific CORBA::Object operations
55 private static String[]__ids = {
56 "IDL:BillingServiceModule/BillingService:1.0"};
57 public String[] _ids ()
58 {
59 return (String[])__ids.clone ();
60 }
61
62 private void readObject (java.io.ObjectInputStream s)
throws java.io.IOException
63 {
64 String str = s.readUTF ();
65 String[] args = null;
66 java.util.Properties props = null;
67 org.omg.CORBA.Object obj = org.omg.CORBA.ORB.init
(args, props).string_to_object (str);
68 org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate ();
69 _set_delegate (delegate);
70 }
71
72 private void writeObject (java.io.ObjectOutputStream s)
throws java.io.IOException
73 {
74 String[] args = null;
75 java.util.Properties props = null;
76 String str = org.omg.CORBA.ORB.init (args, props).object_to_string
(this);
77 s.writeUTF (str);
78 }
79 } // class _BillingServiceStub
И последний файл BillingServicePOA.java (пример 8.7) содержит класс, выполняющий всю техническую работу по диспетчеризации сообщений клиента, - этот класс будет являться предком для нашего серверного класса, в котором мы переопределим методы, выполняющие содержательные CORBA -интерфейс (InvokeHandler) и интерфейс BillingServiceOperations.Интерфейс InvokeHandler объявляет метод , который является реализацией BillingServicePOA.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/BillingServicePOA.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса BillingServicePOA
11 public abstract class BillingServicePOA extends
org.omg.PortableServer.Servant
12 implements
com.asw.corba.ex2.BillingServiceModule.BillingServiceOperations,
org.omg.CORBA.portable.InvokeHandler
13 {
14 // Constructors
15 private static java.util.Hashtable _methods = new java.util.Hashtable ();
16 static
17 {
18 _methods.put ("getCard", new java.lang.Integer (0));
19 _methods.put ("addNewCard", new java.lang.Integer (1));
20 }
21
22 public org.omg.CORBA.portable.OutputStream _invoke (String $method,
23 org.omg.CORBA.portable.InputStream in,
24 org.omg.CORBA.portable.ResponseHandler $rh)
25 {
26 org.omg.CORBA.portable.OutputStream out = null;
27 java.lang.Integer __method = (java.lang.Integer)_methods.get ($method);
28 if (__method == null)
29 throw new org.omg.CORBA.BAD_OPERATION (0,
org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
30
31 switch __method.intValue ())
32 {
33 case 0: // BillingServiceModule/BillingService/getCard
34 {
35 String card = in.read_string ();
36 com.asw.corba.ex2.BillingServiceModule.Card $result = null;
37 $result = this.getCard (card);
38 out = $rh.createReply();
39 com.asw.corba.ex2.BillingServiceModule.CardHelper.write (out, $result);
40 break;
41 }
42
43 case 1: // BillingServiceModule/BillingService/addNewCard
44 {
45 String personName = in.read_string ();
46 String card = in.read_string ();
47 com.asw.corba.ex2.BillingServiceModule.Card $result = null;
48 $result = this.addNewCard (personName, card);
49 out = $rh.createReply();
50 com.asw.corba.ex2.BillingServiceModule.CardHelper.write (out, $result);
51 break;
52 }
53
54 default:
55 throw new org.omg.CORBA.BAD_OPERATION
(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
56 }
57 return out;
58 } // _invoke
59
60 // Type-specific CORBA::Object operations
61 private static String[] __ids =
{"IDL:BillingServiceModule/BillingService:1.0"};
62
63 public String[] _all_interfaces
(org.omg.PortableServer.POA poa, byte[] objectId)
64 {
65 return (String[]) __ids.clone ();
66 }
67
68 public BillingService _this()
69 {
70 return BillingServiceHelper.narrow(super._this_object());
71 }
72
73 public BillingService _this(org.omg.CORBA.ORB orb)
74 {
75 return BillingServiceHelper.narrow(super._this_object(orb));
76 }
77
78 } // class BillingServicePOA
Теперь перейдем к рассмотрению интерфейса Card.В файле Card.java (пример 8.8) определен интерфейс Card, наследующий от созданного idlj интерфейса CardOperations (пример 8.9) и двух интерфейсов - они являются определенными в CORBA типами, от которых должны наследовать все CORBA -совместимые объекты, - org.omg.CORBA.Object и org.omg.CORBA.portable.IDLEntity.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/Card.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июль 2006 г. 15:01:11 MSD
9 */
10
11 public interface Card extends CardOperations,
12 org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity
13 {
14 } // interface Card
CardOperations, ни от кого не наследуя, объявляет три метода, изначально определенные в IDL.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/CardOperations.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июль 2006 г. 15:01:11 MSD
9 */
10
11 // определение CORBA-совместимого сервиса
12 public interface CardOperations
13 {
14 void addMoney (double money);
15 void subMoney (double money);
16 double getBalance ();
17 } // interface CardOperations
Файлы CardHelper.java (пример 8.10) и CardHolder.java (пример 8.11) содержат вспомогательные классы.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3
4 /**
5 * com/asw/corba/ex2/BillingServiceModule/CardHelper.java .
6 * Generated by the IDL-to-Java compiler (portable), version "3.1"
7 * from com/asw/corba/ex2/BillingService.idl
8 * 16 Июля 2006 г. 15:01:11 MSD
9 */
10
11 // определение класса CardHelper
12 abstract public class CardHelper
13 {
14 private static String _id = "IDL:BillingServiceModule/Card:1.0";
15
16 public static void insert (org.omg.CORBA.Any a,
com.asw.corba.ex2.BillingServiceModule.Card that)
17 {
18 org.omg.CORBA.portable.OutputStream out = a.create_output_stream();
19 a.type (type ());
20 write (out, that);
21 a.read_value (out.create_input_stream (), type ());
22 }
23
24 public static com.asw.corba.ex2.BillingServiceModule.Card extract
(org.omg.CORBA.Any a)
25 {
26 return read (a.create_input_stream ());
27 }
28
29 private static org.omg.CORBA.TypeCode __typeCode = null;
30 synchronized public static org.omg.CORBA.TypeCode type ()
31 {
32 if (__typeCode == null)
33 {
34 __typeCode = org.omg.CORBA.ORB.init ().create_interface_tc
(com.asw.corba.ex2.BillingServiceModule.CardHelper.id (),
"Card");
35 }
36 return __typeCode;
37 }
38
39 public static String id ()
40 {
41 return _id;
42 }
43
44 public static com.asw.corba.ex2.BillingServiceModule.Card read
(org.omg.CORBA.portable.InputStream istream)
45 {
46 return narrow (istream.read_Object (_CardStub.class));
47 }
48
49 public static void write (org.omg.CORBA.portable.OutputStream ostream,
com.asw.corba.ex2.BillingServiceModule.Card value)
50 {
51 ostream.write_Object ((org.omg.CORBA.Object) value);
52 }
53
54 public static com.asw.corba.ex2.BillingServiceModule.Card
narrow (org.omg.CORBA.Object obj)
55 {
56 if (obj == null)
57 return null;
58 else if (obj instanceof com.asw.corba.ex2.BillingServiceModule.Card)
59 return (com.asw.corba.ex2.BillingServiceModule.Card)obj;
60 else if (!obj._is_a (id ()))
61 throw new org.omg.CORBA.BAD_PARAM ();
62 else
63 {
64 org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl)obj)._get_delegate ();
65 com.asw.corba.ex2.BillingServiceModule._CardStub stub =
new com.asw.corba.ex2.BillingServiceModule._CardStub ();
66 stub._set_delegate(delegate);
67 return stub;
68 }
69 }
70 }
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/CardHolder.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса CardHolder
11 public final class CardHolder implements org.omg.CORBA.
portable.Streamable
12 {
13 public com.asw.corba.ex2.BillingServiceModule.Card value = null;
14
15 public CardHolder ()
16 {
17 }
18
19 public CardHolder (com.asw.corba.ex2.BillingServiceModule.Card
initialValue)
20 {
21 value = initialValue;
22 }
23
24 public void _read (org.omg.CORBA.portable.InputStream i)
25 {
26 value = com.asw.corba.ex2.BillingServiceModule.CardHelper.read (i);
27 }
28
29 public void _write (org.omg.CORBA.portable.OutputStream o)
30 {
31 com.asw.corba.ex2.BillingServiceModule.CardHelper.write (o, value);
32 }
33
34 public org.omg.CORBA.TypeCode _type ()
35 {
36 return com.asw.corba.ex2.BillingServiceModule.CardHelper.type ();
37 }
38 }
Файл _CardStub.java (пример 8.12) содержит клиентскую заглушку. Класс CardStub наследует от org.omg.CORBA.portable.ObjectImpl и реализует интерфейс Card.При вызове клиентом методов этого класса происходит упаковка вызова (и параметров) и их передача по сети серверному классу.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/_CardStub.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса _CardStub
11 public class _CardStub extends org.omg.CORBA.portable.ObjectImpl
implements com.asw.corba.ex2.BillingServiceModule.Card
12 {
13 public void addMoney (double money)
14 {
15 org.omg.CORBA.portable.InputStream $in = null;
16 try {
17 org.omg.CORBA.portable.OutputStream $out =
_request ("addMoney", true);
18 $out.write_double (money);
19 $in = _invoke ($out);
20 return;
21 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
22 $in = $ex.getInputStream ();
23 String _id = $ex.getId ();
24 throw new org.omg.CORBA.MARSHAL (_id);
25 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
26 addMoney (money );
27 } finally {
28 _releaseReply ($in);
29 }
30 } // addMoney
31
32 public void subMoney (double money)
33 {
34 org.omg.CORBA.portable.InputStream $in = null;
35 try {
36 org.omg.CORBA.portable.OutputStream $out =
_request ("subMoney", true);
37 $out.write_double (money);
38 $in = _invoke ($out);
39 return;
40 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
41 $in = $ex.getInputStream ();
42 String _id = $ex.getId ();
43 throw new org.omg.CORBA.MARSHAL (_id);
44 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
45 subMoney (money );
46 } finally {
47 _releaseReply ($in);
48 }
49 } // subMoney
50
51 public double getBalance ()
52 {
53 org.omg.CORBA.portable.InputStream $in = null;
54 try {
55 org.omg.CORBA.portable.OutputStream $out =
_request ("getBalance", true);
56 $in = _invoke ($out);
57 double $result = $in.read_double ();
58 return $result;
59 } catch (org.omg.CORBA.portable.ApplicationException $ex) {
60 $in = $ex.getInputStream ();
61 String _id = $ex.getId ();
62 throw new org.omg.CORBA.MARSHAL (_id);
63 } catch (org.omg.CORBA.portable.RemarshalException $rm) {
64 return getBalance ( );
65 } finally {
66 _releaseReply ($in);
67 }
68 } // getBalance
69
70 // Type-specific CORBA::Object operations
71 private static String[] __ids =
{"IDL:BillingServiceModule/Card:1.0"};
72
73 public String[] __ids ()
74 {
75 return (String[]) __ids.clone ();
76 }
77
78 private void readObject (java.io.ObjectInputStream s)
throws java.io.IOException
79 {
80 String str = s.readUTF ();
81 String[] args = null;
82 java.util.Properties props = null;
83 org.omg.CORBA.Object obj =
org.omg.CORBA.ORB.init (args, props).string_to_object (str);
84 org.omg.CORBA.portable.Delegate delegate =
((org.omg.CORBA.portable.ObjectImpl) obj)._get_delegate ();
85 _set_delegate (delegate);
86 }
87
88 private void writeObject (java.io.ObjectOutputStream s)
throws java.io.IOException
89 {
90 String[] args = null;
91 java.util.Properties props = null;
92 String str = org.omg.CORBA.ORB.init (args, props).object_to_string
(this);
93 s.writeUTF (str);
94 }
95 } // class _CardStub
И, наконец, файл CardPOA.java (пример 8.13) содержит класс, выполняющий всю рутинную работу по диспетчеризации сообщений клиента, - этот класс будет являться предком для нашего серверного класса, в котором мы переопределим нужные методы. Класс CardPOA наследует от org. и реализует CORBA -интерфейс InvokeHandler и интерфейс CardOperations.
1 package com.asw.corba.ex2.BillingServiceModule;
2
3 /**
4 * com/asw/corba/ex2/BillingServiceModule/CardPOA.java .
5 * Generated by the IDL-to-Java compiler (portable), version "3.1"
6 * from com/asw/corba/ex2/BillingService.idl
7 * 16 Июль 2006 г. 15:01:11 MSD
8 */
9
10 // определение класса CardPOA
11 public abstract class CardPOA extends org.omg.PortableServer.Servant
12 implements com.asw.corba.ex2.BillingServiceModule.CardOperations,
org.omg.CORBA.portable.InvokeHandler
13 {
14 // Constructors
15 private static java.util.Hashtable _methods =
new java.util.Hashtable ();
16 static
17 {
18 _methods.put ("addMoney", new java.lang.Integer (0));
19 _methods.put ("subMoney", new java.lang.Integer (1));
20 _methods.put ("getBalance", new java.lang.Integer (2));
21 }
22
23 public org.omg.CORBA.portable.OutputStream _invoke (String $method,
24 org.omg.CORBA.portable.InputStream in,
25 org.omg.CORBA.portable.ResponseHandler $rh)
26 {
27 org.omg.CORBA.portable.OutputStream out = null;
28 java.lang.Integer __method = (java.lang.Integer)_methods.get
($method);
29 if (__method == null)
30 throw new org.omg.CORBA.BAD_OPERATION
(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
31
32 switch __method.intValue ())
33 {
34 case 0: // BillingServiceModule/Card/addMoney
35 {
36 double money = in.read_double ();
37 this.addMoney (money);
38 out = $rh.createReply();
39 break;
40 }
41
42 case 1: // BillingServiceModule/Card/subMoney
43 {
44 double money = in.read_double ();
45 this.subMoney (money);
46 out = $rh.createReply();
47 break;
48 }
49
50 case 2: // BillingServiceModule/Card/getBalance
51 {
52 double $result = (double)0;
53 $result = this.getBalance ();
54 out = $rh.createReply();
55 out.write_double ($result);
56 break;
57 }
58
59 default:
60 throw new org.omg.CORBA.BAD_OPERATION
(0, org.omg.CORBA.CompletionStatus.COMPLETED_MAYBE);
61 }
62 return out;
63 } // _invoke
64
65 // Type-specific CORBA::Object operations
66 private static String[] __ids =
{"IDL:BillingServiceModule/Card:1.0"};
67
68 public String[] _all_interfaces
(org.omg.PortableServer.POA poa, byte[] objectId)
69 {
70 return (String[])__ids.clone ();
71 }
72
73 public Card _this()
74 {
75 return CardHelper.narrow(super._this_object());
76 }
77
78 public Card _this(org.omg.CORBA.ORB orb)
79 {
80 return CardHelper.narrow(super._this_object(orb));
81 }
82
83 } // class CardPOA
Файлы BillingServiceImpl.java, CardImpl.java и BillingServiceServer.java
Следующим шагом после генерации необходимых вспомогательных файлов будет реализация
BillingServiceImpl (пример 8.14) является BillingService. Этот класс не объявляет метод main, этот метод объявляется в файле BillingServiceServer.java.
1 // BillingServiceImpl.java
2 package com.asw.corba.ex2;
3
4 //AccountManagerImpl.java
5 import com.asw.corba.ex2.BillingServiceModule.*;
6 // базовые пакеты Java
7 import java.util.*;
8
9 public class BillingServiceImpl extends BillingServicePOA {
10 public synchronized Card addNewCard
(String personName, String cardCode) {
11 // Lookup the account in the account dictionary.
12 Card card = (Card) _cards.get(cardCode);
13 // If there was no account in the dictionary, create one.
14 if(card == null) {
15 // Make up the account's balance, between 0 and 1000 dollars.
16 // Create the account implementation, given the balance.
17 CardImpl cardServant = new CardImpl(personName,0.0);
18 try {
19 // Activate it on the default POA which is root POA for this servant
20 card = CardHelper.narrow(_default_POA().servant_to_reference
(cardServant));
21 } catch (Exception e) {
22 e.printStackTrace();
23 }
24 // Print out the new account.
25 System.out.println("Created " + cardCode +
"'s account: " + card);
26 // Save the account in the account dictionary
27 _cards.put(cardCode, card);
28 }
29 // Return the account.
30 return card;
31 }
32 private Dictionary _cards = new Hashtable();
33 private Random _random = new Random();
34 public Card getCard(String cardCode) {
35 // TODO Auto-generated method stub
36 Card card = (Card) _cards.get(cardCode);
37 return card;
38 }
39 }
Класс BillingServiceImpl является наследником класса BillingServicePOA (который был построен автоматически) и, таким образом, уже обладает всей базовой функциональностью серверного класса. Все, что мы должны сделать, - определить реализацию методов addNewCard и getCard.
Класс BillingServiceImpl реализует методы сервера, а запуск сервера производится классом BillingServiceServer (пример 8.16).
Прежде чем рассматривать класс BillingServiceServer,рассмотрим реализацию класса CardImpl (пример 8.15). Класс CardImpl наследует от класса CardPOA (построен автоматически) и реализует методы addMoney, subMoney и getBalance.
1 // CardImpl.java
2 package com.asw.corba.ex2;
3
4 import com.asw.corba.ex2.BillingServiceModule.*;
5
6 //AccountImpl.java
7 public class CardImpl extends CardPOA {
8 public CardImpl(String personName,double balance) {
9 _personName = personName;
10 _balance = balance;
11 }
12
13 private double _balance;
14 private String _personName;
15
16 public void addMoney(double money) {
17 _balance += money;
18 }
19
20 public void subMoney(double money) {
21 _balance -= money;
22 }
23
24 public double getBalance() {
25 // TODO Auto-generated method stub
26 return _balance;
27 }
28 }
И наконец, класс BillingServiceServer содержит метод main, являющийся точкой
1 // BillingServiceServer.java
2 package com.asw.corba.ex2;
3
4 // пакеты OMG CORBA
5 import org.omg.CosNaming.*;
6 import org.omg.PortableServer.*;
7
8 public class BillingServiceServer {
9 public static void main(String args[]) {
10 try{
11 // Initialize the ORB.
12 org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
13 // get a reference to the root POA
14 POA rootPOA = POAHelper.narrow(orb.resolve_initial_references
("RootPOA"));
15 // get a reference to the Naming Service root_context
16 org.omg.CORBA.Object rootObj =
orb.resolve_initial_references ("NameService");
17 NamingContextExt root = NamingContextExtHelper.narrow(rootObj);
18
19 // Create policies for our persistent POA
20 org.omg.CORBA.Policy[] policies = {
21 rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)
22 };
23 // Create myPOA with the right policies
24 POA myPOA = rootPOA.create_POA( "billing_agent_poa",
rootPOA.the_POAManager(), policies );
25 // Create the servant
26 BillingServiceImpl managerServant = new BillingServiceImpl();
27 // Decide on the ID for the servant
28 byte[] managerId = "BillingService".getBytes();
29 // Activate the servant with the ID on myPOA
30 myPOA.activate_object_with_id(managerId, managerServant);
31
32 // Activate the POA manager
33 rootPOA.the_POAManager().activate();
34
35 // Associate the bank manager with the name at the root context
36 // Note that casting is needed as a workaround for a JDK 1.1.x bug.
37 ((NamingContext)root).bind(root.to_name("BillingService"),
myPOA.servant_to_reference(managerServant));
38
39 System.out.println(myPOA.servant_to_reference(managerServant) +
40 " is ready.");
41 // Wait for incoming requests
42 orb.run();
43 }
44 catch (Exception e) {
45 e.printStackTrace();
46 }
47 }
48 }
Первое, что делает это класс, - создает ссылку на (null.
Затем идут несколько строчек (строки 14-17), отвечающих за получение и активизацию ссылки на корневой POA ( ). Строка "RootPOA" является стандартным именем, определенным в спецификации CORBA (вместе со списком других имен). Статический метод narrow класса POAHelper используется для преобразования возвращенной объектной ссылки в объект нужного типа.
В строке 26 создается экземпляр нашего класса BillingServiceImpl.
Затем задается имя для нашего объекта, и метод bind (строка 37) вводит NameComponent в сервисе имен.
Вызов orb.run (строка 42) переводит объект в состояние ожидания запросов от клиентов, более того, этот вызов является блокирующим.
Таким образом, мы создали
Следует обратить внимание на то, что при создании объекта он был определен как персистентный (строка 20), что приведет к особенностям при его запуске.
Персистентным называется такой объект, получив ссылку на который, клиент может воспользоваться им независимо от того, активен этот объект в настоящий момент или нет (загружен он в память или нет); к тому же, независимо от того, сколько циклов загрузки/выгрузки пережил персистентный объект, объектная ссылка изменяться не будет. Для клиента это выглядит следующим образом: клиент получает объектную ссылку, вызывает метод объекта, и если объект присутствует в памяти (активен), все происходит обычным образом, а вот если объекта в памяти нет - система его загружает, инициирует и после этого передает ему запрос клиента.
В противном случае (если объект на персистентный, а транзиентный), объектная ссылка является действительной лишь до тех пор, пока объект присутствует в памяти. В случае завершения работы объекта клиент, обратившийся к объекту, по его объектной ссылке получит сообщение об ошибке.
Файл BillingServiceClient.java
BillingServiceClient (пример 8.17) представляет собой клиент, который соединяется с BillingService. Клиент содержит один метод main, который добавляет денежные средства на карту с номером 1 и затем выводит текущий баланс этой карты (строки 29-30).
1 // BillingServiceClient.java
2 package com.asw.corba.ex2;
3
4 // пакеты OMG CORBA
5 import org.omg.CORBA.ORB;
6 import org.omg.CosNaming.NamingContextExt;
7 import org.omg.CosNaming.NamingContextExtHelper;
8
9 import com.asw.corba.ex2.BillingServiceModule.*;;
10
11 public class BillingServiceClient {
12 static BillingService BSImpl;
13
14 public static void main(String args[])
15 {
16 try{
17 // create and initialize the ORB
18 ORB orb = ORB.init(args, null);
19
20 // get the root naming context
21 org.omg.CORBA.Object objRef =
22 orb.resolve_initial_references("NameService");
23
24 // Use NamingContextExt instead of NamingContext. This is
25 // part of the Interoperable naming Service.
26 NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
27
28 // resolve the Object Reference in Naming
29 String name = "BillingService";
30 System.out.println("1");
31 BSImpl = BillingServiceHelper.narrow(ncRef.resolve_str(name));
32
33 System.out.println("Obtained a handle on server object: " + BSImpl);
34 Card card = BSImpl.addNewCard("Ivan","1");
35 card.addMoney(10);
36 System.out.println(card.getBalance());
37 } catch (Exception e) {
38 System.out.println("ERROR : " + e) ;
39 e.printStackTrace(System.out);
40 }
41 }
42 }
В строке 18 вызывается статический метод init класса для создания , в строках 21-22 вызывается метод resolve_initial_references этого
Клиент должен запросить у сервиса имен объектную ссылку на сервис, который он разыскивает, - сервис BillingService,имеющий имя "BillingService" (объявлен в классе BillingServiceServer).Статический метод BillingServiceHelper.narrow осуществляет приведение объектной ссылки к требуемому типу
Выполнение примера
Если исходный код находится в каталоге C:\src,командная строка будет выглядеть следующим образом (исходя из IDL -описания, представленного в примере 8.1):
idlj -td c:\src -pkgPrefix BillingServiceModule com.asw.corba.ex2 -fall BillingService.idl
Эта командная строка создает и серверные, и клиентские файлы CORBA-Java. После реализации сервера и клиента следует скомпилировать серверный и клиентский код. При компиляции никаких особенностей нет:
javac *.java
Так же как и в предыдущем примере, необходимо проследить, чтобы пакет org.omg.*,содержащий реализацию поддержки CORBA, присутствовал в путях classpath.
Поскольку созданное нами приложение является персистентным объектом, для его функционирования потребуется сервис orbd,который предоставляет клиентам CORBA возможность прозрачной работы с персистентными объектами. Этот сервис, будучи запущенным, автоматически запускает сервис имен.
Запуск сервиса orbd по умолчанию не требует указания дополнительных параметров и выглядит следующим образом:
G:\jdk\bin\orbd
После запуска сервер создает в текущем каталоге файлы внутренней базы данных и служебную структуру директорий, в которой, в частности, будут находиться файлы с выводом нашего сервиса.
(рис 8.1) Работа утилиты servertoolДля первоначальной регистрации объектов используется утилита servertool.
Утилита servertool способна выполнять различные команды, полный список которых можно получить, набрав команду help в появившемся после ее запуска приглашении. Для нас сейчас наибольшую ценность представляет команда регистрации
servertool > register -server com.asw.corba.ex2.BillingServiceServer -classpath h:\servers\BS
где ключ - server определяет название запускающего класса (в данном случае - com.asw.corba.ex2.BillingServiceServer),а параметр -classpath указывает, где этот класс следует искать.
Список зарегистрированных объектов может быть получен с помощью команды list.Ниже приведен пример вывода утилиты servertool.
После регистрации объект готов к работе.
Далее мы запускаем клиента:
G:\ BillingService>java com.asw.corba.ex2.BillingServiceClient2
Выполнение команды приводит к следующему результату:
1 Obtained a handle on server object: IOR:000000000000002c49444c3a42696c6c696e67536572766963654d6f64756c 652f42696c6c696e67536572766963653a312e30000000000100000000000000a2 000102000000000c3139322e3136382e312e3100041900000000004fafabcb0000 0000220000010100000001000000000000000200000008526f6f74504f41000000 001262696c6c696e675f6167656e745f706f610000000000000e42696c6c696e67 536572766963651400000000020000000100000020000000000001000100000002 050100010001002000010109000000010001010000000026000000020002 10.0
Клиент получает объектную ссылку, распечатывает ее, вызывает метод addNewCard,который создает новую карту и возвращает объектную ссылку на вновь созданный объект. Полученная объектная ссылка может быть использована самым обычным образом - в данном случае клиент вызывает методы addMoney и getBalance и распечатывает баланс карты после выполнения операции, после чего прекращает работу.
Вывод сервера перехватывается orbd и перенаправляется в файлы <serverid>.err и <serverid>.out,располагающиеся в директории logs структуры файлов orbd.
В нашем случае файл 259.out будет иметь следующий вид:
[Sat Dec 30 17:09:15 MSK 2005] Server started [Sat Dec 30 17:09:16 MSK 2005] Install starting [Sat Dec 30 17:09:16 MSK 2005] Install completed IOR:000000000000002c49444c3a42696c6c696e67536572766963654d6f64756c6 52f42696c6c696e67536572766963653a312e30000000000100000000000000a200 0102000000000c3139322e3136382e312e3100041900000000004fafabcb0000000 0220000010100000001000000000000000200000008526f6f74504f410000000012 62696c6c696e675f6167656e745f706f610000000000000e42696c6c696e6753657 2766963651400000000020000000100000020000000000001000100000002050100 010001002000010109000000010001010000000026000000020002 is ready. Created 1's account: IOR:000000000000002249444c3a42696c6c696e67536572766963654d6f64756c 652f436172643a312e30000000000000010000000000000086000102000000000c 3139322e3136382e312e31000f58000000000031afabcb0000000020d3b1664d00 000001000000000000000100000008526f6f74504f410000000008000000010000 000014000000000000020000000100000020000000000001000100000002050100 010001002000010109000000010001010000000026000000020002
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.