You are on page 1of 87

Chapter 26: Common Object Request

Broker Architecture(CORBA): Part 1


Outline
26.1 Introduction
26.2 Step-by-Step
26.3 First Example: SystemClock
26.3.1 SystemClock.idl
26.3.2 SystemClockImpl.java
26.3.3 SystemClockClient.java
26.3.4 Running the Example
26.4 Technical/Architectural Overview
26.5 CORBA Basics
26.6 Example: AlarmClock
26.6.1 AlarmClock.idl
26.6.2 AlarmClockImpl.java
26.6.3 AlarmClockClient.java
26.7 Distributed Exceptions

 2002 Prentice Hall. All rights reserved.


Chapter 26: Common Object Request
Broker Architecture(CORBA): Part 1
26.8 Case Study: Chat
26.8.1 chat.idl
26.8.2 ChatServerImpl.java
26.8.3 DeitelMessenger.java
26.8.4 Running Chat
26.8.5 Issues
26.9 Comments and Comparisons
26.10 Internet and World Wide Web Resources

 2002 Prentice Hall. All rights reserved.


26.1 Introduction

• CORBA
– Common Object Request Broker Architecture
• Allows programs written in various languages to
communicate with each other as would two
processes in the same address space.
• Features leveraged by clients:
– Invocation transparency
– Implementation transparency
– Location transparency

 2002 Prentice Hall. All rights reserved.


26.1 Introduction (cont.)

• IDL
– Interface Definition Language
• a pure description language.
– enables developers to describe an interface they wish to use
remotely in a language-independent fashion.
• language specific compiler required for each
participating language.
– creates files required by each language for CORBA related
tasks.

 2002 Prentice Hall. All rights reserved.


26.1 Introduction (cont.)

• Components of Interoperability
– Object reference pointing to a remote object.
• comes from an object adapter
• information contained:
1. location (network address)
2. reference to the adapter that created object reference
3. object ID
– Parsing object reference to transmit
• GIOP
– Defines messages needed by ORBs to communicate with
each other.
– IIOP (Internet Inter-ORB Protocol)-GIOP implementation.

 2002 Prentice Hall. All rights reserved.


26.2 Step-by-Step

• Distributed system implementation steps using


Java and CORBA:
1. Analysis and Design
– break problem into smaller fundamental services or
subsystems
– decide which subsystems to configure as distributed services
2. Defining the IDL
– define functionality each service will expose
– define data structures received and returned by each service
3. Implementing the servant
4. Implementing a client
5. Distribution of servant’s object reference
6. Running the servant implementation
7. Running the client

 2002 Prentice Hall. All rights reserved.


26.3 First Example: SystemClock

• Provides a basic service by enabling client to


query for current time.
• Client requirements:
– retrieve the current system time
– display the retrieved time in GUI window

 2002 Prentice Hall. All rights reserved.


26.3.1 SystemClock.idl

• SystemClock server IDL definition


• Declares a single method
currentTimeMillis

 2002 Prentice Hall. All rights reserved.


1 // Fig. 26.1: systemclock.idl Outline
2 // IDL definition of SystemClock.
3
4 module clock {
5 Fig. 26.1
6 // The definition of the CORBA-enabled service IDL definition for
7 interface SystemClock { server
8 long long currentTimeMillis();
9 }; SystemClock
10 };
Lines 1-2 and 6

Line 4
denote single line comments module keyword maps given
name to a Java package Lines 4, 10
curly braces denote scope
boundaries of block semicolon identifies end of Lines 9-10
block
Line 7
server type from client’s perspective
and return type - maps to Java
long ( single long maps to
server implemented interface
Java int)

 2002 Prentice Hall.


All rights reserved.
26.3.1 SystemClock.idl (cont.)

• Everything declared in IDL file is public.


• Java IDL compiler, idlj, compiles
systemclock.idl with command:
idlj –td c:\src –pkgPrefix clock
com.deitel.advjhtp1.idl –fall
systemclock.idl
- Generates following files:
- SystemClock.java
- SystemClockOperations.java
- _SystemClockImplBase.java

 2002 Prentice Hall. All rights reserved.


1 package com.deitel.advjhtp1.idl.clock; Outline
2
3
4 /**
5 * com/deitel/jhtp4/idl/clock/SystemClock.java Fig. 26.2
6 * Generated by the IDL-to-Java compiler (portable), version "3.0" A Java interface
7 * from systemclock.idl generated by idlj.
8 * Wednesday, February 28, 2001 8:24:01 PM PST
9 */
10 Line 12
11 public interface SystemClock extends SystemClockOperations,
12 org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity
13 { Line 11
14 } // interface SystemClock

declares public operations of


CORBA-defined types from which server (generated from IDL)
all CORBA-enabled objects inherit

 2002 Prentice Hall.


All rights reserved.
1 package com.deitel.advjhtp1.idl.clock; Outline
2
3
4 /**
5 * com/deitel/advjhtp1/idl/clock/SystemClockOperations.java Fig. 26.3
6 * Generated by the IDL-to-Java compiler (portable), version "3.0" SystemClockOpera
7 * from systemclock.idl tions interface
8 * Sunday, July 1, 2001 10:36:53 PM PDT
9 */ generated by idlj
10
11 Line 15
12 // The definition of the CORBA-enabled service
13 public interface SystemClockOperations
14 { Line 15
15 long currentTimeMillis ();
16 } // interface SystemClockOperations

IDL file long long mapped method defined in IDL file


to Java long

 2002 Prentice Hall.


All rights reserved.
1 // Fig. 26.4: SystemClockImpl.java Outline
2 // SystemClock service implementation.
3
4 package com.deitel.advjhtp1.idl.clock;
5 Fig. 26.4
6 // OMG CORBA packages Implementation of the
7 import org.omg.CORBA.ORB; SystemClock
8 import org.omg.CosNaming.*;
9 import org.omg.CosNaming.NamingContextPackage.*; server
10
11 public class SystemClockImpl extends _SystemClockImplBase {
12
13 // return computer's current time in milliseconds
14 public long currentTimeMillis()
15 {
16 return System.currentTimeMillis();
17 }
18
19 // initialize SystemClockImpl object by calling method register
20 public SystemClockImpl( String params[] ) throws Exception
21 {
22 register( "TimeServer", params );
23 }
24
25 // register SystemClockImpl object with Naming Service
26 private void register( String corbaName, String params[] )
27 throws org.omg.CORBA.ORBPackage.InvalidName,
28 org.omg.CosNaming.NamingContextPackage.InvalidName,
29 CannotProceed, NotFound
30 {

 2002 Prentice Hall.


All rights reserved.
31 // Check name of service. If name is null or blank Outline
32 // do not attempt to bind to Naming Service.
33 if ( ( corbaName == null ) ||
34 ( corbaName.trim().length() == 0 ) )
35 throw new IllegalArgumentException( Fig. 26.4
36 "Registration name cannot be null or blank." ); Implementation of the
37 SystemClock
38 // create and initialize ORB
server.
39 ORB orb = ORB.init( params, null ); creation of a new ORB object
40
41 // register this object with ORB Line 39
42 orb.connect( this ); pass implementation object to ORB
43
44 // find Naming Service Line 42
45 org.omg.CORBA.Object corbaObject =
46 orb.resolve_initial_references( "NameService" ); retrieves Naming Service
CORBA Lines 45-46 to cast
mechanism
47 NamingContext naming = object reference
48 NamingContextHelper.narrow( corbaObject );
one Object reference to
49 Lines
another (in47-48
this case,
50 // create NameComponent array with path information to
51 // find this object NamingContext)
52 NameComponent namingComponent = naming Lines 52-53
context (identifies
53 new NameComponent( corbaName, "" );
54 NameComponent path[] = { namingComponent };
object reference in naming
55 Line 57
service)
56 // bind SystemClockImpl object with ORB
57 naming.rebind( path, this ); store reference to current
58 System.out.println( "Rebind complete" );
59 }
object using provided naming
60 context
61 // main method to execute server
62 public static void main( String[] args ) throws Exception
63 {
64 // Create the SystemClock CORBA object.
65 SystemClock timeServer = new SystemClockImpl( args );
 2002 Prentice Hall.
All rights reserved.
66 Outline
67 // Wait for requests from the outside.
68 java.lang.Object object = new java.lang.Object();
69
70 // keep server alive Fig. 26.4
71 synchronized( object ) { Implementation of the
72 object.wait(); SystemClock
73 }
74 } server.
75 } // end class SystemClockImpl

 2002 Prentice Hall.


All rights reserved.
26.3.3 SystemClockClient.java

• Represents the client that connects to


SystemClock.
• Connects to SystemClock service, requests
current time and displays result.

 2002 Prentice Hall. All rights reserved.


1 // Fig. 26.5: SystemClockClient.java Outline
2 // Client application for the SystemClock example.
3
4 package com.deitel.advjhtp1.idl.clock;
5 Fig. 26.5 Client that
6 // Java core packages connects to
7 import java.text.DateFormat; SystemClock.
8 import java.util.*;
9
10 // Java extension packages Line 35
11 import javax.swing.JOptionPane;
12
13 // OMG CORBA packages
14 import org.omg.CORBA.ORB;
15 import org.omg.CosNaming.*;
16 import org.omg.CosNaming.NamingContextPackage.*;
17
18 public class SystemClockClient implements Runnable {
19 private SystemClock timeServer;
20
21 // initialize client
22 public SystemTimeClient( String params[] ) throws Exception
23 {
24 connectToTimeServer( params );
25 startTimer();
26 }
27
28 // use NameService to connect to time server
29 private void connectToTimeServer( String params[] )
30 throws org.omg.CORBA.ORBPackage.InvalidName, create ORB
31 org.omg.CosNaming.NamingContextPackage.InvalidName,
32 NotFound, CannotProceed
33 {
34 // connect to SystemClock server
35 ORB orb = ORB.init( params, null );
 2002 Prentice Hall.
All rights reserved.
36 Outline
37 org.omg.CORBA.Object corbaObject =
38 orb.resolve_initial_references( "NameService" );
39 NamingContext naming =
40 NamingContextHelper.narrow( corbaObject ); Fig. 26.5 Client that
41 connects to
42 // resolve object reference in naming SystemClock.
43 NameComponent nameComponent =
44 new NameComponent( "TimeServer", "" ); obtain reference of object
45 NameComponent path[] = { nameComponent }; obtain
boundreference
to name Line 37
to Naming
TimeServer Service
46 corbaObject = naming.resolve( path );
47 timeServer = SystemClockHelper.narrow( corbaObject ); cast to type
Line SystemClock
44
48 }
49
50 // start timer thread Line 47
51 private void startTimer()
52 {
53 Thread thread = new Thread( this ); Line 68
54 thread.start();
55 }
56
57 // talk to server on regular basis and display results
58 public void run()
59 {
60 long time = 0;
61 Date date = null;
62 DateFormat format =
63 DateFormat.getTimeInstance( DateFormat.LONG );
64 String timeString = null;
65 int response = 0;
66 invoke method on remote object
67 while( true ) {
68 time = timeServer.currentTimeMillis();
69 date = new Date( time );
70 timeString = format.format( date );
 2002 Prentice Hall.
All rights reserved.
71 Outline
72 response = JOptionPane.showConfirmDialog( null, timeString,
73 "SystemClock Example", JOptionPane.OK_CANCEL_OPTION );
74
75 if ( response == JOptionPane.CANCEL_OPTION ) Fig. 26.5 Client that
76 break; // Get us out of here connects to
77 } SystemClock.
78
79 System.exit( 0 );
80 }
81
82 // main method to execute client application
83 public static void main( String args[] ) throws Exception
84 {
85 // create client
86 try {
87 new SystemClockClient( args );
88 }
89
90 // process exceptions that occur while client executes
91 catch ( Exception exception ) {
92 System.out.println(
93 "Exception thrown by SystemClockClient:" );
94 exception.printStackTrace();
95 }
96 }
97 } // end of class SystemClockClient

 2002 Prentice Hall.


All rights reserved.
26.3.4 Running the Example

• Ensure JDK 1.3 is installed on workstation and PATH


environment variable includes JDK’s bin directory.
• Steps to execute SystemClock example:
1. compile IDL file using idlj
– example (source code in c:\src):
idlj –pkgPrefix clock com.deitel.advjhtp1.idl
–td c:\src -fall SystemClock.idl
2. implement and compile server code
3. implement and compile client code
4. run Naming Service
– tnameserv provided included in JDK 1.3 as a CORBA Object
Service Naming Service test tool implementation
– example:
tnameserv -ORBInitialPort 1050
5. run server
– java com.deitel.advjhtp1.idl.clock.SystemClockImpl –
ORBInitialPort 1050

 2002 Prentice Hall. All rights reserved.


26.3.4 Running the Example (cont.)

6. run client
java com.deitel.advjhtp1.idl.clock.SystemClockClient
-ORBInitialPort 1050

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview

• ORB is the central mechanism of CORBA.


• One ORB must exist for every object in a
CORBA-enabled distributed system.
• An ORB’s relationship to services in a
distributed system is comparable to the
relationship between a computer’s
communication bus and devices connected to it.
• Clients communicate with an ORB by using:
1. IDL compiler generated stub,
2. dynamic interface (using CORBA’s dynamic invocation
API), or
3. ORB’s API

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

c a ll p a th in re a lity

C lie n t Se rve r

c a ll p a th fro m c lie n t p e rsp e c t iv e


Clie n t Se rve r Stu b Ske le to n

ORB ORB

Fig. 26.6 Call path from a client to a distributed object.

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

• An ORB communicates with servants through


1. a static skeleton,
2. a dynamic interface, or
3. a servant’s object adapter.

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

Clie n ts Se rv a n ts

Dy na mic IDL O RB Sta t ic IDL Dy na mic O b je c t


In vo c a tio n Stu b s In te rfa c e Ske le t o n Ske le t o n Ad a p te r

ORB

Fig. 26.8 ORB request-interface structure. Courtesy of Object Management Group, Inc.

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

• CORBAservices are the baseline services


available to all objects sitting on the ORB
communication bus.
1. Naming Service
2. Event Management Service
3. Life Cycle Service
4. Persistent State Service
5. Transaction Service
6. Concurrency Service
7. Relationship Service
8. Externalization Service

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

9. Query Service
10. Licensing Service
11. Property Service
12. Time Service
13. Security Service
14. Notification Service
15. Trader Service
16. Collections Service

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

• CORBAfacilities come in two groups:


1. horizontal facilities
– target client-side functionality
2. vertical facilities
– target domain-specific functionality

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

• Horizontal facilities specifications:


1. Mobile Agents Facility
2. Printing Facility
3. Internationalization Facility
• Vertical facilities domain-specific services are
being developed for various business areas:
1. Common Enterprise Models
2. Finance/Insurance
3. Electronic Commerce
4. Manufacturing
5. Healthcare
6. Telecommunications

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

7. Transportation
8. Life Science Research
9. Utilities
10. C4I (Command, Control, Communications, Computers, and
Intelligence)
11. Space

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

No n-sta n d a rd ize d a p p - Ap p lic a tio n d o ma in - Ho rizo nta l fa c ility


sp e c ific in te rfa c e s sp e c ific in t e rfa c e s in te rfa c e s
Ap p lic a tio n In te rfa c e s C o mm o n Fa c ilitie s
CORBAfacilities Do m a in In te rfa c e s
CORBAfacilities

O b je c t Re q u e st Bro ke r

Ob je c t Se rv ic e s
G e n e ra l se rvic e in te rfa c e s

Fig. 26.7 Object Management Architecture reference


model. Courtesy of Object Management Group, Inc.

 2002 Prentice Hall. All rights reserved.


26.4 Technical/Architectural Overview (cont.)

• Applications Objects are the top layer of the


OMA.
• Application Objecs have the functionality not
found at the domain layer, facilities layer or the
services layer.
• Basic concepts of distributed systems are the same
regardless of the designed system’s size.
• An understanding of the OMA means a head start
in developing an architecture, because most pieces
needed are defined in the OMA.

 2002 Prentice Hall. All rights reserved.


26.5 CORBA Basics

IDL J a va
module package
interface interface
struct class
const public static final
boolean boolean
char char
wchar wchar
octet octet
string java.lang.String
wstring java.lang.String
short short
unsigned short short
long int
unsigned long int
long long long
unsigned long long long
float float
double double
fixed (not supported in idlj) java.math.BigDecimal
sequence [] (array)
[] (array) [] (array)
Fig . 26.9 IDL ke yw o rd s, typ e s a n d th e ir m a p p in g s to J a va ke yw o rd s.

 2002 Prentice Hall. All rights reserved.


1 /* Outline
2 * Any comments located outside of the module declaration are
3 * ignored by the IDL compiler. This multi-line comment does
4 * not appear in any of the files generated by idlj.
5 */ Fig. 26.10 IDL file
6 testing many of the
7 // This single-line comment is also ignored by the IDL compiler IDL keywords and
8
types.
9 module maptest { maps directly to Java package maptest
10
11 // This comment appears in the generated files for StructMap Line 9
12 struct StructMap { maps directly to a Java class named StructMap (StructMap
13
14 // This comment appears at
may contain object references but is declared
start of the type declarations Linefinal,
12 which
15 boolean boolValue; prevents it from being subclassed)
16 char charValue;
17 wchar wCharValue; Lines 15-28
18 octet octetValue;
19 string stringValue; Line 33
20 wstring wStringValue;
21 short shortValue;
primitive types map to
22 unsigned short uShortValue; corresponding Java primitive
Line 34 types
23 long longValue;
24 unsigned long uLongValue;
25 long long longLongValue;
26 unsigned long long uLongLongValue;
27 float floatValue;
28 double doubleValue;
29
30 // fixed fixedValue; not supported by JavaIDL
31 };
32
33 typedef sequence <StructMap> StructMapSeq; unbounded sequence maps to a
34 typedef sequence <StructMap, 5> BoundStructMapSeq; Java array of type
bounded sequence
StructMap mapsHall.
to
35
 2002 Prentice
StructMap Allarray of size 5
rights reserved.
36 typedef long IntArray[ 5 ]; Outline
37
38 // This comment appears above
39 // the interface declaration for interfaceName
40 interface InterfaceName { Fig. 26.10 IDL file
41 testing many of the
42 // comment above the readwrite attribute maps to array of type
IDLint of size 5and
keywords
43 attribute long anAttribute;
44 readonly attribute long roAttribute; types.
45 const long constantValue = 42;
maps to methods with signatures:
46 Line 36
47 // comment above the methods
48 void seqMethod( in StructMapSeq seq );
public void anAttribute(int x)
49 void boundSeqMethod( in BoundStructMapSeq seq ); Line 40
50 void arrayMethod( in IntArray array );
and
51 void intOutMethod( inout long intValuemaps
); to interface
maps to method with signature:
52 };
public int InterfaceName
anAttribute()
Line 43(exposes
53 }; // end module maptest public functionality available to remote clients)
public int roAttribute()
Line 44
maps to immutable int field with value 42
Line 45

methods will pass a copy of argument, i.e., Line48


call-by-value (methods defined with treats arguments as references,
keyword out pass references as regardless of primitivesLine49
or
arguments, i.e., call-by-reference) object types
Line 50

Line 51
 2002 Prentice Hall.
All rights reserved.
1 package maptest; Outline
2
3
4 /**
5 * maptest/StructMap.java Fig. 26.11 IDL-
6 * Generated by the IDL-to-Java compiler (portable), version "3.0" generated file
7 * from maptest.idl StructMap.java
8 * Monday, May 14, 2001 4:18:09 PMcannot
PDT inherit from this class
9 */
10 Line 33
11
12 // This comment appears in the generated files for StructMap
13 public final class StructMap implements Lines 12, 17
14 org.omg.CORBA.portable.IDLEntity
comments appearing in IDL file
15 { Line 13
16
17 // This comment appears at start of the type declarations
18 public boolean boolValue = false;
19 public char charValue = ( char ) 0;
20 public char wCharValue = ( char ) 0;
21 public byte octetValue = ( byte ) 0;
22 public String stringValue = null;
23 public String wStringValue = null;
24 public short shortValue = ( short ) 0;
25 public short uShortValue = ( short ) 0;
26 public int longValue = ( int ) 0;
27 public int uLongValue = ( int ) 0;
28 public long longLongValue = ( long ) 0;
29 public long uLongLongValue = ( long ) 0;
30 public float floatValue = ( float ) 0;
31 public double doubleValue = ( double ) 0;
32
33 public StructMap () default constructor-all fields
34 { initialized to 0, 
false, or null
2002 Prentice Hall.
35 } // ctor
All rights reserved.
36 Outline
37 public StructMap( boolean _boolValue, char _charValue,
38 char _wCharValue, byte _octetValue, String _stringValue,
39 String wStringValue, short _shortValue,
40 short _uShortValue, int _longValue, int _uLongValue, Fig. 26.11 IDL-
41 long _longLongValue, long _uLongLongValue, generated file
42 float _floatValue, double _doubleValue ) StructMap.java
43 {
44 boolValue = _boolValue;
45 charValue = _charValue;
46 wCharValue = _wCharValue;
47 octetValue = _octetValue;
48 stringValue = _stringValue;
49 wStringValue = _wStringValue;
50 shortValue = _shortValue;
51 uShortValue = _uShortValue;
52 longValue = _longValue;
53 uLongValue = _uLongValue;
54 longLongValue = _longLongValue;
55 uLongLongValue = _uLongLongValue;
56 floatValue = _floatValue;
57 doubleValue = _doubleValue;
58 } // ctor
59
60 } // class StructMap

 2002 Prentice Hall.


All rights reserved.
1 package maptest; Outline
2
3
4 /**
5 * maptest/InterfaceNameOperations.java Fig. 26.12 IDL-
6 * Generated by the IDL-to-Java compiler (portable), version "3.0" generated file
7 * from maptest.idl InterfaceNameOpe
8 * Monday, May 14, 2001 4:18:09 PM PDT
9 */ rations.java
10
11 Line 13
12 // the interface declaration for InterfaceName
13 public interface InterfaceNameOperations generated from IDL file
14 { Lines 16, 19
15 // comment above the readwrite attribute interface declaration
16 int anAttribute();
17 Line 20
18 // comment above the readwrite attribute
generated from attribute
anAttribute
generated fromLines 23-26attribute
19 void anAttribute(int newAnAttribute);
20 int roAttribute(); read-only
21 roAttribute
22 // comment above methods
23 void seqMethod( maptest.StructMap[] seq );
24 void boundSeqMethod( maptest.StructMap[] seq );
25 void arrayMethod( int[] array ); generated method definitions
26 void intOutMethod( org.omg.CORBA.IntHolder intValue );
27 } // interface InterfaceNameOperations

 2002 Prentice Hall.


All rights reserved.
1 package maptest; Outline
2
3 /**
4 * maptest/InterfaceName.java
5 * Generated by the IDL-to-Java compiler (portable), version "3.0" Fig. 26.13 IDL-
6 * from maptest.idl generated file
7 * Monday, May 14, 2001 4:18:09 PM PDT InterfaceName.ja
8 */
9 va
10 // the interface declaration for InterfaceName
11 public interface InterfaceName extends InterfaceNameOperations, Line 14
12 org.omg.CORBA.Object, org.omg.CORBA.portable.IDLEntity
13 {
14 public static final int constantValue = ( int ) ( 42 );
15 } // interface InterfaceName

constants will always appear in


file named after the interface
declaration

 2002 Prentice Hall.


All rights reserved.
26.5 CORBA Basics (cont.)

• Method call types:


– synchronous
• client makes call on remote blocking method
– standard method call on remote service
• client makes call on remote non-blocking method
– remote method qualified with oneway modifier in IDL
file
– remote method receives only in arguments
– asynchronous
• client makes synchronous call on remote method, remote
service responds at a later time by calling method on client
• must be qualified with oneway to prevent deadlock

 2002 Prentice Hall. All rights reserved.


26.5 CORBA Basics (cont.)

1. registerClient( this )

Clie n t Se rve r

2. clent.endMessage()
C lie n t a n d se rve r a re n o w d e a d lo c ke d .

Fig. 26.14 Deadlock caused by client calling a server that calls the client.

 2002 Prentice Hall. All rights reserved.


26.6 Example: AlarmClock

• Example of a typical push-model application


– client sets alarm on server
– server notifies client each time internal alarm event ocurrs

 2002 Prentice Hall. All rights reserved.


1 // Fig. 26.15: alarmclock1.idl Outline
2 // The IDL for the AlarmClock example
3
4 module alarm {
5 interface AlarmListener { Fig. 26.15
6 void updateTime( in long long newTime ); alarmclock1.idl
7 };
8
9 interface AlarmClock { Line 12
10 const string NAME = "AlarmClock";
11 Line 13
12 oneway void addAlarmListener( in string listenerName,
13 in AlarmListener listener );
14
15 void setAlarm( in string listenerName,
16 in long long seconds );
17 };
18 };

receive copy of listener stub


declare non-blocking method

 2002 Prentice Hall.


All rights reserved.
1 // Fig. 26.16: AlarmClockImpl.java Outline
2 // Implementation of AlarmClock server.
3
4 package com.deitel.advjhtp1.idl.alarm;
5 Fig. 26.16
6 // Java core packages AlarmClockImpl.j
7 import java.util.*; ava is the
8
9 // Java extension packages AlarmClock server
10 import org.omg.CORBA.ORB; implementation.
11 import org.omg.CosNaming.*;
12 import org.omg.CosNaming.NamingContextPackage.*;
13 Line 21
14 public class AlarmClockImpl extends _AlarmClockImplBase {
15
16 // list contains name/alarm pairs of register service with Naming Service
17 // registered objects waiting for an alarm
18 private Hashtable alarmList = new Hashtable();
19
20 // register AlarmClockImpl object with Naming Service
21 public void register( String corbaName, String params[] )
22 throws org.omg.CORBA.ORBPackage.InvalidName,
23 org.omg.CosNaming.NamingContextPackage.InvalidName,
24 CannotProceed, NotFound
25 {
26 if ( ( corbaName == null ) ||
27 ( corbaName.trim().length() == 0 ) )
28 throw new IllegalArgumentException(
29 "Registration name cannot be null or blank");
30
31 // create and initialize ORB
32 ORB orb = ORB.init( params, null );
33
34 // register this object with ORB
35 orb.connect( this );
 2002 Prentice Hall.
All rights reserved.
36 Outline
37 // retrieve reference to Naming Service
38 org.omg.CORBA.Object corbaObject =
39 orb.resolve_initial_references( "NameService" );
40 NamingContext naming = Fig. 26.16
41 NamingContextHelper.narrow( corbaObject ); AlarmClockImpl.j
42 ava is the
43 // create NameComponent array with path information to
44 // find this object AlarmClock server
45 NameComponent namingComponent = implementation.
46 new NameComponent( corbaName, "" );
47 NameComponent path[] = { namingComponent };
48 Line 56
49 // bind AlarmClockImpl object with ORB
50 naming.rebind( path, this ); add listener to internal list
51 System.out.println( "Rebind complete" );
52 }
53
54 // method used by clients wanting to register
55 // as callback/listener objects
56 public void addAlarmListener( String listenerName,
57 AlarmListener listener )
58 throws DuplicateNameException
59 {
60 if ( listenerName == null ||
61 listenerName.trim().length() == 0 )
62 throw new IllegalArgumentException(
63 "Name cannot be null or blank");
64 else
65
66 if ( alarmList.get( listenerName ) != null )
67 throw new IllegalArgumentException(
68 "Name is already registered, please choose another" );
 2002 Prentice Hall.
All rights reserved.
69 else Outline
70
71 if ( listener == null )
72 throw new IllegalArgumentException(
73 "Listener cannot be null" ); Fig. 26.16
74 AlarmClockImpl.j
75 // create new Timer and save it under listener name ava is the
76 alarmList.put( listenerName, new AlarmTimer( listener ) );
77 } AlarmClock server
78 implementation.
79 // Set an alarm for a client. If client not registered
80 // throw a runtime exception.
81 public void setAlarm( String name, long seconds ) Line 90
82 {
83 // get alarm for particular client
84 AlarmTimer timer = ( AlarmTimer ) alarmList.get( name );
85
86 if ( timer == null ) schedule an alarm for time
87 throw new IllegalArgumentException( specified by remote client
88 "No clock found for the incoming name" );
89 else
90 timer.schedule( new TaskWrapper(timer.getListener(),
91 seconds), seconds * 1000 );
92 }
93
94 // main method to execute AlarmClock server
95 public static void main( String args[] ) throws Exception
96 {
97 AlarmClockImpl alarm = new AlarmClockImpl();
98 alarm.register( AlarmClock.NAME, args );
99
100 java.lang.Object object = new java.lang.Object();
101
 2002 Prentice Hall.
All rights reserved.
102 // keep server alive Outline
103 synchronized( object ) {
104 object.wait();
105 }
106 } Fig. 26.16
107 AlarmClockImpl.j
108 // Every listener get an AlarmTimer assigned to them. ava is the
109 private class AlarmTimer extends Timer {
110 AlarmClock server
111 // The listener this Timer is assigned to. implementation.
112 private AlarmListener listener;
113
114 public AlarmTimer( AlarmListener l ) Line 129
115 {
116 listener = l;
117 }
118
119 // Accessor method so we can get to the listener
120 // object reference.
121 public AlarmListener getListener()
122 {
123 return listener;
124 }
125 } // end of private inner class TaskWrapper
126
127 // TaskWrapper takes care of calling our clients
128 // when their alarm expires.
129 private class TaskWrapper extends TimerTask {
130 calls client when alarm expires
131 // The reference to our listener
132 private AlarmListener listener;
133 private long seconds;
134
 2002 Prentice Hall.
All rights reserved.
135 // TaskWrapper needs to know who to call and Outline
136 // how long was the alarm set (in seconds).
137 public TaskWrapper( AlarmListener l, long s )
138 {
139 listener = l; Fig. 26.16
140 seconds = s; AlarmClockImpl.j
141 } ava is the
142
143 public void run() AlarmClock server
144 { implementation.
145 // Go wake them up!
146 listener.updateTime(seconds); call-back
Line 146
147
148 // Discard this TaskWrapper. When the client
149 // wants a new alarm we create a new TaskWrapper.
150 this.cancel();
151 }
152 } // end private inner class TaskWrapper
153 } // end class AlarmClockImpl

 2002 Prentice Hall.


All rights reserved.
1 // Fig. 26.17: ClockClientGUI.java Outline
2 // GUI used by the AlarmClockClient.
3
4 package com.deitel.advjhtp1.idl.alarm;
5 Fig. 26.17
6 // Java core packages ClockClientGUI
7 import java.awt.*; informs the user when
8 import java.awt.event.*;
9 the alarm has
10 // Java extension packages sounded.
11 import javax.swing.*;
12
13 public class ClockClientGUI extends JFrame {
14 private JLabel outputLabel;
15
16 // set up GUI
17 public ClockClientGUI()
18 {
19 super( "Clock GUI" );
20
21 outputLabel =
22 new JLabel( "The alarm has not gone off..." );
23 getContentPane().add( outputLabel, BorderLayout.NORTH );
24
25 setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
26 setResizable( false );
27 Dimension screenSize =
28 Toolkit.getDefaultToolkit().getScreenSize();
29 setSize( new Dimension( 450, 100 ) );
30 setLocation( ( screenSize.width - 450 ) / 2,
31 ( screenSize.height - 100 ) / 2 );
32 }
33
 2002 Prentice Hall.
All rights reserved.
34 // set label's text Outline
35 public void setText( String message )
36 {
37 outputLabel.setText( message );
38 } Fig. 26.17
39 ClockClientGUI
40 } // end of class ClockClientGUI informs the user when
the alarm has
sounded.

 2002 Prentice Hall.


All rights reserved.
1 // Fig. 26.18: AlarmClockClient.java Outline
2 // Client of the AlarmClock service
3
4 package com.deitel.advjhtp1.idl.alarm;
5 Fig. 26.18
6 // OMG CORBA packages AlarmClockClient
7 import org.omg.CORBA.ORB; is the AlarmClock
8 import org.omg.CosNaming.*;
9 import org.omg.CosNaming.NamingContextPackage.*; client.
10
11 public class AlarmClockClient extends _AlarmListenerImplBase { Line 34
12
13 // Reference to the GUI to be displayed
14 private ClockClientGUI gui;
15
16 // Reference to the alarm clock server we connect to
17 private AlarmClock alarmClock;
18
19 // Name of this client used by server to make proper callback
20 private String name;
21
22 public AlarmClockClient( String params[] ) throws Exception
23 {
24 // create displayable name that is unique among VMs
25 // running on same computer (or at least randomly unique)
26 name = new Long(
27 System.currentTimeMillis() % 10000 ).toString();
28
29 // create GUI to display name and
30 // number of seconds before alarm expires connect to service
31 gui = new ClockClientGUI();
through helper method
32
33 // connect to TimeService
34 connectToAlarmServer( name, params );
35
 2002 Prentice Hall.
All rights reserved.
36 // display GUI and wait for user to terminate app. Outline
37 gui.show();
38 }
39
40 // perform connection to AlarmServer Fig. 26.18
41 private void connectToAlarmServer( AlarmClockClient
42 String name, String params[] ) is the AlarmClock
43 throws org.omg.CORBA.ORBPackage.InvalidName,
44 org.omg.CosNaming.NamingContextPackage.InvalidName, client.
45 NotFound, CannotProceed
46 { Lines 41-68
47 // connect AlarmClockClient to an ORB
48 ORB orb = ORB.init( params, null );
49 Line 65
50 // connect to Naming Service and find object obtain reference to service
51 // reference for AlarmClock service
52 org.omg.CORBA.Object corbaObject =
53 orb.resolve_initial_references( "NameService" );
54 NamingContext naming =
55 NamingContextHelper.narrow( corbaObject );
56
57 // resolve object reference in naming
58 NameComponent nameComponent =
59 new NameComponent( AlarmClock.NAME, "" );
60 NameComponent path[] = { nameComponent };
61 alarmClock =
62 AlarmClockHelper.narrow( naming.resolve( path ) );
63
64 // register this object with AlarmClock service
65 alarmClock.addAlarmListener( name, this ); register listener with service
66 gui.show();
67 updateTime( 0 );
68 }
69
 2002 Prentice Hall.
All rights reserved.
70 // The callback method defined in AlarmListener. Outline
71 public void updateTime( long seconds )
72 {
73 // Make up a length of time to use for the alarm setting.
74 int newTime = ( int )( Math.random() * 10.0 ) + 1; Fig. 26.18
75 gui.setText( "Alarm " + name + " came in at " + seconds + AlarmClockClient
76 " seconds. Resetting to " + newTime + " seconds" ); is the AlarmClock
77 alarmClock.setAlarm( name, newTime );
78 } client.
79
handle call-back
80 // main method to execute client Lines 71-78
81 public static void main( String args[] ) throws Exception
82 {
83 // create client
84 try {
85 AlarmClockClient client = new AlarmClockClient( args );
86 }
87
88 // process exceptions that occur while client executes
89 catch ( Exception exception ) {
90 System.out.println(
91 "Exception thrown by AlarmClockClient:" );
92 exception.printStackTrace();
93 }
94 }
95
96 } // end of class AlarmClockClient

 2002 Prentice Hall.


All rights reserved.
Outline

Fig. 26.18
AlarmClockClient
is the AlarmClock
client.

 2002 Prentice Hall.


All rights reserved.
26.7 Distributed Exceptions

• CORBA specifies two exception types:


1. System Exceptions
– defined for use by CORBA infrastructure
2. User Exceptions
– defined using IDL by developers
• Standard CORBA exceptions map to Java
exceptions as final classes.

 2002 Prentice Hall. All rights reserved.


1 module domain { Outline
2 exception DatabaseException {
3 string msg;
4 };
5 Fig. 26.19 A user-
6 interface CustomerHome { defined CORBA
7 void find( in long key ) raises ( DatabaseException ); exception
8 };
9 }; (DataseException
) and an operation
capable of throwing
the exception.
maps to Java’s throws keyword
declaration of exception
Line 2

Line 7

 2002 Prentice Hall.


All rights reserved.
1 public final class DatabaseException Outline
2 extends org.omg.CORBA.UserException
3 implements org.omg.CORBA.portable.IDLEntity
4 {
5 public String msg = null; Fig. 26.20 The
6 generated
7 public DuplicateNameException () DatabaseExceptio
8 {
9 } // ctor n.java file
10 (reformatted for
11 public DuplicateNameException( String _msg ) clarity)
12 {
13 msg = _msg;
14 } // ctor Line 2
15 } // class DatabaseException
Line 5

defined in IDL file

all exceptions inherit from UserException (which


indirectly inherits from java.lang.Exception)

 2002 Prentice Hall.


All rights reserved.
1 // Fig. 26.21: alarmclock2.idl Outline
2 // The IDL for the AlarmClock example
3
4 module alarm {
5 exception DuplicateNameException { Fig. 26.21
6 string msg; Alarmclock2.idl
7 }; is the IDL for the
8
9 interface AlarmListener { AlarmClock
10 void updateTime( in long long newTime ); example.
11 };
12 changes to previous alarmLines
clock5-7,
IDL18
definition
13 interface AlarmClock {
14 const string NAME = "AlarmClock";
15
16 void addAlarmListener( in string listenerName,
17 in AlarmListener listener )
18 raises( DuplicateNameException );
19
20 void setAlarm( in string listenerName,
21 in long long seconds );
22 };
23 };

 2002 Prentice Hall.


All rights reserved.
1 public void addAlarmListener( String listenerName, Outline
2 AlarmListener listener ) throws DuplicateNameException
3 {
4 if ( listenerName == null ||
5 listenerName.trim().length() == 0 ) Fig. 26.22 Excerpt
6 throw new IllegalArgumentException( from
7 "Name cannot be null or blank" ); AlarmClockImp.ja
8 else
9 va
10 if ( list.get( listenerName ) != null ) method can now throw exceptions
11 throw new DuplicateNameException( Line 2
12 "Name is already registered, please choose another" );
13 else
14
15 if ( listener == null )
16 throw new IllegalArgumentException(
17 "Listener cannot be null" );
18
19 // Create a new Timer and save it under the listener name
20 alarmList.put( listenerName, new AlarmTimer( listener ) );
21 }

 2002 Prentice Hall.


All rights reserved.
26.8 Case Study: Chat

• Chat is a basic network application using a


central broadcasting point where a collection of
clients pushes in messages and the middleware
pushes out messages.
• Following use cases:
1. Connect: A client finds and connects to a chat server.
2. Disconnect: A client completes a chat session by
disconnecting from the chat server.
3. Send message: A connected client creates a chat message and
gives the message to the chat server.
4. Receive message: A connected client receives messages
delivered by the chat server.

 2002 Prentice Hall. All rights reserved.


1 // Chat.idl Outline
2 // This file contains the IDL defining the API to the ChatServer
3 // as well as the ChatClient and ChatMessage.
4
5 module corba { Fig. 26.23
6 struct ChatMessage { abstracting message toChatClient
struct and
7 ChatMessage
8 // ChatMessage properties enables each client to receive its own
9 string from; interface
copy of message object. Prevents definitions.
10 string message; bottleneck problem associated with
11 }; Line
sending reference to one 6
message
12
13 module client { object.
14 interface ChatClient { Lines 13-22, 24-40
15
16 // receive new message
17 void deliverMessage( in ChatMessage message ); Line 33
18
19 // method called when server shuting down Line 33
20 void serverStopping();
21 };
22 };
23 two different scope levels
24 module server {
25 interface StoppableChatServer {
26 void stopServer(); resolves to client scope level,
27 }; resolves IDL namespace in same way “.”
ChatClient interface
28
29 interface ChatServer {
resolves Java package/class namespace
30 const string NAME = "ChatServer";
31
32 // register new ChatClient with ChatServer
33 oneway void registerClient( in client::ChatClient client );
34
 2002 Prentice Hall.
All rights reserved.
35 // unregister ChatClient with ChatServer Outline
36 void unregisterClient( in client::ChatClient client );
37
38 // post new message to ChatServer
39 void postMessage( in ChatMessage message ); Fig. 26.23
40 }; ChatClient and
41 ChatMessage
42 // Create a combination interface
43 interface ChatService : ChatServer, StoppableChatServer { interface definitions.
44 };
45 };
46
47 }; // end module corba

 2002 Prentice Hall.


All rights reserved.
26.8.2 ChatServerImpl.java

• IDL compiler generates following server-side use


files:
– messenger\client\_ChatClientImplBase.java
– messenger\server\_ChatServerImplBase.java
– messenger\client\ChatClient.java
– messenger\client\ChatClientOperations.java
– messenger\ChatMessage.java
– messenger\server\ChatServer.java
– messenger\server\ChatServerOperations.java

 2002 Prentice Hall. All rights reserved.


26.8.2 ChatServerImpl.java

• IDL compiler also generates following support


files:
– messenger\ChatMessageHelper.java
– messenger\ChatMessageHolder.java

 2002 Prentice Hall. All rights reserved.


1 // ChatServerImpl.java Outline
2 // ChatServerImpl implements the CORBA ChatServer.
3 package com.deitel.messenger.corba.server;
4 abstract class that requires ChatServerImpl to implement
5 // Java operations
core packages defined in interface ChatServerOperations Fig. 26.24
6 import java.io.*; ChatServerImpl
7 import java.util.*; implementation of the
8 import java.net.MalformedURLException;
9 CORBA
10 // Java extension packages ChatServer.
11 import org.omg.CosNaming.*;
12 import org.omg.CosNaming.NamingContextPackage.*;
13 import org.omg.CORBA.*; Line 19
14
15 // Deitel packages Line 32
16 import com.deitel.messenger.corba.ChatMessage;
17 import com.deitel.messenger.corba.client.ChatClient;
18
19 public class ChatServerImpl extends _ChatServerImplBase {
20
21 // The ORB that connects us to the network
22 private ORB orb;
23
24 // Map of ChatClient references
25 private Map clients = new HashMap();
26 register service
27 // construct new ChatServerImpl
28 public ChatServerImpl( String[] args )
29 throws Exception
30 {
31 super();
32 register( ChatServer.NAME, args );
33 }
34
 2002 Prentice Hall.
All rights reserved.
35 // register new ChatClient with ChatServer Outline
36 public void registerClient( ChatClient client )
37 {
38 // add client to Map of registered clients
39 String key = orb.object_to_string( client ); Fig. 26.24
40 synchronized( clients ) { ChatServerImpl
41 clients.put( key, client ); implementation of the
42 }
43 CORBA
44 System.out.println( "Registered Client: " + key ); ChatServer.
45
46 } // end method registerClient
47
48 // unregister client with ChatServer
49 public void unregisterClient( ChatClient client )
50 {
51 // remove client from Map of registered clients
52 String key = orb.object_to_string( client );
53 synchronized( clients ) {
54 clients.remove( key );
55 }
56
57 System.out.println( "Unregistered Client: " + key );
58
59 } // end method unregisterClient
60
61 // post new message to ChatServer
62 public void postMessage( ChatMessage message )
63 {
64 Iterator iterator = null;
65
66 // get Iterator for Set of registered clients
67 synchronized( clients ) {
68 iterator = new HashSet( clients.entrySet() ).iterator();
69 }
 2002 Prentice Hall.
All rights reserved.
70 Outline
71 // send message to every ChatClient
72 while ( iterator.hasNext() ) {
73 ChatClient client =
74 ( ChatClient ) ( ( Map.Entry ) iterator.next() ).getValue(); Fig. 26.24
75 client.deliverMessage( message ); ChatServerImpl
76 } implementation of the
77
78 } // end method postMessage CORBA
79 remote method invocation sending a struct
ChatServer.
80 // Register ChatServerImpl object with Naming Service
81 public void register( String serverName, String[] parameters )
82 throws NotFound, CannotProceed, Line 75
83 org.omg.CosNaming.NamingContextPackage.InvalidName,
84 org.omg.CORBA.ORBPackage.InvalidName
85 {
86 if ( serverName == null )
87 throw new IllegalArgumentException(
88 "Registration name can not be null" );
89
90 // Bind ChatServerImpl object to Naming Service.
91 // Create and initialize ORB.
92 orb = ORB.init( parameters, null );
93
94 // create servant and register it with ORB
95 orb.connect( this );
96
97 org.omg.CORBA.Object corbaObject =
98 orb.resolve_initial_references( "NameService" );
99 NamingContext naming =
100 NamingContextHelper.narrow( corbaObject );
101 NameComponent namingComponent =
102 new NameComponent( serverName, "" );
103 NameComponent path[] = { namingComponent };
104 naming.rebind( path, this );
 2002 Prentice Hall.
All rights reserved.
105 System.out.println( "Server bound to naming" ); Outline
106 }
107
108 // notify each client that server is shutting down and
109 // terminate server application Fig. 26.24
110 public void stopServer() ChatServerImpl
111 { implementation of the
112 System.out.println( "Terminating server ..." );
113 CORBA
114 Iterator iterator = null; ChatServer.
115
116 // get Iterator for Set of registered clients
117 synchronized( clients ) {
118 iterator = new HashSet( clients.entrySet() ).iterator();
119 }
120
121 // send serverStopping message to every ChatClient
122 while ( iterator.hasNext() ) {
123 ChatClient client = ( ChatClient ) iterator.next();
124 client.serverStopping();
125 System.err.println( "Disconnected: " + client );
126 }
127
128 // create Thread to terminate application after
129 // stopServer method returns to caller
130 Thread terminator = new Thread(
131 new Runnable() {
132
133 // sleep for 5 seconds, print message and terminate
134 public void run()
135 {
136 // sleep
137 try {
138 Thread.sleep( 5000 );
139 }
 2002 Prentice Hall.
All rights reserved.
140 Outline
141 // ignore InterruptedExceptions
142 catch ( InterruptedException exception ) {}
143
144 System.err.println( "Server terminated" ); Fig. 26.24
145 System.exit( 0 ); ChatServerImpl
146 } implementation of the
147 }
148 ); CORBA
149 ChatServer.
150 terminator.start(); // start termination thread
151
152 } // end method stopServer Line 168
153
154 // main method to execute ChatServerImpl
155 public static void main( String[] args )
156 {
157 // set up ChatServerImpl object and bind to Naming Service
158 try {
159
160 // create ChatServerImpl object
161 ChatServerImpl chatServerImpl =
162 new ChatServerImpl( args );
163
164 java.lang.Object object = new java.lang.Object();
165
166 // keep server alive
167 synchronized( object ) {
168 object.wait(); ensure server object not garbage collected
169 }
170 }
171

 2002 Prentice Hall.


All rights reserved.
172 // process problems setting up ChatServerImpl object Outline
173 catch ( Exception exception ) {
174 exception.printStackTrace();
175 System.exit( 1 );
176 } Fig. 26.24
177 ChatServerImpl
178 } // end method main implementation of the
179 }
CORBA
ChatServer.

 2002 Prentice Hall.


All rights reserved.
26.8.3 DeitelMessenger.java

• IDL compiler generates following client-use files:


– messenger\client\_ChatClientStub.java
– messenger\server\_ChatServerStub.java
– messenger\client\ChatClient.java
– messenger\client\ChatClientOperations.java
– messenger\ChatMessage.java
– messenger\server\ChatServer.java
– messenger\server\ChatServerHelper.java
– messenger\server\ChatServerOperations.java

 2002 Prentice Hall. All rights reserved.


26.8.3 DeitelMessenger.java (cont.)

• Following generated server-side files are available


for client to accept callback invocations from
server:
– messenger\client\_ChatClientImplBase.java
– messenger\client\ChatClient.java
– messenger\client\ChatClientOperations.java
• Following support files generated:
– messenger\client\ChatClientHelper.java
– messenger\client\ChatClientHolder.java
– messenger\ChatMessageHelper.java
– messenger\ChatMessageHolder.java
– messenger\server\ChatServerHolder.java

 2002 Prentice Hall. All rights reserved.


1 // CORBAMessageManager.java Outline
2 // CORBAMessageManager implements the ChatClient remote
3 // interface and manages incoming and outgoing chat messages
4 // using CORBA.
5 abstract class
package requires CORBAMessageManager implement operation
com.deitel.messenger.corba.client; Fig. 26.25
6 defined in ChatClientOperations (method deliverMessage) CORBAMessageMana
7 // Java core packages ger implementation
8 import java.awt.*;
9 import java.awt.event.*; of interface
10 import java.util.*; MessageManager
11 using CORBA.
12 // Java extension packages
13 import org.omg.CosNaming.*;
14 import org.omg.CosNaming.NamingContextPackage.*; Line 23
15 import org.omg.CORBA.*;
16
17 // Deitel packages
18 import com.deitel.messenger.*;
19 import com.deitel.messenger.corba.client.ChatClient;
20 import com.deitel.messenger.corba.ChatMessage;
21 import com.deitel.messenger.corba.server.*;
22
23 public class CORBAMessageManager extends _ChatClientImplBase
24 implements MessageManager {
25
26 // incoming ORB configuration parameters
27 private String[] configurationParameters;
28
29 // listeners for incoming messages and disconnect notifications
30 private MessageListener messageListener;
31 private DisconnectListener disconnectListener;
32
33 // ChatServer for sending and receiving messages
34 private ChatServer chatServer;
35
 2002 Prentice Hall.
All rights reserved.
36 // CORBAMessageManager constructor Outline
37 public CORBAMessageManager( String[] parameters )
38 {
39 configurationParameters = parameters;
40 } Fig. 26.25
41 CORBAMessageMana
42 // connect to ChatServer ger implementation
43 public void connect( MessageListener listener )
44 throws Exception of interface
45 { MessageManager
46 using
initializes ORB and gets Naming CORBA.
Service object
47 // find ChatServer remote object
48 ORB orb = ORB.init( configurationParameters, null );
49 org.omg.CORBA.Object corbaObject = Lines 43-67
50 orb.resolve_initial_references( "NameService" );
51 NamingContext naming =
52 NamingContextHelper.narrow( corbaObject );
53
54 // Resolve the object reference in naming
55 NameComponent nameComponent =
56 new NameComponent( ChatServer.NAME, "" );
57 NameComponent path[] = { nameComponent };
58 chatServer =
59 ChatServerHelper.narrow( naming.resolve( path ) );
60
61 // register client with ChatServer to receive messages
62 chatServer.registerClient( this );
63
64 // set listener for incoming messages
65 messageListener = listener;
66
67 } // end method connect
68
 2002 Prentice Hall.
All rights reserved.
69 // disconnect from ChatServer Outline
70 public void disconnect( MessageListener listener )
71 throws Exception
72 {
73 if ( chatServer == null ) Fig. 26.25
74 return; CORBAMessageMana
75 ger implementation
76 chatServer.unregisterClient( this );
77 messageListener = null; of interface
78 MessageManager
79 // notify listener of disconnect using CORBA.
80 fireServerDisconnected( "" );
81
82 } // end method disconnect Lines 92-93
83
84 // send ChatMessage to ChatServer
85 public void sendMessage( String fromUser, String message )
86 throws Exception
87 {
88 if ( chatServer == null )
89 return;
90
91 // create ChatMessage with message text and user name
92 ChatMessage chatMessage =
93 new ChatMessage( fromUser, message ); create struct, copy sent to server
94
95 // post message to ChatServer
96 chatServer.postMessage( chatMessage );
97
98 } // end method sendMessage
99

 2002 Prentice Hall.


All rights reserved.
100 // process delivery of ChatMessage from ChatServer Outline
101 public void deliverMessage( ChatMessage message )
102 {
103 if ( messageListener != null )
104 messageListener.messageReceived( message.from, Fig. 26.25
105 message.message ); CORBAMessageMana
106 } ger implementation
107
108 // process server shutting down notification of interface
109 public void serverStopping() MessageManager
110 { using from
receive broadcasts CORBA.
server
111 chatServer = null;
112 fireServerDisconnected( "Server shut down." );
113 } Line 104-105
114
115 // register listener for disconnect notifications
116 public void setDisconnectListener(
117 DisconnectListener listener )
118 {
119 disconnectListener = listener;
120 }
121
122 // send disconnect notification
123 private void fireServerDisconnected( String message )
124 {
125 if ( disconnectListener != null )
126 disconnectListener.serverDisconnected( message );
127 }
128 }

 2002 Prentice Hall.


All rights reserved.
1 // DeitelMessenger.java Outline
2 // DeitelMessenger uses ClientGUI and CORBAMessageManager to
3 // implement an CORBA chat client.
4 package com.deitel.messenger.corba.client;
5 Fig. 26.26
6 // Deitel packages DeitelMessenger
7 import com.deitel.messenger.*; application for
8
9 public class DeitelMessenger { launching the CORBA
10 chat client.
11 // launch DeitelMessenger application
12 public static void main( String args[] ) throws Exception
13 {
14 // create CORBAMessageManager for communicating with server
15 MessageManager messageManager =
16 new CORBAMessageManager( args );
17
18 // configure and display chat window
19 ClientGUI clientGUI = new ClientGUI( messageManager );
20 clientGUI.setSize( 300, 400 );
21 clientGUI.setResizable( false );
22 clientGUI.setVisible( true );
23 }
24 }

 2002 Prentice Hall.


All rights reserved.
26.8.4 Running Chat

• Steps for running example follows:


1. Compile IDL file using idlj
idlj -pkgPrefix chat com.deitel.advjhtp1.idl
-td c:\src -fall chat.idl
2. Implement and compile server class.
3. Implement and compile client class.
4. Open window, run tnameserv Naming Service:
tnameserv –ORBInitialPort 1050
5. Open window, run server:
java com.deitel.messenger.corba.server.ChatServerImpl
-ORBInitialPort 1050
6. Open window, run client
java com.deitel.messenger.corba.client.DeitelMessenger
-ORBInitialPort 1050

 2002 Prentice Hall. All rights reserved.


26.8.5 Issues

• Why use local objects for the messages received


by the clients?
• How would making ChatMessage a distributed
object alter the application’s complexity?

 2002 Prentice Hall. All rights reserved.


26.8.5 Issues (cont.)

• Changing ChatMessage from struct to


interface.
– Advantages:
• clearly defined API and proper encapsulation of
ChatMessage
• would be remote object (all clients could inspect message
object and see any changes immediately)
– Disadvantages:
• clients sharing single remote object could create network
bottleneck
• must deal with data locking issues due to synchronous data
access by multiple clients

 2002 Prentice Hall. All rights reserved.


26.8.5 Issues (cont.)

• Objects-by-Value (OBV) specification defines


new kind of interface type-valuetypes.
– a struct with behavior semantics (ability to support
declaration of operations)
• Advantages:
– ability to pass copies of “objects” around a distributed
system that contain behavior in addition to data.

 2002 Prentice Hall. All rights reserved.


1 // Fig. 26.27: Chat.idl Outline
2 // This file contains the IDL defining the
3 // API to the ChatServer as well as the
4 // ChatClient and ChatMessage.
5 Fig. 26.27 chat.idl
6 module obvcorba { with ChatMessage
7 valuetype ChatMessage { changed to be a
8
9 // ChatMessage properties valuetype.
10 private string from;
field declarations
11 private string message;
constructor declaration valuetype Lines 7-17
definition
12
13 string getSenderName();
14 string getMessage(); method declarationsLines 10-11
15
16 factory create( in string from, in string message );
17 }; Lines 13-14
18
19 module client { Line 16
20 interface ChatClient {
21
22 // receive new message
23 void deliverMessage( in ChatMessage message );
24 };
25 };
26
27 module server {
28 interface ChatServer {
29 const string NAME = "ChatServer";
30
31 // register new ChatClient with ChatServer
32 void registerClient( in string chatName,
33 in client::ChatClient client );
34
 2002 Prentice Hall.
All rights reserved.
35 // unregister ChatClient with ChatServer Outline
36 void unregisterClient( in string chatName );
37
38 // post new message to ChatServer
39 void postMessage( in ChatMessage message ); Fig. 26.27 chat.idl
40 }; with ChatMessage
41 }; changed to be a
42 }; // end of module obvmessenger
valuetype.

 2002 Prentice Hall.


All rights reserved.
26.8.5 Issues (cont.)

Ke yw o rd s sp e c ific to valuetypes
valuetype
private
public
factory
custom
supports
truncatable
Fig . 26.28 Ke yw o rd s sp e c ific to valuetypes.

 2002 Prentice Hall. All rights reserved.


26.8.5 Issues (cont.)

• To create a Java valuetype object


– define valuetype in an IDL
– compile definition using idlj, and
– derive new class from base valuetype class definition.

 2002 Prentice Hall. All rights reserved.


1 // Fig. 26.29: ChatMessageImpl.java Outline
2 package com.deitel.messenger.obvcorba;
3
4 public class ChatMessageImpl extends ChatMessage {
5 Fig. 26.29
6 // default constructor for empty ChatMessageImpl object ChatMessageImpl
7 public ChatMessageImpl() is the ChatMessage
8 {
9 this( "", "" ); implementation.
10 }
11 derive generated valuetype
Line 4 class
12 // constructor to initialize from and message properties
13 public ChatMessageImpl( String sender, String text )
14 {
15 from = sender;
16 message = text;
17 }
18
19 // return name of sender
20 public String getSenderName()
21 {
22 return from;
23 }
24
25 // get message
26 public String getMessage()
27 {
28 return message;
29 }
30 }

 2002 Prentice Hall.


All rights reserved.
26.9 Comments and Comparisons

• RMI mechanism in JDK 1.2 implements stub-only


communication model.
• CORBA uses skeleton-stub model
• CORBA is a powerful means of designing robust
distributed systems.
– Legacy applications have become valuable long-term assets,
and new applications have become reusable services that can
exchange data in a platform-neutral fashion.

 2002 Prentice Hall. All rights reserved.

You might also like