|
|
|
Distributed Objects |
|
CORBA: Introduction and Overview |
|
CORBA Clients |
|
CORBA Servers |
|
CORBA Development Issues |
|
|
|
JavaIDL: http://java.sun.com/products/jdk/idl |
|
|
|
|
Traditional enterprise apps are self-contained,
monolithic apps |
|
Limited access to another’s procedures and data |
|
Apply OO techniques for networked apps |
|
multi-tiered architecture (separation of
concerns) |
|
1st, 2nd, 3rd generation systems |
|
|
|
|
Local vs. Remote objects |
|
|
|
|
|
|
|
|
|
|
|
An enterprise app is a collection of
co-operating objects located on different machines |
|
|
|
|
Benefit from OO techniques |
|
Eliminates protocol design, which is error-prone |
|
Convenient resource sharing |
|
|
|
|
|
|
Design and Impl’n is more complex |
|
Multiple failure modes |
|
Security issues |
|
Use of multiple technologies |
|
Testing and debugging |
|
|
|
|
Many technologies available: |
|
Sockets (TCP, UDP) Not OO |
|
RPC (not OO) |
|
|
|
RMI |
|
CORBA |
|
|
|
|
OMG |
|
Current state of OMG/CORBA efforts |
|
Object Model |
|
Client Server model and issues |
|
|
|
|
|
Non-profit consortium of software vendors |
|
Formed in 1989 by 8 companies |
|
Has more than 800 members now |
|
http://www.omg.org |
|
Goals: |
|
Develop specs to provide a common framework for
distributed applications development |
|
Promote a heterogeneous computing environment |
|
|
|
|
Stands for: Common Object Request Broker
Architecture |
|
A spec for creating distributed objects |
|
CORBA is NOT a programming language |
|
Its architecture is based on the object model |
|
Promotes design of applications as a set of
cooperating objects |
|
OMG Object Model: object is defined as what the
client could see. |
|
|
|
|
|
clients are isolated from servers by interface |
|
CORBA objects vs. typical objects: |
|
CORBA objects run on any platform |
|
CORBA objects can be located anywhere on the
network |
|
CORBA objects can be written in any language
that has IDL mapping |
|
|
|
|
|
|
The software that implements the CORBA
specification |
|
Object bus that provides object location
transparency |
|
Responsible for mechanisms to: |
|
Find the object implementation of the request |
|
Prepare object implem’n to receive the request |
|
Communicate the data making up the request |
|
|
|
|
Client and object implem’n are isolated from the
ORB by an IDL interface |
|
all requests (local or remote) are managed by
the ORB |
|
|
|
|
|
|
|
|
Basic services that every object needs |
|
System level services with well-defined IDL
interfaces |
|
They enhance functionality supported by ORBs |
|
|
|
|
|
|
Naming Service: find an object and bind to it |
|
Event service: supports notification of events
to interested objects |
|
Persistent object service: provides a common set
of interfaces for managing the state of objects |
|
Trader service: an alternative location facility
to the naming service |
|
|
|
|
Stands for: Interface Definition Language |
|
A CORBA object is specified with interface |
|
interface: contract between client and server |
|
specified in a special declarative language |
|
Lexical rules are same as C++ with new keywords |
|
IDL mapping to programming languages (e.g. C++,
Java, etc) are provided in specs |
|
|
|
|
|
IDL interface provides a description of services
available to clients |
|
IDL interface describes an object with: |
|
Attributes |
|
Methods with their signatures |
|
Exceptions |
|
Inheritance information |
|
Type and constant definitions |
|
|
|
|
any attribute |
|
char const |
|
double enum |
|
Fixed float |
|
interface long |
|
octet oneway |
|
readonly sequence |
|
struct switch |
|
unsigned union |
|
wstring |
|
boolean
case |
|
context default |
|
exception FALSE |
|
in inout |
|
module object |
|
out raises |
|
short string |
|
TRUE typedef |
|
void wchar |
|
|
|
|
module <identifier> { |
|
<type declarations>; |
|
<constant declarations>; |
|
<exception declarations; |
|
|
|
<interface definition>; |
|
<interface definition>; |
|
}; |
|
|
|
|
At the highest level, IDL definitions are
packaged into module. |
|
A module is analogous to a package in Java |
|
Example: |
|
module Bank { |
|
//body |
|
}; |
|
|
|
|
An IDL interface is the definition of an object |
|
IDL interfaces are analogous to Java interfaces |
|
An interface declares the operations that the
CORBA object supports and its attributes |
|
interface Account { |
|
//attributes |
|
//
operations |
|
}; |
|
|
|
|
An interface may inherit from multiple
interfaces |
|
It inherits all attributes and operations of its
super-interfaces |
|
interface JointSavingsAccount: JointAccount,
SavingsAccount { |
|
//
attributes |
|
//
operations |
|
}; |
|
|
|
|
|
|
|
|
They describe the variables (properties) of an
interface |
|
An attribute can be readonly or read-write |
|
interface Account { |
|
attribute string name; |
|
readonly attribute string sin; |
|
readonly attribute long long accountNumber; |
|
}; |
|
|
|
|
|
They describe the methods of an interface |
|
They have a return type and parameters |
|
Parameters are flagged as: |
|
in: parameter is passed from client to server |
|
out: parameter is passed from server to client |
|
inout: parameter is passed in both directions |
|
void withdraw(in unsigned long amount); |
|
void add(in long a, in long b, out long sum); |
|
|
|
|
IDL supports user-defined exceptions |
|
exception InsufficientFunds { |
|
long
currentBalance; |
|
}; |
|
void withdraw(in unsigned long amount) |
|
raises (InsufficientFunds); |
|
}; |
|
|
|
|
|
IDL Supports a rich variety of data types |
|
|
|
Primitive: |
|
float, double, long, short (signed, unsigned),
char, |
|
long long, boolean, octet |
|
Complex
(discussed later): |
|
arrays, sequences, structures |
|
|
|
|
|
|
IDL Java |
|
boolean boolean |
|
octet byte |
|
char char |
|
string String |
|
short short |
|
long int |
|
long lon long |
|
float float |
|
IDL Java |
|
double double |
|
fixed BigDecimal |
|
|
|
|
|
Mediate between CORBA objects and programming
language implementations |
|
Provide a number of services: |
|
Creation of CORBA objects and their references |
|
Dispatching requests to the appropriate servant
that provides implementation for the target object |
|
Activation and deactivation of CORBA objects |
|
|
|
|
|
|
CORBA 2.0 defines the Basic Object Adapter (BOA) |
|
ORB vendors discovered that BOA is ambiguous and
missing features so they developed proprietary extensions |
|
This resulted in poor portability between ORBs |
|
The new standard is: Portable Object Adapter
(POA) |
|
Refer to book (pp. 159) |
|
|
|
|
|
The steps involved: |
|
Define an interface |
|
Map IDL to Java (idlj compiler) |
|
Implement the interface |
|
Write a Server |
|
Write a Client |
|
Run the application |
|
Example: a step-by-step Hello example |
|
|
|
|
Hello.idl |
|
|
|
module HelloApp { |
|
interface Hello { |
|
string sayHello(); |
|
}; |
|
}; |
|
|
|
|
|
Use the idlj compiler (J2SE 1.3) |
|
idlj –fall Hello.idl |
|
This will generate: |
|
_HelloImplBase.java (server skeleton) |
|
HelloStub.java (client stub, or proxy) |
|
Hello.java |
|
HelloHelper.java, HelloHolder.java |
|
HelloOperations.java |
|
|
|
|
Implement the servant: |
|
import HelloApp.*; |
|
class HelloServant extends _HelloImplBase { |
|
public
String sayHello() { |
|
return “\nHello There\n”; |
|
} |
|
} |
|
|
|
|
Import statements: |
|
import org.omg.CosNaming.*; |
|
import org.omg.CosNaming.NamingCotextPackage.*; |
|
import org.omg.CORBA.*; |
|
|
|
class HelloServer { |
|
public static void main(String argv[]) { |
|
try { |
|
|
|
|
Create and initialize the ORB: |
|
ORB
orb = ORB.init(argv, null); |
|
|
|
Create the servant and register it with ORB |
|
HelloServant helloRef = new HelloServant(); |
|
orb.connect(helloRef); |
|
|
|
|
|
|
Get the root NamingConext: |
|
|
|
org.omg.CORBA.Object objRef =
org.resolve_initial_references(“NameService”); |
|
NamingContext ncRef =
NamingContectHelper.narrow(objRef); |
|
|
|
|
|
|
|
|
Bind the object reference in naming |
|
|
|
NameComponent
nc = new NameComponent("Hello", " "); |
|
NameComponent path[] = {nc}; |
|
ncRef.rebind(path, helloRef); |
|
|
|
|
|
|
Wait for invocations from clients: |
|
|
|
java.lang.Object sync = new java.lang.Object(); |
|
synchronized(sync) { |
|
sync.wait(); |
|
} |
|
|
|
|
|
|
|
|
Catch the exceptions |
|
}
catch(Exception e) { |
|
System.err.println("ERROR:
" + e); |
|
e.printStackTrace(System.out); |
|
} //
end catch |
|
} //
end main() |
|
} // end class |
|
|
|
|
|
|
Import statements: |
|
import HelloApp.*; |
|
import org.omg.CosNaming.*; |
|
import org.omg.CORBA.*; |
|
class HelloClient { |
|
public static void main(String argv[]) { |
|
try { |
|
|
|
|
|
Initialize ORB |
|
Export object: |
|
orb.connect() |
|
Server is ready: |
|
Do a wait() |
|
Initialize ORB and BOA |
|
Export object: |
|
boa.obj_is_ready() |
|
Server is ready: |
|
boa.impl_is_read() |
|
|
|
|
Create and initialize the ORB: |
|
ORB orb = ORB.init(argv, null); |
|
Create the root naming context: |
|
org.omg.CORBA.Object objRef = |
|
orb.resolve_initial_references("NameService"); |
|
NamingContext ncRef = |
|
NamingContextHelper.narrow(objRef); |
|
|
|
|
|
|
Resolve the object reference in naming: |
|
|
|
NameComponent nc = new NameComponent("Hello",
" "); |
|
NameComponent path[] = {nc}; |
|
Hello helloRef = HelloHelper.narrow(ncRef.resolve(path)); |
|
|
|
|
|
|
Call the object: |
|
String Hello = helloRef.sayHello(); |
|
System.out.println(Hello); |
|
Catch exception: |
|
} catch(Exception e) { |
|
System.out.println("ERROR
: " + e); |
|
e.printStackTrace(System.out); |
|
} } }
// end catch, main, class |
|
|
|
|
|
|
|
|
|
|
Run the naming service: |
|
prompt> tnameserver |
|
Run the server |
|
prompt> java HelloServer |
|
Run the client |
|
prompt> java HelloClient |
|
Hello There |
|
prompt> |
|
|
|
|
Using the idlj compiler |
|
Initializing the ORB |
|
Helper classes |
|
Holder classes |
|
Exceptions |
|
The naming service |
|
|
|
|
|
|
|
|
|
Syntax: idlj [options] idl-file |
|
Examples: |
|
Idlj myfile.idl (generates client-side bindings) |
|
Equivalent to: idlj –fclient myfile.idl |
|
To generate client and server side bindings: |
|
Idlj –fclient –fserver myfile.idl OR |
|
Idlj –fall myfile.idl |
|
idlj supports other options….not important to us
here |
|
|
|
|
|
|
|
Before invoking a CORBA object, you must first
create an ORB object and initialize it |
|
public
static void main(String argv[]) { |
|
try {
ORB orb = ORB.init(argv, null); // .. } |
|
} |
|
Arguments to init(): |
|
ORB init(String[] argv, Properties props) |
|
argv: a list of command-line arguments to the
app. |
|
props: programmatically specify these options |
|
|
|
|
|
Command-line arguments (options): |
|
-ORBClass: that class that provides your ORB
implementation (JavaSoft’s ORB) |
|
-ORBSingletonClass:the class that provides your
ORB singleton implementation (JavaSoft’s ORB) |
|
-ORBInitialHost:the host where the naming
service is running (default value: localhost) |
|
-ORBInitialPort:the port where the naming
service is running. Default value: 900 |
|
|
|
|
|
Properties: |
|
|
|
org.omg.CORBAClass |
|
org.omg.CORBA.ORBSingletonClass |
|
org.omg.CORBA.ORBInitialHost |
|
org.omg.CORBA.ORBInitialPort |
|
|
|
How to use these? |
|
|
|
|
|
|
Properties: alternative to command-line args |
|
Example: |
|
Properties props = new Properties(); |
|
props.put(“org.omg.CORBA.ORBInitialHost”,
initialHost); |
|
props.put(“org.omg.CORBA.ORBInitialPort”,
initialPort); |
|
String noArgs[] = null; |
|
ORB orb = orb.init(noargs, props); |
|
|
|
|
They provide some utility functions (narrow) |
|
For interface Hello in module HelloApp, a helper
class: HelloApp.HelloHelper is created |
|
Important method: |
|
Hello narow(org.omg.CORBA.Object object) |
|
The naming service returns an Object, you must
cast it to narrow it down….use narrow() |
|
|
|
|
Used to implement “out” and “inout” parameters
to CORBA operations. |
|
Why do we need them? |
|
void op(inout long x); // alter the value of
x |
|
But in Java: |
|
int x = 10; op(x);// op is not allowed to
change x |
|
However, “out” or “inout” mean that the actual
value of the parameter will be changed. |
|
|
|
|
Solution: use holder classes: |
|
For primitive data types: primitive holders |
|
int x = 10; |
|
IntHolder myx; |
|
myx.value = x; |
|
op(myx); |
|
x =
myx.value; |
|
BooleanHolder, CharHolder, StringHolder, etc |
|
|
|
|
|
|
|
|
For user-defined types: |
|
|
|
Employee employee = …; |
|
EmployeeHolder emp; |
|
emp.value = employee; |
|
op(emp); |
|
employee = emp.value; |
|
|
|
|
|
|
|
System exceptions |
|
|
|
org.omg.CORBA.SystemException |
|
|
|
User exceptions |
|
|
|
org.omg.CORBA.UserException |
|
|
|
|
Those implicit, unpredictable exceptions that
can arise as a result of a CORBA failure |
|
System exceptions are all implemented as a
subclass of org.omg.CORBA.SystemException |
|
A subclass of java.lang.RuntimeException |
|
Therefore, any SystemException may be implicitly
thrown by a CORBA operation without being declared in a throws clause |
|
|
|
|
Those, explicit, predictable exceptions that are
documented in IDL operation declarations. |
|
Raised by CORBA operations in response to
specific situations (e.g. InsufficientFund) |
|
Implemented as a subclass of
org.omg.CORBA.UserException |
|
A subclass of java.lang.Exception |
|
Therefore, they must be explicitly handled |
|
|
|
|
CORBA interfaces defined in IDL, RMI interfaces are defined in Java |
|
CORBA is language-independent, RMI is not |
|
CORBA objects are not garbage collected, RMI
objects are garbage collected automatically. |
|
RMI does not support “out” and “inout”
operations since local objects passed by copy, remote objects passed by
reference to stub |
|
RMI-IIOP |
|
|
|
|
|
|
|