Wednesday, February 27, 2008

Back 2 Basics : RMI

Intro and Basics

RMI forms the basis for Java's own remoting capabilities. RMI makes remoting transparent by making remote objects look like local objects. The only difference from a user of a remote service's user's perspective would be how the object itself is obtained. RMI is based on 3 abstraction layers.

  • Stub / Skeleton layer
  • Remote Reference layer
  • Transport layer

Stubs and Skeletons

Stubs and skeletons are special objects that make remoting with RMI possible. The client actually invokes the method on the client side object called Stub, though this is transparent to the client, since the client uses an interface type. The method call and the parameters are intercepted by the Stub, marshalled (something like serialized) across to the Skeleton, a server side object which un-marshalls (deserializes) the method call and parameters and makes the call to the actual object. The return value is intercepted by the skeleton and sent back to the Stub, who in turn returns it to the client. The stub is a proxy on the client side and the skeleton is a helper class that acts as liaison or connector between the Stub and the actual object. The Stub passes the data to the remote reference layer, which hands it to the skeleton.

Remote Reference Layer

The remote reference later defines the semantics for remote object references. It connects the and governs the communication between the the Stub and the Skeleton. Its is JRMP specific and defines classes like RemoteRef which are used by the Stub to get data across to the Skeleton. From Java 2, remote reference layer adds semantics for activatable objects. Another example of the semantics defined and managed by this layer is Multi-cast , in which the method is invoked on several remote implementations and he first response to return is used.

The Transport Layer

The transport layer is responsible for the low level connection between the two JVMs, and management of these connections. RMI defines a wire level protocol called JRMP, JRMP is on P/IP and also provides some firewall penetration strategies. JRMP was updated in java 2, to eliminate skeletons and to use reflection instead.

Looking up Remote objects

A client can use either JNDI or the more simpler RMI registry to look-up the remote objects. We will not discuss JNDI here. The RMI registry itself is a remote object., and implements the interface java.rmi.registry.Registry. RMI registries can be started as a separate process or in a programmatic way, by an object itself, and by default runs on the port 1099. Starting a registry means exporting the remote object that implements the Registry interface, that is the actual resgisty itself is a remote object. Once a remote object is bound to a registry under a public name, a client can look-up the registry for a remote object based on the name with which it was bound. Here's what happens :
  • The client tries to get a registry, which gets him a Stub that acts as the client proxy to the registry, [This step is usually transparent because JDK classes d the job of getting the registry]
  • The client makes a "look-up" on the registry with the pubic name with which the remote object was bound
  • A Stub to the remote object is returned to the client.
  • The client can now invoke methods on the remote object just as if it were a local object.

Parameter Passing

With RMI we have three types of parameters :
  • Primitive params : these are passed by value , just like any other primitive parameter.
  • Object parameters : Since references in one JVM are meaningless in another JVM, objects are serialized and passed by value. So changing the properties of an object in the remote JVM does not make those changes visible to the local JVM.
  • Remote Params : Remote params are params that happen to be remote objects themselves. When a remote object is used as a parameter or a return type, the JVM passes the stub to the remote object and not the remote object itself. Under the covers the JVM checks the parameters and return types. if any of them is an instance of Remote, then its stub is fetched, serialized and sent across, instead of the actual remote object. this rule applies to all references, including say, retuning 'this' from a remote object.

Distributed Garbage Collection

RMI provides a distributed garbage collector to gc the remote objects. GC in RMI is more complex because there may not be any local references to an object. Internally, the JVM keeps track of clients requesting access to a remote object, and marks that object as dirty. When the remote reference is dropped, the object is marked clean; all clean objects are eligible for garbage collection when the DGC runs. In addition to the reference counting mechanism, there is a lease mechanism, which basically means that even if a client requested access to a remote object, unless the client is actively using the connection, the connection has a timeout associated with it (default 10 mins), and when the timeout has been reached, the object is marked clean. Like the finalize() method, RMI has an interface Unreferenced, with a single method unreferenced() that is invoked when there are no more clients holding a live connection to the remote object. Remember that the registry itself is a client to the remote object and the unreferenced method on a remote object(should it choose to implement Unreferenced) will not be invoked if the registry is holding a reference to it.

Dynamic Class Loading

Normally the clients needs to have the remote interface type class files available on the client JVM so that they can use it to cast the resulting stub from from a look-up and invoke methods on it. However, RMI support dynamic class loading as an alternative to this static approach. Dynamic class loading in RMI works similar to applets; a system property for a codebase is set and the required class definitions are downloaded on demand from that code base. the property is java.rmi.server.codebase and is a URL that can be accessed with file:// ftp:// or http:// protocols. note that though we say "client jvms download the class def" its not restricted to client JVMs. server JVMs can also use a code base to download other remote object definitions or client side classes for callbacks. When an object is bound in the registry, the code base is also saved with it.When a client requests a remote object, the registry returns a stub to the remote object, and the client JVM looks for the class definition of the stub in its CLASSPATH and if it does not find it there, it uses the code base from the registry, to download the definitions. RMI has its own Security manager, the RMISecurityManager and the VM will not download any files unless the security manager is present.

Advanced RMI

Object Activation

One of the downsides to RMI is that the remote objects have to be accessible at all times, including when clients are not executing or requesting their services, and eats up a lot of resources. To solve this problem object activation was introduced. This is similar to having the remote objects on an "as required" basis, and can be though similar to lazily instantiated references. All the magic happens in the Remote reference layer, and the stub given to client is not connected to a live remote object or its skeleton, instead its connected to the activation system, that transparently makes resources available when the stub is actually being used. Tha activations system is a complex ecosystem and core t it is an RMI daemon 'rmid' which is able to start
new VM instances for the required remote objects 'On Demand'.

Activatable Remote objects extend from the abstract class Activatable(no this is not an interface) and not from the usual UnicastRemoteObject. The process of registering an activatable remote object is also considerably different, though the client does not see any difference. The steps are :
  1. install the SecurityManager - RMISecurityMananger
  2. create an ActivationGroup - which is an object that keeps a collection of activatable objects
  3. create an ActivationDesc - or ActivationDescriptor instance, that provides all information to the rmid (the Activator) to create a new instance of the Implementation class.
  4. register the remote interface with the Activativator - Activatable.register() registers the Remote interface with the rmid
  5. bind the stub that was returned as a result of register() with the RMIRegistry.

once this rig is setup, Activation process works like this :
  1. The Stub for the Activatable object contains special information like the ActivationID that idetifies an Activatable.
  2. The stub uses this ActivationID to call on the Activator (rmid) to activate the object.
  3. The activator (rmid) uses the ActivationDescriptor to find the JVM in which the object is to be activated.
  4. The activator locates the ActivationGroup and if the ActivationGroup does not yet exist, then a new JVM is created for the AcivationGroup to run in and the request for the object's activation is forwarded to the ActivationGroup.
  5. The ActivationGroup loads the class and creates a new instance of the remote object.
  6. The live reference of the real remote object is returned to the Activator , which records the ActiovationID and reference pairing and the live reference is returned to the stub.
  7. The stub now forwards all method invocations to the remote object via the live reference.

HTTP Tunneling

Firewalls prevent application / non-standard ports from being opened up in a public network, we can use HTTP tunneling to get RMI working. Tunnelling is essentially wrapping up the RMI calls inside an HTTP POST request.
Its the responsibility of the Transport layer to do this wrapping. There are two ways to do this :
  • HTTP to port : Used when the client of an RMI service is behind a firewall. The JRMP call data is automatically wrapped in an HTTP POST and sent to the proxy server on the client. This proxy server is the http proxy server the client uses to connect to the public network. The only config required to do this is to set the proxy server settings via java system properties.
  • HTTP to CGI : is used when the the server is behind a firewall and cannot accept incoming connections. Here the transport layer redirects http wrapped JRMP calls to a cgi script running in a webserver. This cgi script is java-rmi and is a part of the JDK ( see bin directory). A servlet version of the cgi is also available. The cgi intercepts requests coming on 80, which is intended for a non-default port (the client transport layer embeds this info if its wrapping up the JRMP call in http) and forwards the call to the local port.

Although tunnelling is a very attractive solution to the problem of firewalls, they should be carefully used because there will be severe performance degradation, and the cgi script is actually a security hole and tunneled applications cannot use callbacks.

RMI IIOP - CORBA Interoperability

RMI-IIOP was designed to make RMI applications interoperable with CORBA applications. This involves supporting both the RMI's own wire protocol JRMP s well as CORBA's wire protocol IIOP. The interoperability is achieved by letting java developers use a Java interface and the CORBA developers use the IDL for coding. With an RMI-IIOP server, the remote interface can be used to generate the corresponding IDL for a CORBA C++ Client. The clients can also use a IDL to java conversion to convert IDL to a Java Interface, enabling the RMI-IIOP client to connect to a CORBA server. The stubs for an RMI-IIOP Client should be generated with the -iiop option so that they can use the IIOP protocol.

CORBA compliant remote objects are derived from the PortableRemoteObject and they need to be rmic'd with the -iiop option to tell the compiler to generate Stubs and skeletons that can speak RMI-IIOP. They form the foundation for the enterprise level distributed computing in java and the heart of the EJB programming model, though EJBs would make most of this transparent to the developer. Another crucial difference is that in a plain vanilla RMI-IIOP environment, the rmi registry is replaced by JNDI using a COS Naming Service like tnameserv or an LDAP server. Distributed garbage collection is not supported by CORBA, which means objects have to be created and destroyed explicitly. The RMI activation system is replaced by the PortableObjectAdaper and the remote references have to be down cast using the OPrtablRemoteObject's narrow() method and not using a normal java cast.

Sunday, February 03, 2008

Riders

The moon shone on the arid desert
The wind caressed it, the dry leaves fluttering
the stars like Christmas lights
The cactus bushes stood ignorant and
across the canyon rode the rider.

Relentless and unforgiven
Hollow and void
his sights set deep in to the night
he passed the cactus bush
The very same one he passed
he never knew how many times
he had stopped counting after the first few

Tired but still resolute
he looked toward the horizon
the one thing that still eluded him

Friday, February 01, 2008

CDMA

Confused Desi in Mainland America.
I admit. I really don't get it. Being a Desi in the states has brought its share of confusion in me. After much rumination I am sorry to say the confusion is not going to go away. What I have ascertained causes much despair as its neither going to change soon, nor is it going to be easy to see the light. We seem to be hard wired to certain ideas, belief systems and a way of thinking, what we call a mindset. Desi's in the US come in many flavors, the americanized ones who after an year of getting off the boat , all of a sudden seem to think that India is a village and crack jokes about it with his new homies in da 'hood [I call these the fresh dawgs ], or the more commonplace "OMG that coffee is 3 bucks .. thats like 120 Rupees. I'm NOT drinking THAT !" kind [the constant calculator], then we have the ever so common "Wanna screw white chicks, but I'll marry only a 'good girl' from India" type [the horny chauvinist ] and thats just a broad generalization.

Simon lives in an apartment and shares place with 3 other guys and cant find enough time to explain why India is still a frigid old village and how the American life has made him see the light. It was a Saturday night and like every other Saturday night he goes out to a club. Inside the club the American Desi faces a dilemma, the brown skins are outnumbered and his new found culture and lifestyle don't seem to stand a chance with the real thing. The first thing that he does is to scope out the place. Not for low hanging fruits but simply for prey looking the other side. The target is locked, he runs. Like an F-22 re-fueling in mid-air, he tries to connect his nozzle to the rear of his prey. The unsuspecting girl shrieks and jumps ! Simon engages the cloaking device called "run the hell outta there" and moves in to stealth mode. Bogie one is down. Between a couple of beers he hunts down another couple more targets. Mission accomplished, Simon returns to base before lights come on and blows his cover. At home he found the (single) bedroom locked, from the inside and yells "Sridhar, make it fast. I've got to sleep, gotta go to the church tomorrow"

Sridhar is working for an Indian software company and has been here for just about two months now on an on site assignment. He does not join Simon in his club quests since the entry fee is 10 bucks and thats like 400 rupees. Simon chuckles as an apparently exhausted Sridhar opens the door ... "dude ... get a life man. get a lap dance instead of a laptop. You stupid Indians ... break out of that shell man... taste the real life like me...". Poor Sridhar makes the mistake of asking Simon how the night went. "Dude ... cool man... I danced with at least 5 chicks man... I was grinding so hard with the third chick, I almost messed up my trousers man...hahaha...So you decided on what laptop you wanna buy ? " Sridhar's time once he got back from work was divide between searching for laptop deals, checking the USD to INR conversion rate every other minute and watching porn. "The Dell has a new coupon and I get it for 15 bucks less than the HP with the same config. But I'm still undecided if I want to go for a 2.0 GHz one and pay the extra 100 bucks. Or maybe I should go for that VAIO, it looks so sexy. I'd love to have that MacBook but nothing runs on it. Sim..."
Simon is heartily snoring by now lying next to Jinesh who was already dead asleep, and Sridhar ponders if wants to watch more porn or search for more deals, he starts by hitting finance.yahoo.co.in and checking the Dollar rate now. "Damn! down 15 paise again..."

Earlier that day Jinesh was out and his phone rings. "Hello Amma... ... Yeah I'm doing okay ma... How is everything there... okay... what ? the proposal ?... okay did you see the girl's photo ? okay... Is she fair ? how fair ? and did you like her ma ? .... Whats she doing ma ? what ? ... shes a fashion designer ? No ma... I told you na.. nothing but IT people please.. Its very hard to find job openings in these professions here, IT is easy and how do you think two people can survive here without a double income ? ... No ma... Plus you have absolutely no idea what goes on in these colleges ma... I'm sure she's had an affair and all... ... No ma ... I told you na... Look for only software engineers and girls who went to colleges nearby their homes, and not hostels... Okay ma... I'm in the midst of some work here, I'll call you back ma.. Yeah... I'm staying late in the office today, lot of work to do...Okay...bye." Jinesh puts the phone away and deftly slides a dollar bill in to Eva's g-string as she purrs in her Scandinavian accent "ready for your next lapdance... baby ?" somebody would have to wipe the smile off his face now.


But all this boils down to some simple facts. Simon has a confused identity, Sridhar, a confused bank statement and Jinesh, confused morality. But how should I explain myself as the guy who sat in the living room all the while just blogging about it ?