Java RMI, making an object serializeable AND remote
You might be thinking why would you want to have an object both Remote AND serializeable. Well let me give you some context.
I'm building an air traffic control system (school project), it's distributed so that each control zone runs on it's own server and communicates with other control zones. Each control zo开发者_运维知识库ne keeps track of its own aiplanes.
When an airplane (flying in controlzone A) is 100km near its border, it is passed as a remote object to the controlzone (controlzone B) it's near to. This way controlzone B can see where the aiplane is (by periodical asking its position) while it's still controlled by controlzone A.
But when an airplane crosses the border between controlzone A and B, controlzone B should keep track of the airplane instead of controlzone A. So we we want to serialize the airplane and pass it to controlZone B. This is where our problem lies.
Can I make the airplane remote AND serializeable?
EDIT: Also, I could use remote methods to copy the needed fields for the airplane, but I prefer serializing it.
If a remote object isn't exported at the time it is sent as a remote method parameter or result, it is serialized instead of being passed as a remote reference, provided that it implements Serializable as well as Remote. It is then exported at the receiver. UnicastRemoteObject does this for example, and therefore so does any remote object derived from it. This can be used for mobile remote agents.
You don't have to make your object subclass UnicastRemoteObject.
Take your class, define it to implement Serializable and your RMI api interface, which itself should implement Remote. It doesn't need to subclass anything other than java.lang.Object.
When you are ready for your object to be called remotely, call the static UnicastRemoteObject.exportObject() method on it. From that point on, any reference you return over RMI to that object will be remotely callable.
When you want to pass the object off to another server, call UnicastRemoteObject.unexportObject() on your object. Then when you pass it over an RMI call, you'll be passing the serialized representation of that object.
The downside to this is once you pass it off, the object on your server will no longer accept RMI calls. unexportObject() turns it off completely as an RMI call recipient.
If you want to be able to maintain an object as an RMI target and concurrently pass it around over RMI as a serializable object, you'll need to make it serializable and interpose a proxy object that exports the Remote interface and which can talk to the non-exported, serializable object on the caller's behalf.
When you want to pass the underlying object with serialization, you pass it directly. When you want to pass a remotely callable reference to it, you pass the proxy.
Take a look at UnicastRemoteObject
class. It is normally used for callback driven programming in RMI and hence implements both Remote
and Serializable
. Though you might want to revisit your logic since you now have an entity (airplane) which acts like a "remote server".
Turns out this solution was not correct. See @EJP's answer below for the only way to do this with a single instance.
精彩评论