760 likes | 885 Views
Lesson 3. Advanced RMI JNI. Assorted real-world RMI issues. Review of rmi basics. rmi is a relatively very simple D.O. framework. Major limitations Only java to java Major advantages Clean, easy to deploy, robust Maps very cleanly to java language semantics
E N D
Lesson 3 Advanced RMI JNI
Review of rmi basics • rmi is a relatively very simple D.O. framework. • Major limitations • Only java to java • Major advantages • Clean, easy to deploy, robust • Maps very cleanly to java language semantics • Competing frameworks/technologies • CORBA • Web Services
rmi approach • Distributed objects have look-and-feel of local objects, but can be called across machines. • A distributed object is a regular object augmented with the following: • Extends UnicastRemoteObject • Have public distributed methods that throw RemoteException • Have parameters that implement Serializable • Have a constructor that throws RemoteException (it need not directly call super) • Have a separate interface file that lists the remote methods and extents java.rmi.Remote.
Creating stubs • Layout of most simple rmi application before stub generation looks like • Server • StoreImpl.java (implementation) • Store.java (interface) • StoreServer.java (to bootstrap) • Other local classes • Client • StoreClient.java • Store.java • Must compile client and server before using rmic!
Stub Class Generation • Recall that the _stub class contains the glue messaging code on both the client and the server. • There are three ways to create the stubs depending on which version of java you are using: • As of jdk5.0, stubs generated automatically. • As of jdk1.2, stubs are generated as • rmic –v1.2 StoreImpl • Before jdk1.2, stubs and skeletons are creates as • rmic –v1.1 StoreImpl • This creates StoreImpl_stub.class
Creating stubs • Layout of most simple rmi application before stub generation looks like • Server • StoreImpl.class (implementation) • Store.class (interface) • StoreServer.class (to bootstrap) • Other local classes • StoreImpl_stub.class • Client • StoreClient.class • Store.class • StoreImpl_stub.class • Must compile client and server before using rmic! Make sure these are same!
Deployment issues • A couple of more sophisticated issues arise in deployment • How to have client automatically download stubs and update class defintions • How to handle security issues • There are pretty simple approaches for each described in book. • For now, we will assume in our assignments that client has all updated class files and that security is not an issue. • I will give a quick pointer to security issues later in this lecture.
More complex issues Callbacks
Typical model of callback • class Client{ • Client(){ • Server x = new Server(); • x.doIt(…, this); • } • doIt(…){ • …. • } • } • class Foo{ • public void doIt(…, Client client){ • … • client.doIt(); • } • }
Callback example – timer class • At specified time interval, server sends you e.g. current time, which you display locally. • Design • Server contains register method and receives remote reference to client • Client contains update method which recieves current time and displays • Consider how both all rmi and rmi + sockets version of this program would look
Another callback example • TicTacToe game is another good example of a callback. • Client accesses server object to place next move. • Once new move is placed and accepted, server must contact other player with updated move. • In this sense, server become client and client server for this particular call • How to architect this with rmi?
Tic-tac-toe with RMI • Pure rmi implementation • TicTacToeClient is adorned as D.O. also! • Contains method such as otherPlayerMove • TicTacToeClient calls server register method and passes copy of this • TicTacToeImpl stores this and uses for D.O. call to inform other player of current players move. • Note that notion of server and client is only meaningful for a particular method!
Tic-tac-toe with RMI • RMI + sockets implementation • In this example, each client runs a socket server and gets a direct socket connection from the game server • TicTacToeClient is not a remote object • Game server still runs as remote object in regular way • Examples all posted on web site
Handling many server objects Bootstrapping registry
Binding many objects to registry • What if many people logon to play tic-tac-toe? How do we give each pair their own game? • What if we have many objects in general to post? • There are two ways to deal with this • give each their own name in registry (not good) • bootstrap off a single factory method (good)
Bootstrapping • For tic-tac-toe example, we could have a method: TicTacToe getGame() throws RemoteException; • As long as both getGame and TicTacToeImpl are setup up as remote, only one remote object need get posted to the registry. • Can create a pool of tic-tac-toe games and assign as they come in. • Will be required for hw2, recommended for hw1. • This is a great simplification vs. binding multiple objects! • See examples under bootstrap directory
Contacting rmi registry • In our simplified application, to get a remote reference we called: Naming.lookup(“tic-tac-toe”); • This assumes the default rmi port (1099) on localhost. • To change ports, run rmiregistery <port> • The more general rmi URL is Naming.lookup(“rmi://host:port/name”); e.g. to lookup on port 99 at host yourserver.com Naming.lookup(“rmi://yourserver.com:99/tic-tac-toe”);
Listing objects in the registery • Note that the Naming class has a method list which returns a listing of all objects bound to the registry. • It is called from the client as: String[] bindings = Naming.list(“<rmi url goes here>”);
Security issues • Recall that client needs up-to-date stub functions. • No problem if these are available locally on client. • However, keeping a local installation can be cumbersome. Often stubs are downloaded via other servers (we’ll see how to do this). • In this case, a SecurityManager needs to be installed to ensure that the stubs are not hostile (unless applet is used, which has its own SecurityManager).
RMISecurityManager • Easiest way to do this System.setSecurityManager(new RMISecurityManager()); • By default prohibits any socket connections • Obviously this is too strict. Need a policy file to allow client to make network connection to rmi port. It would look something like: grant{ permission java.net.SocketPermission “*:1024-65535”, “connect”} java Client –Djava.security.policy=client.policy
Server-side security/firewalls • For this class we assume you have control over the server security configuration.
RMI application deployment • Very simple if client/server both have up-to-date copies of all class files • However, this is unrealistic and impractical. • Better if client can dynamically load classes remotely. • RMI provides such a mechanism built on top of standard server protocols
Deployment, cont. • For server, following classes must be available to its classloader: • Remote service interface definitions • Remote service implementations • Stubs • All other server classes • For client • Remote service interface definitions • Stubs • Server classes for objects used by the client (e.g. return values) • All other client classes
RMIClassLoader • RMI support remote class loading by specfying the java.rmi.server.codebase property with an appropriate URL • This is done as: java WhateverImp -Djava.rmi.server.codebase=http://whatever ftp, file, etc. can also be used • See deployment directory in class examples • Proper remote deployment will be required on the next assignment.
Remote Objects and object methods Clone, equals, etc.
Using Remote Objects in Sets • Recall that equals() and hashcode must be overridden to use Sets. • For remote objects, this would require a network call to the server, which could fail. • Since equals does not throw RemoteException, it cannot be overridden and used remotely. • Thus, must use equals and hashCode methods in RemoteObject class. • These unfortunately only compare stubs, not contents. • Probably not a great idea to do this unless necessary
clone() method • Can not call at all directly for stubs • If you want to clone, simply define a new remote method (e.g. remoteClone), have it call clone locally, and return copy as parameter.
Non-remote objects • Note that all objects which are not remote are fully copied to client • This is very different from local method call, where objects are passed as references. • Thus, only remote objects can change state across client-server call • Also, performance issues can arise for very deep object graphs
Using inheritance with rmi • Stubs are generated only from classes that implement a remote interface (and only for methods in that interface). • Subclasses of remote classes can be defined and used in place of superclass in remote method call. • However, only superclass remote methods will be available, not any other defined in subclass!
Using synchronized methods in rmi • Recall that remote objects are passed by reference (stub). • Thus, when many users request the same object, they are manipulating a single copy. • If the object is immutable, there is no need to synchronize. • Otherwise, proper synchronization should be done in the regular way – using synchronized methods where appropriate, and synchronized blocks if necessary.
Native Data Types • Native data types • pass by value – parameter copied before remote transmission • exactly like single jvm behavior • machine-independent format used
Objects • Calling sequence for object parameters • pass by value also! • this differs from single-jvm behavior • All objects are completely serialized (deep copy) and sent to remote location. • This can be hugely inefficient. Be very careful when performance is at a premium!
Remote Objects • Java defines a third type of parameter – a remote object. • Remote objects must be setup as rmi distributed objects in the regular way (extend UnicastRemoteObject and implement Remote interface) • Remote objects are pass-by-reference. proxies rather than serialized objects are returned.
Distributed garbage collection • Server keeps track of clients that have requested object. • When client disconnects, they are removed from the list. • Also a timeout mechanism controlled by java.rmi.dgc.leaveValue. • Remote object can implement java.rmi.server.Unfererenced to get notification when clients no longer hold live reference. • Bottom line: not much to worry about here.
Creating objects remotely • What we have learned about RMI requires the server to instantiate one or more objects and post them to the registry • What if objects do not exists. Is it possible for the client to remotely create an object on the server? • This can be useful occasionally and is now possible with java Activation framework. • We will not discuss Activation in this class.
JNI • Recall that CORBA allows inter-language remote object calls; RMI does not! • However, JNI allows one to call “native code” directly from java. • Thus, the two together give more CORBA-like capabilities. • rmi calls java remote method, which locally calls C code, which returns java parameter(s), and rmi sends back to client.
What exactly does JNI do? • Provides the glue between java – C/C++ (but no other languages) • Provides the machinery for mapping datatypes. • Can be used to call C/C++ from Java (typical), or Java from C (invocation API) • Does NOT provide network transparency!
Reasons for using JNI • Feature not available in java language. • Code already written in another language, don’t want to rewrite. • Java is slow. • Other language has no additional features per se, but has much better syntax for handling certain operations (Fortran for math).
Problems with JNI • Only provides C/C++ bindings. Going to Fortran, COBOL, Ada, etc. requires extra step. • Not portable • Mapping is not trivial • No built-in security