Präsentationsquelle herunterladen

Download Report

Transcript Präsentationsquelle herunterladen

Remote Method Invocation with
Java-RMI
Automatically
generated
Skeleton
- Demarshalling
- Dispatch
Stub
- Marshalling
Network
ServerI
Server
Client
Contains only
functionality
What does the client see?
• A remote object (proxy, stub) can
– be casted to all interface the server implements,
– be accessed only via interface methods.
• On a remote invocation
– non-remote arguments are copied (using serialization),
– remote arguments are given as reference,
 different to local invocation
– java.rmi.RemoteException can always be thrown.
• Remote Objects always support the interface Remote.
(Tag interface)
How to build the server?
Class diagram:
Remote
RemoteObject
RemoteServer
Provided by
the JDK
UnicastRemoteObject Activatable
ServerI
ServerImpl
Provided by
the programer
- every method which is remotely invocable must be declared to
throw RemoteException.
- Skeletons/Stubs are created with the JDK tool rmic.
Coordination with a naming service
• The naming service (rmiregistry)
– is a remote Java object,
– manages relationships between Strings (i.e. names) and remote
Java objects (on the same host).
• remote Java objects register themselves with
java.rmi.Naming.bind(String name,Remote obj);
java.rmi.Naming.rebind(String name,Remote obj);
• the name has the form: “//host:port/identifier“
(default: host=localhost, port=1099)
• clients use the name to receive a stub:
Remote Naming.lookup(String name);
Examplary Server
Server interface:
interface ServerI extends Remote
{ public void doSomeService()
throws RemoteException;}
Server implementation:
class Server extends UnicastRemoteObject
implements ServerI
{ public Server() throws RemoteException
{ super();}
public void doSomeService()
throws RemoteException
{ System.out.println("Working hard..");}
....
Initialisation+Registration
...
public static void main(String args[])
{try { // create instance
Server myServer = new Server();
// bind it to the naming service
Naming.rebind(“//elfe:4711/HardServer",
myServer);
// done
} catch(Exception ex)
{ex.printStackTrace();
System.exit(5);
}
}
}
Remote Invocation of the Server
public class Client
{ static public void main(String args[])
{ try { // locate Server
Remote rs = Naming.lookup(“//elfe:4711/HardServer");
ServerI server = (ServerI) rs;
// use service
server.doSomeService();
// done
} catch(Exception ex)
{ ex.printStackTrace();
System.exit(5);
}
} }
Compilation, Configuration, Startup
Compile classes
jedi> javac Server.java ServerI.java
Client.java
Create Skeletons and Stubs
jedi> rmic Server
Start naming service on elfe
elfe> rmiregistry 4711 &
Start server on elfe
elfe> java Server &
Start client somewhere
jedi> java Client
Working hard..
on elfe
Installation of JacORB
• Source code with examples and documentation:
http://www.inf.fu-berlin.de/~brose/jacorb
• local installation in the Sun pool:
setenv JACO /import/public/opt/JacORB1_1
setenv PATH $JACO/bin:$PATH
setenv CLASSPATH
$JACO/lib/idl.jar:$JACO/lib/jacorb.jar:$CLASSPATH
cp $JACO/jacorb_properties.template
~/.jacorb_properties
edit ~/.jacorb_properties
(an install script is on the WWW)
• adapt the URL settings in the property file; at least this entry:
jacorb.NameServerURL=file:/....
Overview about CORBA
Server
Client
Servant
Impl.
IDL
Interface
Servant
Servant
Skeleton
Stub
POA
ORB
POA
Class Hierarchie for CORBA Servers for
the Interface Foo
Servant
<<interface>>
FooOperations
FooPOA
<<interface>>
Foo
Delegates to
FooImpl
Servants are no
CORBA objects
FooPOATie
FooDelegateImpl
Delegate allows use of inheritence:
new FooPOATie(new FooDelegateImpl()
The CORBA COS Naming Service
• A naming context
– stores relationships between names and Objects,
– is itself a CORBA object (allows hierarchical, potentially cyclic
name spaces).
• name = sequence<name_components>,
name_component=(string id, string kind)
• ORB provides bootstrapping with the root context NameServer
(ORB uses jacorb.NameServerURL; it points to an IOR)
• bind an object in a subcontext
NamingContext.bind(Name n, Object o);
• resolve an object Object
Object NamingContext.resolve(Name n);
• create a new sub context
NamingContext NamingContext.new_context();
NamingContext.bind_new_context(Name n);
• bug in JDK  use NamingContextExt !
Examplary Server now in CORBA
Server IDL interface:
interface Server
{ void doSomeService();};
Server implementation:
class ServerImpl extends ServerPOA
{
public void doSomeService()
{ System.out.println("Working hard..");}
// main method follows
Initialisation+Registration
static public void main(String args[])
{ try { // access CORBA, activate POA
ORB orb = org.omg.CORBA.ORB.init(args, null);
POA poa =
POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
poa.the_POAManager().activate(); // from now on requests are
handled !!!
// get name server
NamingContextExt nc =
NamingContextExtHelper.narrow(orb.resolve_initial_references("NameSer
vice"));
// generate a server and register it at the POA
org.omg.CORBA.Object cob = poa.servant_to_reference(new
ServerImpl());
// generate a name
NameComponent [] name = new NameComponent[1];
name[0] = new NameComponent( "HardServer", "some kind");
// bind server to name
Remote Invocation of the Server
class Client
{ static void main(String args[])
{ try{
// get ORB and naming service
ORB orb = org.omg.CORBA.ORB.init(args, null);
NamingContextExt nc =
NamingContextExtHelper.narrow(orb.resolve_initial_references("NameSer
vice"));
// generate the name
NameComponent [] name = new NameComponent[1];
name[0] = new NameComponent( "HardServer", "some kind");
// query naming service, cast the stub
org.omg.CORBA.Object cob = nc.resolve(name);
Server server = ServerHelper.narrow(cob); // use the generated
Helper class
// use service
server.doSomeService();
Compile the Example
• Generate skeleton,stubs, helper classes from the IDL
> idl server.idl
– Skeletons:
ServerPOA.java,ServerPOATie.java
– Stub: _ServerStub.java
– Helpers:
ServerHelper.java, ServerHolder.java
– Interfaces:
Server.java, ServerOperations.java
• compile the classes
> javac *.java
(take care of your CLASSPATH!)
Startup your Scenario
• Start the naming service
> ns NSIOR
NSIOR should be:
file(jacorb.NameServerURL)
E.g.: file:/home/tnfink/ns.ior  /home/tnfink/ns.ior
• start the server
jedi> jaco ServerImpl
Server is ready.
• Start the client
troll> jaco Client
Working hard.
(auf jedi)
Miscellaneous Methods
• Convert CORBA object references to Java Strings:
String ORB.object_to_string(org.omg.CORBA.Object obj);
org.omg.CORBA.Object ORB.string_to_object(String ior);
• test for existance of an CORBA object (i.e. stub)
boolean Object._non_existent();
• test if two CORBA objects are equal
boolean Object._is_equivalent(Object other);
a return of false does not guarantee inequality!
• Duplicate a CORBA object (reference)
Object Object.duplicate();
Miscellaneous Tools, Parameters
• naming service GUI
>nmg
• analysis of IORs
> dior -f ns.ior
------IOR components----TypeId :
IDL:omg.org/CosNaming/NamingContextExt:1.0
Profile Id
: TAG_INTERNET_IOP
IIOP Version : 1.1
Host
:
160.45.110.127
Port
:
1281
...
• Parameter for debug output (0=none, 1=important, ... 10)
jacorb.verbosity = 0
Java RMI  CORBA
• Java RMI
– is easy to learn and use,
– does not support heterogeneity, scalability, reliability
• CORBA
– needs effort for learning
– is a sophisticated industrial tool for the real world.