Sei sulla pagina 1di 71

Chapter 27: Common Object Request

Broker Architecture(CORBA): Part 2


Outline
27.1 Introduction
27.2 Static Invocation Interface (SII), Dynamic
Invocation Interface (DII) and Dynamic Skeleton Interface
(DSI)
27.3 BOAs, POAs and TIEs
27.4 CORBAservices
27.4.1 Naming Service
27.4.2 Security Service
27.4.3 Object Transaction Service
27.4.4 Persistent State Service
27.4.5 Event and Notification Services
27.5 EJBs and CORBAcomponents
27.6 CORBA vs. RMI
27.6.1 When to Use RMI
27.6.2 When to Use CORBA
27.6.3 RMI-IIOP

 2002 Prentice Hall. All rights reserved.


Chapter 27: Common Object Request
Broker Architecture(CORBA): Part 2
27.7 RMIMessenger Case Study Ported to RMI-IIOP
27.7.1 ChatServer RMI-IIOP Implementation
27.7.2 ChatClient RMI-IIOP Implementation
27.7.3 Compiling and Running the ChatServer and
ChatClient
27.8 Future Directions
27.9 Internet and World Wide Web Resources

 2002 Prentice Hall. All rights reserved.


27.1 Introduction

• JavaIDL is the first step into the world of CORBA


and distributed systems.
• Understanding of CORBA concepts at both the
low level (i.e., object adapters) and high level (i.e.,
CORBAservices and CORBAcomponents) is
important.

 2002 Prentice Hall. All rights reserved.


27.2 Static Invocation Interface
(SII), Dynamic Invocation Interface
(DII) and Dynamic Skeleton Interface
(DSI)
• Two ways to invoke a request:
– statically – using Static Invocation Interface (SII)
– relies on creating a request through invoking a static method
in a stub
– stub generated from compile-time definition of an object
type (IDL interface) and object operations (methods
within IDL interface)
– dynamically – using Dynamic Invocation Interface (DII)
– programmatically creates and send invocation request
directly to ORB without assistance of stub
– developers responsible for guaranteeing sending proper type
and number of arguments to invocation
• Server unaware of process that created the
request.
 2002 Prentice Hall. All rights reserved.
27.2 Static Invocation Interface
(SII), Dynamic Invocation Interface
(DII) and Dynamic Skeleton Interface

(DSI) (cont.)
Interface Repository (IR)
– contains descriptive information about distributed objects:
• modules available
• interfaces defined
• names of operations defined within interfaces
• argument types
• return types
• exceptions raised
• Steps needed to make DII call:
• Obtain object reference to server object
• Look up desired method in Interface Repository
• Build argument list using IR’s OperationDef
• Create and initialize Request object
• Invoke Request and wait for call to unblock (return)
• Get results
 2002 Prentice Hall. All rights reserved.
27.2 Static Invocation Interface
(SII), Dynamic Invocation Interface
(DII) and Dynamic Skeleton Interface
(DSI) (cont.)
• Java 1.3 does not ship with an Interface
Repository
• Steps needed to make DII call (without using
Interface Repository):
• Obtain object reference to server object
• Create and initialize a Request object
• Invoke Request and wait for call to unblock (return)
• Get results

 2002 Prentice Hall. All rights reserved.


1 // SystemClockClient.java Outline
2 // Client that uses DII to request the system time from a servant.
3 package com.deitel.advjhtp1.idl.dii;
4
5 // Java core packages Fig. 27.1
6 import java.text.DateFormat; SystemClockClien
7 import java.util.*; t modified to
8
9 // Java extension packages support DII
10 import javax.swing.JOptionPane;
11 Line 20
12 // OMG CORBA packages
13 import org.omg.CORBA.ORB;
14 import org.omg.CosNaming.*; Line 21
15 import org.omg.CosNaming.NamingContextPackage.*;
16
17 public class SystemClockClient implements Runnable { Line 26
18
19 // object reference to desired server
20 private org.omg.CORBA.Object timeServer; holds reference to remote server
21 private ORB orb; used to connect client to server and to create
22
23 // initialize client support objects for invocation to server
24 public SystemClockClient( String[] params ) throws Exception
25 {
26 connectToTimeServer( params ); obtains reference to server
27 startTimer();
28 }
29

 2002 Prentice Hall.


All rights reserved.
30 // use NameService to connect to time server Outline
31 private void connectToTimeServer( String [] params )
32 throws org.omg.CORBA.ORBPackage.InvalidName,
33 org.omg.CosNaming.NamingContextPackage.InvalidName,
34 NotFound, CannotProceed Fig. 27.1
35 { SystemClockClien
36 // Connect to the SystemClock server t modified to
37 orb = ORB.init( params, null );
38 support DII
39 org.omg.CORBA.Object corbaObject =
40 orb.resolve_initial_references( "NameService" );
41 NamingContext naming =
42 NamingContextHelper.narrow( corbaObject );
43
44 // Resolve the object reference in naming
45 NameComponent nameComponent =
46 new NameComponent( "TimeServer", "" );
47 NameComponent path[] = { nameComponent };
48 timeServer = naming.resolve( path );
49 }
50
51 // start timer thread
52 private void startTimer()
53 {
54 Thread thread = new Thread( this );
55 thread.start();
56 }
57
58 // talk to server on a regular basis and display the results
59 public void run()
60 {
61 long time = 0;
62 Date date = null;
63 DateFormat format =
64 DateFormat.getTimeInstance( DateFormat.LONG );
 2002 Prentice Hall.
All rights reserved.
65 String timeString = null; Outline
66 int response = 0;
67
68 org.omg.CORBA.Request request =
69 timeServer._request( "currentTimeMillis" ); Fig. 27.1
70 request.set_return_type( orb.get_primitive_tc( SystemClockClien
71 org.omg.CORBA.TCKind.tk_longlong ) t modified to
72 );
support DII
73 Request object used by client to call server
74 while( true ) {
75 Lines 68-69
76 // invoke method currentTimeMillis using the request object
77 // time = timeServer.currentTimeMillis(); original method invocation
78 request.invoke(); invoke request on server Line 77
79
80 // get time value from request object
81 time = request.result().value().extract_longlong(); Line
obtain 78 response
server
82 date = new Date( time );
83 timeString = format.format( date ); Line 81
84
85 response = JOptionPane.showConfirmDialog( null, timeString,
86 "SystemClock Example", JOptionPane.OK_CANCEL_OPTION );
87
88 if ( response == JOptionPane.CANCEL_OPTION )
89 break;
90 }
91
92 System.exit( 0 );
93 }
94

 2002 Prentice Hall.


All rights reserved.
95 // main method to execute client application Outline
96 public static void main( String args[] )
97 {
98 // create client
99 try { Fig. 27.1
100 new SystemClockClient( args ); SystemClockClien
101 } t modified to
102
103 // process exceptions that occur while client executes support DII
104 catch ( Exception exception ) {
105 System.out.println(
106 "Exception thrown by SystemClockClient:" );
107 exception.printStackTrace();
108 }
109 }
110 }

 2002 Prentice Hall.


All rights reserved.
27.2 Static Invocation Interface (SII,
Dynamic Invocation Interface (DII)
and Dynamic Skeleton Interface (DSI)
(cont.)
• Using Interface Repository enables flexibility at
runtime to discover more about types available in
a distributed system.
• IR functions as a distributed version of the Java
reflection mechanism.
• JavaIDL is not a complete implementation of
CORBA.
– when designing a distributed system with CORBA, use a
third party implementation:
• commercial vendors implementations
• open-source implementations

 2002 Prentice Hall. All rights reserved.


27.3 BOAs, POAs and TIEs

• Object adapter
– stands between a distributed object and its ORB
– enables clients to access ORB services:
• IOR generation
• security
• activation/deactivation
• OMG specified two adapter types:
– Basic Object Adapter (BOA)
• vague definition of an adapter which led to inconsistencies
between different vendors’ implementations
– Portable Object Adapter (POA)
• more widely used, even though more complex than BOAs

 2002 Prentice Hall. All rights reserved.


27.3 BOAs, POAs and TIEs (cont.)

• POA connects an object reference to developer-


written code using code found in IDL generated
skeleton.
– allow fine-grained control
• Distributed objects inherit from a POA base
definition generated by IDL compiler
– enables distributed object to be usable by a POA,
– enables POA to control all access to servant through policies

 2002 Prentice Hall. All rights reserved.


27.3 BOAs, POAs and TIEs (cont.)

• POA policies:
– ImplicitObjectActivation,
• tells POA outside object created servant and activated it
– IDAssignmentPolicy, and
• determines who is responsible for assigning a unique ID to a
given servant
– RequestProcessingPolicy.
• uses object id either to find matching servant or invoke default
service that uses object id to perform lookup in database
• Policy combinations provide POAs with fine-
grained control over one or many servants.

 2002 Prentice Hall. All rights reserved.


27.3 BOAs, POAs and TIEs (cont.)

• Another way for developer to us a POA is to wrap


their servants in a TIE.
– enables interaction with a POA without having servant’s
object implementation inherit structure from POAImpl.
– servant can inherit from other base classes freely

 2002 Prentice Hall. All rights reserved.


27.4 CORBAservices

• CORBAservices define base services and a


support structure useful to a wide range of
applications.
• Five most commonly used services:
1. Naming Service
2. Security Service
3. Object Transaction Service
4. Persistent State Service
5. Event and Notification Services

 2002 Prentice Hall. All rights reserved.


27.4.1 Naming Service

• Associates name objects with arbitrary value


(known as name bindings).
• A path to a name binding consists of zero or more
naming contexts (a collection of unique name
bindings).
• Resolving a name binding returns object
associated with name.
• Binding a name creates association between a
name and an object.
• Multiple name bindings can point to a single
object.
 2002 Prentice Hall. All rights reserved.
27.4.2 Security Service

• Consists of two levels


– Level 1
• provides basic security for
1. user authentication,
2. invocation security, and
3. availability of authentication principals to security-aware
applications
• allows applications to ignore system-security requirements
• requires support for no delegation and single delegation
models

 2002 Prentice Hall. All rights reserved.


27.4.2 Security Service (cont.)

– Level 2
• is everything level 1 provides in addition to:
1. more fine-grained user authentication
2. greater invocation security
3. auditing
4. finer control over secure invocations
5. delegation
6. administrators can set security policies
7. discovery of security policies by security-aware
applications
8. discovery of security policies by ORBs and other
services

 2002 Prentice Hall. All rights reserved.


27.4.3 Object Transaction Service

• Enables CORBA objects to execute as parts of


distributed transactions.
– a transaction describes a collection of interactions where
multiple users may access and/or modify data.
• acronym ACID describes four standard requirements for
reliable transactions:
1. Atomic – completion of numerous steps must be
conducted as one, otherwise each step must be
undone.
2. Consistent – effects of transaction are repeatable
and predictable.
3. Isolated – transaction not interrupted from outside
and gives no indication if execution is proceeding
serially or concurrently.
4. Durable – transaction results are persistent.

 2002 Prentice Hall. All rights reserved.


27.4.3 Object Transaction Service
(cont.)
– transactions complete in one of two ways:
1. committed
• changes are made to persist
2. rolled back
• changes made to data are discarded
– POAs dictate transaction types supported by servants
• shared transactions
• unshared transactions
• shared and unshared transactions

 2002 Prentice Hall. All rights reserved.


27.4.3 Object Transaction Service
(cont.)
• Concepts of transactional clients, transactional
objects and recoverable objects define the OTS.
– transactional clients interact with OTS to create and commit
or rollback a transaction
– transaction objects’ behaviors vary when invoked within a
transaction (object’s data not recoverable)
– recoverable object is a transactional object in which data is
recoverable (maintain their data and capable of restoring
their lost state)
• Java Transaction Service (JTS) is Java
implementation of distributed transaction service
– uses CORBA OTS specification to define protocol

 2002 Prentice Hall. All rights reserved.


27.4.4 Persistent State Service

• Persistent State Service (PSS) stores and retrieves


objects.
• Abstracts interaction between objects and
datastores.
• Persistent State Definition Language (PSDL)
defines a distributed object schema in a portable
fashion.
– PSDL is a superset of IDL
• defines two new constructs
– storagetype
– storagehome

 2002 Prentice Hall. All rights reserved.


27.4.4 Persistent State Service
(cont.)
– contains two definition types:
• abstract definition
– define portable definition of the persistable state of a
CORBA object
• concrete definition

 2002 Prentice Hall. All rights reserved.


1 // The schema for a domain object. This is the abstract definition Outline
2 // needed by the PSS. The concrete definition of Customer is below.
3 abstract storagetype Customer {
4 // The accountNumber is our primary key
5 readonly state string accountNumber; Fig. 27.2
6 state string name; Persistent State
7 }; Definition
8
9 declares abstract
// The factory to be used to retrieve Customer objects storagetype Language
10 declares
abstractdeclares
readable/writable
a read-only
storagehome accountNumber
CustomerHome of Customer { example.
11 name
// using keyword method
The creation statewill create persistent Customers
12 to notify PSDL compiler
Customer create( of
in string accountNumber ); creates Customers
Line 3using method
13 };
14 which fields to persist create, each with
15 // Our factory finder. Use the CustomerDirectory to accountNumberLine as
5 primary key
16 // find any factories used by the system to create
17 // domain objects like Customer
18 catalog CustomerDirectory { Line 6
19 provides CustomerHome customerHome;
20 };
21 Line 12
22 // This is the concrete declaration of the Customer defined
23 // above. These declarations are empty as we are not adding
24 // any addition structure to Customer or its factory.
25 storagetype CustomerImpl implements Customer {};
26
27 storagehome CustomerHomeImpl of CustomerImpl
28 implements CustomerHome {};

 2002 Prentice Hall.


All rights reserved.
27.4.5 Event and Notification
Services
• Event Service defines mechanism that decouples
delivery of events (messages) from source of
events.
– no predefined event types in specification
– keeps track of action events and event listeners
• Supplier creates events that are processed by a
consumer.
• In push model, supplier sends event messages
asynchronously to all consumers registered to
receive messages.
• In pull model, consumer polls supplier for events.
 2002 Prentice Hall. All rights reserved.
27.4.5 Event and Notification
Services (cont.)
• Notification Service is a direct extension of the
Event Service.
– objects can create and destroy event channels arbitrarily, and
can filter output using Filter Objects and Object Constraint
Language

 2002 Prentice Hall. All rights reserved.


27.4.5 Event and Notification
Services (cont.)
• Standard flow of a StructuredEvent:
• finding object reference to Notificaion Service (instance of
EventChannelFactory)
• EventChannelFactory creates an EventChannel
• supplier asks EventChannel to return SupplierAdmin
object
• SupplierAdmin returns a Consumer proxy (such as
StructuredProxyPushConsumer) to an event channel
• access to distributed events (through push or pull models) is
accessible through proxy

 2002 Prentice Hall. All rights reserved.


27.4.5 Event and Notification
Services (cont.)
C oncep tua lly, a Sup plie r send s a n Eve nt to a C onsume r.

Supp lier Co nsumer


Eve nt

An EventChannel deco up les the Supp lier from the Consumer.

Supp lier EventChannel Co nsumer


Eve nt Eve nt

Ad ding a ProxyConsumer a nd ProxySupplier enables further d ecoupling


a nd make s it p ossible to sup po rt bo th the p ush and pull mod els.

Supp lier ProxyConsumer


Eve nt

Event

EventChannel

Event

ProxySupplier Co nsumer
Eve nt

Fig. 27.3 Supplier-to-consumer flow using the Event/Notification Service.

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents

• CORBA Component Model (CCM) Request for


Proposal (RFP) recommends the JavaBeans
component model as basis of a server-side
framework.
• CORBAcomponents based on Component
Implementation Framework (CIF) architecture.
• CIF defines superset of Persistent State Definition
Language called Component IDL (CIDL)
• CIDL is component model for CORBA objects
and a container-programming model where
CORBA components exist at runtime
 2002 Prentice Hall. All rights reserved.
27.5 EJBs and CORBAcomponents
(cont.)
IDL keywords to support the C O RBA
C omponent Model (C C M)
component  home  provides
consumes  import  setRaises
emits  local  supports
finder  multiple  typeId
getRaises  primaryKey  typePrefix
Fig. 27.4IDL keywords to support the C ORBA C omponent Model.

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
• Component Interface Definition Language (CIDL)
is a superset of Persistent State Definition
Language.
– defines
• components in a way that enables automatic generation of
component’s persistence code.
• component implementation
• state management
– compiled with a CIDL compiler
• Developers organize components as an assembly
with a descriptor.
– describes how components are deployed
– extension of Open Software Description (OSD) Format

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
• A Container class creates a containment hierarchy
grouping components and other containers
together.
• Container programming model is a runtime
environment in which component implementations
use their enclosing containers to access various
services the container provides.

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
• Four areas make up CCM container
programming model:
1. External types
• interfaces seen by client wanting to communicate with
component
2. Container types
• API component uses to communicate with runtime
container
3. Container Implementation types
• different containers have different relationships with
surrounding system. Three types: stateless,
conversational, and durable. Each type defines its
system support
4. Component Category
• where a component fits in overall framework

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
• Using a container’s internal interfaces, a
component has full access to services a container
supports
– Container defines APIs for:
• component security
• persistence
• transactions
• events
• lifecycle
– Component implements call-back interfaces to allow
container-to-component communication.

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
• Components can be either
– transient, or
• can only be created by factories
• do not have primary keys
– persistent
• can be created by factories and located by finders
• have primary keys
• support two forms of persistence
– container managed
– component managed

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
C omponent Type Desc rip tion
Service  • Does not maintain state information (completely stateless)
• Does not have a unique id (primary key)
• Implements needed behavior
(e.g., calculateInterest,
addItemToShoppingCart, etc.)
• Can use transactions, is not included in the current
transaction

Session  • Maintains internal-state information


• Has a unique id that is usable only by its container
• Implements needed behavior
• Can use transactions, but is not included in the current transaction
• Maps to Session EJBs

Entity  • Container- or component-managed persistent state


• Has a unique id (primary key)
• Implements needed behavior that is optionally transactional
• Maps to Entity EJBs

Process  • Container-managed or component-managed persistent state that is inaccessible to


clients
• Container-managed or component-managed persistence of the component’s
primary key (identity) with visibility of the primary key through user-defined
methods
• Implements needed behavior and the behavior is optionally transactional

Fig. 27.5C O RBA c omponent types and d esc riptions.

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
• Activation and passivation are actions around
invocation boundaries of an object operation.
– activation lifecycle
1. request arrives to ORB to invoke operation on object
2. ORB sends request to POA
3. POA sends request to container managing component
4. container activates object
– passivation policies defined by component’s deployment
information

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
• In distributed systems, clients don’t create remote
objects. Clients discover remote objects.
– discovery through file containing object’s IOR
– discovery through Naming Service
• Factories (ComponentHome instances) of
remote systems create objects for their
corresponding systems.
– component definition must define component factory
– if component persistent, must define find method using
component’s primary key

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
• CORBAcomponents use subset of CORBAservices for
Component Implementation Framework.
– Security Service
• every component may have own security requirement
– defined in component’s deployment descriptor
• container must keep track of active policies and apply them
– Object Transaction Service (lite version)
• container can control transaction boundaries
• component can control transaction boundaries
– Persistent State Service
• container-managed persistence, PSS transparent to component
– not ideal for all situations
• component-managed persistence, should still use PSS to save state

 2002 Prentice Hall. All rights reserved.


27.5 EJBs and CORBAcomponents
(cont.)
– Notification Service
• accessed indirectly
• container mediates use of event service by component
• container does not preclude direct use of Notification Service
– component developers are encouraged to define events in
IDL as way of keeping component’s functional
description in one location
• keywords:
– publishes
• any number of consumers can subscribe to an event
• methods declared with publishes expected to be part
of shared interface of component
– emits
• only one consumer can subscribe to an event
• expected to be private channel used internally by
system
 2002 Prentice Hall. All rights reserved.
1 // Our Customer can send two events: Outline
2 // creditEvent if the customer's credit limit has been exceeded
3 // and internalStateEvent if the some data in the customer
4 // has not been updated properly
5 component Customer { Fig. 27.6
6 publishes PropertyEvent creditEvent; Customer
7 emits InvariantEvent internalStateEvent; component IDL
8 };
definition
demonstrating
keywords
allows any number of subscribers to an event publishes and
emits for issuing
allows one subscriber to an event events.

Line 6

Line 7

 2002 Prentice Hall.


All rights reserved.
27.5 EJBs and CORBAcomponents
(cont.)
• CCM and EJB models are similar.
• CCM specification defines two component levels
– basic
• mirrors EJB model almost exactly
• single threaded
• uses security, transaction and persistence services only
• exposes only single interface
– extended
• can expose multiple interfaces
• advanced store types allows components to be properly
persisted
• supports use of Event Services
• Sun and OMG worked closely to ensure EJB
model is CCM architecture subset.
 2002 Prentice Hall. All rights reserved.
27.6 CORBA vs. RMI

• CORBA is comprehensive view of distributed


systems architecture.
• RMI describes only communication proxies and
protocols between client object and server object.

 2002 Prentice Hall. All rights reserved.


27.6.1 When to Use RMI

• RMI suitable for smaller distributed applications


in which scalability, architecture, heterogeneity,
and extensibility are not major concerns.
• Mapping of RMI and RMI capabilities to OMA
encompasses only Applications Objects and the
ORB.
• RMI does not define Quality of Service or
asynchronous invocations.
• RMI does not offer POA or range of control
offered by POA.
• RMI has dynamic class loading. CORBA places
implementation burden on clients.
 2002 Prentice Hall. All rights reserved.
27.6.1 When to Use RMI (cont.)

• RMI allows objects to participate in distributed


systems consistently and predictably.
• RMI is a natural choice for distributed systems
built in Java.
• A pure Java-distributed system needs to be
considered from an architectural perspective
where distributed issues can be discovered and
resolved before the implementation issues are
decided.

 2002 Prentice Hall. All rights reserved.


27.6.2 When to Use CORBA

• CORBA defines and provides implementations to


many common requirements for most complex
distributed systems:
– architecture
– Quality of Service (QoS)
– Scalability
– Heterogeneity
– Extensibility

 2002 Prentice Hall. All rights reserved.


27.6.3 RMI-IIOP

• SUN and IBM implemented RMI-over-IIOP (RMI-IIOP)


to replace RMI’s underlying communication protocol
(Java Remote Method Protocol or JRMP).
• Inprise, Netscape, Oracle, Sun and IBM specified reverse
mapping of Java-to IDL.
– Mapping limitations:
• Constants can be of primitive types or of class
java.lang.String only
• IDL normally does not support overloading of method names.
• A class cannot inherit a method with same signature from two
different interfaces.
• Interfaces and value types must be public.
• Compiler considers packages and interface names are not case-
sensitive.

 2002 Prentice Hall. All rights reserved.


27.6.3 RMI-IIOP (cont.)

– runtime limitations:
• sending a tree graph from ORB to ORB may be problematic if
multiple nodes point to one object
• CORBA does not define distributed garbage collection
• Casting stubs may not work properly, so using the static
method narrow of class
java.rmi.PortableRemoteObject is encouraged.
• RMI downloads the stubs needed by client, CORBA does not.

 2002 Prentice Hall. All rights reserved.


27.6.3 RMI-IIOP (cont.)

– steps involved in writing distributed application using RMI-


IIOP:
• use javax.rmi.PortableRemoteObject instead of
using java.rmi.UnicastRemoteObject
• use JNDI (Java Naming and Directory Interface) instead of
RMI Registry
• do not downcast remote objects to subclass types; use method
narrow of class PortableRemoteObject to cast
distributed objects as subclass types

 2002 Prentice Hall. All rights reserved.


27.7 RMIMessenger Case Study
Ported to RMI-IIOP
• Porting RMI messenger example (Chapter 13) to
RMI-IIOP is easier than porting application to
CORBA.
– remote interfaces remain same
– support classes remain same
– new implementations for
• ChatServer remote interface (ChatServerImpl),
• ChatServerAdministrator
• MessageManager interface
(RMIIIOPMessageManager)
• DeitelMessenger

 2002 Prentice Hall. All rights reserved.


27.7.1 ChatServer RMI-IIOP
Implementation
• ChatServerImpl
– implements ChatServer remote interface
• subclass of class javax.rmi.PortableRemoteObject
– does not implement method register
– handles registration with name services

 2002 Prentice Hall. All rights reserved.


1 // ChatServerImpl.java Outline
2 // ChatServerImpl implements the ChatServer and StoppableChatServer
3 // remote interfaces using RMI over IIOP.
4 package com.deitel.messenger.rmi_iiop.server;
5 Fig. 27.7
6 // Java core packages ChatServerImpl
7 import java.io.*; implements the
8 import java.util.*;
9 import java.net.MalformedURLException; Deitel
10 import java.rmi.*; messenger
11 ChatServer using
12 // Java extension packages
13 import javax.rmi.*; RMI-IIOP.
14
15 // Deitel packages Line 20
16 import com.deitel.messenger.rmi.ChatMessage;
17 import com.deitel.messenger.rmi.client.ChatClient;
18 import com.deitel.messenger.rmi.server.*; Line 21
19
20 public class ChatServerImpl extends PortableRemoteObject
21 implements ChatServer, StoppableChatServer {
22 subclass of javax.rmi.PortableRemoteObject,
23 // Set of ChatClient references
24
which is
private Set clients = new HashSet();
base class for RMI-IIOP remote objects
25
26
interfaces remain unchanged for implementation
// construct new ChatServerImpl
27 public ChatServerImpl() throws RemoteException
28 {
29 super();
30 }
31

 2002 Prentice Hall.


All rights reserved.
32 // register new ChatClient with ChatServer Outline
33 public void registerClient( ChatClient client )
34 throws RemoteException
35 {
36 // add client to Set of registered clients Fig. 27.7
37 synchronized( clients ) { ChatServerImpl
38 clients.add( client ); implements the
39 }
40 Deitel
41 System.out.println( "Registered Client: " + client ); messenger
42 ChatServer using
43 } // end method registerClient
44 RMI-IIOP.
45 // unregister client with ChatServer
46 public void unregisterClient( ChatClient client )
47 throws RemoteException
48 {
49 // remove client from Set of registered clients
50 synchronized( clients ) {
51 clients.remove( client );
52 }
53
54 System.out.println( "Unregistered Client: " + client );
55
56 } // end method unregisterClient
57
58 // post new message to ChatServer
59 public void postMessage( ChatMessage message )
60 throws RemoteException
61 {
62 Iterator iterator = null;
63
64 // get Iterator for Set of registered clients
65 synchronized( clients ) {
66 iterator = new HashSet( clients ).iterator();
 2002 Prentice Hall.
All rights reserved.
67 } Outline
68
69 // send message to every ChatClient
70 while ( iterator.hasNext() ) {
71 ChatClient client = ( ChatClient ) iterator.next(); Fig. 27.7
72 client.deliverMessage( message ); ChatServerImpl
73 } implements the
74
75 } // end method postMessage Deitel
76 messenger
77 // notify each client that server is shutting down and ChatServer using
78 // terminate server application
79 public void stopServer() throws RemoteException RMI-IIOP.
80 {
81 System.out.println( "Terminating server ..." );
82
83 Iterator iterator = null;
84
85 // get Iterator for Set of registered clients
86 synchronized( clients ) {
87 iterator = new HashSet( clients ).iterator();
88 }
89
90 // send serverStopping message to every ChatClient
91 while ( iterator.hasNext() ) {
92 ChatClient client = ( ChatClient ) iterator.next();
93 client.serverStopping();
94 System.err.println( "Disconnected: " + client );
95 }
96
97 // create Thread to terminate application after
98 // stopServer method returns to caller
99 Thread terminator = new Thread(
100 new Runnable() {
101
 2002 Prentice Hall.
All rights reserved.
102 // sleep for 5 seconds, print message and terminate Outline
103 public void run()
104 {
105 // sleep
106 try { Fig. 27.7
107 Thread.sleep( 5000 ); ChatServerImpl
108 } implements the
109
110 // ignore InterruptedExceptions Deitel
111 catch ( InterruptedException exception ) {} messenger
112 ChatServer using
113 System.err.println( "Server terminated" );
114 System.exit( 0 ); RMI-IIOP.
115 }
116 }
117 );
118
119 terminator.start(); // start termination thread
120
121 } // end method stopServer
122 }

 2002 Prentice Hall.


All rights reserved.
27.7.1 ChatServer RMI-IIOP
Implementation (cont.)
• ChatServerAdministrator
– utility program for starting and stopping RMI-IIOP
ChatServer implementation

 2002 Prentice Hall. All rights reserved.


1 // ChatServerAdministrator.java Outline
2 // ChatServerAdministrator is a utility for starting and stopping
3 // the RMI-IIOP ChatServer implementation.
4 package com.deitel.messenger.rmi_iiop.server;
5 Fig. 27.8
6 // Java core packages ChatServerAdmini
7 import java.rmi.*; strator
8 import java.rmi.activation.*;
9 import java.util.*; application for
10 starting and
11 // Java extension packages stopping RMI-
12 import javax.rmi.*;
13 import javax.naming.*; IIOP ChatServer.
14
15 // Deitel packages Line 27
16 import com.deitel.messenger.rmi.server.StoppableChatServer;
17
18 public class ChatServerAdministrator { Lines 30 and 35
19
20 // set up ChatServer object
21 private static void startServer()
22 { creates instance of ChatServerImpl
23 // register ChatServer in Naming Service
24 try {
25
26 // create ChatServerImpl object
27 register ChatServer
ChatServerImpl chatServerImpl = new ChatServerImpl(); with naming service
28
29 // create InitialContext for naming service
30 Context namingContext = new InitialContext();
31
32 System.err.println( "Binding server to naming service.." );
33
34 // bind ChatServerImpl object to naming service
35 namingContext.rebind( "ChatServer", chatServerImpl );
 2002 Prentice Hall.
All rights reserved.
36 Outline
37 System.out.println( "Server bound to naming service" );
38
39 } // end try
40 Fig. 27.8
41 // handle exception registering ChatServer ChatServerAdmini
42 catch ( NamingException namingException ) { strator
43 namingException.printStackTrace();
44 System.exit( 1 ); application for
45 } starting and
46 stopping RMI-
47 // handle exception creating ChatServer
48 catch ( RemoteException remoteException ) { IIOP ChatServer.
49 remoteException.printStackTrace();
50 System.exit( 1 ); Line 62
51 }
52
53 } // end method startServer Lines 65-66
54
55 // terminate server
56 private static void terminateServer()
57 {
58 // look up and terminate ChatServer create InitialContext
59 try {
60
61 // create naming Context for looking up server
62 Context namingContext = new InitialContext(); obtain remote reference
63
64 // find ChatServer remote object
65 Object remoteObject =
66 namingContext.lookup( "ChatServer" );
67

 2002 Prentice Hall.


All rights reserved.
68 // narrow remoteObject to StoppableChatServer Outline
69 StoppableChatServer chatServer =
70 ( StoppableChatServer ) PortableRemoteObject.narrow(
71 remoteObject, StoppableChatServer.class );
72 Fig. 27.8
73 // stop ChatServer ChatServerAdmini
74 chatServer.stopServer(); strator
75
76 // remove ChatServer from Naming Service application for
77 namingContext.unbind( "ChatServer" ); starting
remove from Naming Service and
78 stopping RMI-
79 } // end try
80
use method narrow to cast ChatServer.
IIOP reference to
81 // handle exception looking up ChatServer StoppableChatServer type
82 catch ( NamingException namingException ) { Lines 69-71
83 namingException.printStackTrace();
84 }
85 Line 77
86 // handle exception communicating with ChatServer
87 catch ( RemoteException remoteException ) {
88 remoteException.printStackTrace();
89 }
90
91 } // end method terminateServer
92
93 // launch ChatServerAdministrator application
94 public static void main( String args[] )
95 {
96 // check command-line arguments and start or stop server
97 if ( args[ 0 ].equals( "start" ) )
98 startServer();
99
100 else if ( args[ 0 ].equals( "stop" ) )
101 terminateServer();
102
 2002 Prentice Hall.
All rights reserved.
103 // print usage information Outline
104 else
105 System.err.println(
106 "Usage: java ChatServerAdministrator start | stop" );
107 Fig. 27.8
108 } // end method main ChatServerAdmini
109 } strator
application for
Binding server to naming service...
Server bound to naming service starting and
Registered Client: stopping RMI-
IOR:0000000000000040524d493a636f6d2e64656974656c2e6d657373656e6765722e726 IIOP ChatServer.
d692e636c69656e742e43686174436c69656e743a30303030303030303030303030303030
00000000010000000000000054000101000000000d3139322e3136382e312e3435000005e
000000018afabcaff00000002243bba8f0000000800000001000000000000000100000001
000000140000000000010020000000000001010000000000
Registered Client:
IOR:0000000000000040524d493a636f6d2e64656974656c2e6d657373656e6765722e726
d692e636c69656e742e43686174436c69656e743a30303030303030303030303030303030
00000000010000000000000054000101000000000d3139322e3136382e312e3435000005e
500000018afabcaff00000002243bbbed0000000800000001000000000000000100000001
000000140000000000010020000000000001010000000000
Registered Client:
IOR:0000000000000040524d493a636f6d2e64656974656c2e6d657373656e6765722e726
d692e636c69656e742e43686174436c69656e743a30303030303030303030303030303030
00000000010000000000000054000101000000000d3139322e3136382e312e3435000005e
a00000018afabcaff00000002243bbd5c0000000800000001000000000000000100000001
000000140000000000010020000000000001010000000000

 2002 Prentice Hall.


All rights reserved.
Unregistered Client: Outline
IOR:0000000000000040524d493a636f6d2e64656974656c2e6d657373656e6765722e726
d692e636c69656e742e43686174436c69656e743a30303030303030303030303030303030
00000000010000000000000054000101000000000d3139322e3136382e312e3435000005e
000000018afabcaff00000002243bba8f0000000800000001000000000000000100000001 Fig. 27.8
000000140000000000010020000000000001010000000000 ChatServerAdmini
Terminating server ... strator
Disconnected:
IOR:0000000000000040524d493a636f6d2e64656974656c2e6d657373656e6765722e726 application for
d692e636c69656e742e43686174436c69656e743a30303030303030303030303030303030 starting and
00000000010000000000000054000101000000000d3139322e3136382e312 stopping RMI-
e3435000005e500000018afabcaff00000002243bbbed0000000800000001000000000000
000100000001000000140000000000010020000000000001010000000000 IIOP ChatServer.
Disconnected:
IOR:0000000000000040524d493a636f6d2e64656974656c2e6d657373656e6765722e726
d692e636c69656e742e43686174436c69656e743a30303030303030303030303030303030
00000000010000000000000054000101000000000d3139322e3136382e312e3435000005e
a00000018afabcaff00000002243bbd5c0000000800000001000000000000000100000001
000000140000000000010020000000000001010000000000
Server terminated

 2002 Prentice Hall.


All rights reserved.
27.7.2 ChatClient RMI-IIOP
Implementation
• implement ChatClient RMI-IIOP messenger:
– provide RMI-IIOP implementation of interface
MessageManager
– create new DeitelMessenger application for launching
ClientGUI with new MessageManager implementation

 2002 Prentice Hall. All rights reserved.


1 // RMIIIOPMessageManager.java Outline
2 // RMIIIOPM22essageManager implements the ChatClient remote
3 // interface and manages incoming and outgoing chat messages
4 // using RMI over IIOP.
5 package com.deitel.messenger.rmi_iiop.client; Fig. 27.9
6 RMIIIOPMessage
7 // Java core packages Manager
8 import java.awt.*;
9 import java.awt.event.*; implements the
10 import java.rmi.*; ChatClient and
11 import java.rmi.server.*; MessageManager
12 import java.util.*;
13 interfaces using
14 // Java extension packages RMI-IIOP.
15 import javax.rmi.*;
16 import javax.naming.*;
17 Line 24
extends PortableRemoteObject
18 // Deitel packages
19 import com.deitel.messenger.*;
20 import com.deitel.messenger.rmi.client.ChatClient;
21 import com.deitel.messenger.rmi.ChatMessage;
22 import com.deitel.messenger.rmi.server.ChatServer;
23
24 public class RMIIIOPMessageManager extends PortableRemoteObject
25 implements ChatClient, MessageManager {
26
27 // listeners for incoming messages and disconnect notifications
28 private MessageListener messageListener;
29 private DisconnectListener disconnectListener;
30
31 // ChatServer for sending and receiving messages
32 private ChatServer chatServer;
33
34 // RMIMessageManager constructor
35 public RMIIIOPMessageManager() throws RemoteException {}
 2002 Prentice Hall.
All rights reserved.
36 Outline
37 // connect to ChatServer
38 public void connect( MessageListener listener )
39 throws Exception
40 { Fig. 27.9
41 // create naming Context for looking up server RMIIIOPMessage
42 Context namingContext = new InitialContext(); Manager
43
44 // find ChatServer remote object implements the
45 Object remoteObject = obtain remote reference to
ChatClient and
46 namingContext.lookup( "ChatServer" ); RMI-IIOP ChatServer MessageManager
47
48 chatServer = ( ChatServer ) PortableRemoteObject.narrow( interfaces using
49 remoteObject, ChatServer.class ); RMI-IIOP.
50
51 // register client with ChatServer to receive messages
52 chatServer.registerClient( this ); Lines 38-57
53
54 // set listener for incoming messages
55 messageListener = listener;
56
57 } // end method connect
58
59 // disconnect from ChatServer
60 public void disconnect( MessageListener listener )
61 throws Exception
62 {
63 if ( chatServer == null )
64 return;
65
66 chatServer.unregisterClient( this );
67 messageListener = null;
68
69 // notify listener of disconnect
70 fireServerDisconnected( "" );
 2002 Prentice Hall.
All rights reserved.
71 Outline
72 } // end method disconnect
73
74 // send ChatMessage to ChatServer
75 public void sendMessage( String fromUser, String message ) Fig. 27.9
76 throws Exception RMIIIOPMessage
77 { Manager
78 if ( chatServer == null )
79 return; implements the
80 ChatClient and
81 // create ChatMessage with message text and user name MessageManager
82 ChatMessage chatMessage =
83 new ChatMessage( fromUser, message ); interfaces using
84 RMI-IIOP.
85 // post message to ChatServer
86 chatServer.postMessage( chatMessage );
87
88 } // end method sendMessage
89
90 // process delivery of ChatMessage from ChatServer
91 public void deliverMessage( ChatMessage message )
92 throws RemoteException
93 {
94 if ( messageListener != null )
95 messageListener.messageReceived( message.getSender(),
96 message.getMessage() );
97 }
98
99 // process server shutting down notification
100 public void serverStopping() throws RemoteException
101 {
102 chatServer = null;
103 fireServerDisconnected( "Server shut down." );
104 }
105
 2002 Prentice Hall.
All rights reserved.
106 // register listener for disconnect notifications Outline
107 public void setDisconnectListener(
108 DisconnectListener listener )
109 {
110 disconnectListener = listener; Fig. 27.9
111 } RMIIIOPMessage
112 Manager
113 // send disconnect notification
114 private void fireServerDisconnected( String message ) implements the
115 { ChatClient and
116 if ( disconnectListener != null ) MessageManager
117 disconnectListener.serverDisconnected( message );
118 } interfaces using
119 } RMI-IIOP.

 2002 Prentice Hall.


All rights reserved.
1 // DeitelMessenger.java Outline
2 // DeitelMessenger uses ClientGUI and RMIIIOPMessageManager to
3 // implement an RMI over IIOP chat client.
4 package com.deitel.messenger.rmi_iiop.client;
5 Fig. 27.10
6 // Java core packages DeitelMessenger
7 import java.rmi.RMISecurityManager; creates a
8
ClientGUI and
9 // Deitel packages Create instance of class
10 import com.deitel.messenger.*; RMIIIOPMessageMa
RMIIIOPMessageManager
11 nager to launch
12 public class DeitelMessenger {
13 the RMI-IIOP
14 // launch DeitelMessenger application messenger
15 public static void main( String args[] ) throws Exception client.
16 {
17 // create RMIIIOPMessageManager for communicating with server
18 MessageManager messageManager = new RMIIIOPMessageManager(); Line 18
19
20 // configure and display chat window
21 ClientGUI clientGUI = new ClientGUI( messageManager ); Line 21
22 clientGUI.setSize( 300, 400 );
23 clientGUI.setResizable( false );
24 clientGUI.setVisible( true );
25 }
26 }

create GUI instance using


RMIIIOPMessageManager instance

 2002 Prentice Hall.


All rights reserved.
27.7.3 Compiling and Running the
ChatServer and ChatClient
• Using java compiler compile
– ChatServerImpl,
– ChatServerAdministrator,
– RMIIIOPMessageManager, and
– DeitelMessenger.
• Using rmic tool and –iiop command-line
option generate RMI-IIOP stub classes
– ChatServerImpl
• rmic –iiop
com.deitel.messenger.rmi_iiop.server.ChatServerImpl
– RMIIIOPMessageManager
• rmic –iiop
com.deitel.messenger.rmi_iiop.server.RMIIOPMessageManager

 2002 Prentice Hall. All rights reserved.


27.7.3 Compiling and Running the
ChatServer and ChatClient (cont.)
• Start tnameserv
– tnameserv –ORBInitialPort 1050
• Start ChatServerAdministrator
– java –Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
–Djava.naming.provider.url=iiop://localhost:1050
com.deitel.messenger.rmi_iiop.server.ChatServerAdministrator start

• Start ChatServer
– java –Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
–Djava.naming.provider.url=iiop://localhost:1050
com.deitel.messenger.rmi_iiop.client.DeitelMessenger

 2002 Prentice Hall. All rights reserved.


27.8 Future Directions

• OMA guiding document for CORBA systems


– falls short in average-size systems
• CORBA Component Model
– abstracts system issues through programming constructs:
• containers
• subsystems
• CORBA working on architectural process
– Model Driven Architecture™ (MDA)
• Expansion of OMG’s architecture
– maintains compatibility with previous embodiments
– gives new vitality to OMG

 2002 Prentice Hall. All rights reserved.

Potrebbero piacerti anche