Java: Strong Code mobility How to?
Does anyone know how to use Java for Strong code mobility? Have you ever done it before?
Here's what I try to achieve.
Suppose we have 2 separate Java applications that communicate over network. App A and App B.
App A has a class x instantiated as an object, and has been using it. App B has no prior knowledge of this class x.
App A needs to migrate the instance of class x over to App B. App B should be able to dynamically load class x, and retains the state of class x.
I have Googled around and found a bunch of resources on how to dynamically load class at run-time. However, I'm not sure if the mechanism of transferring an object instance over network along with its state, and to invoke it dynamically is covered.
Any pointers would be very helpful, and thank you in advance!
NOTE: I'm mostly interested in how (i.e. 开发者_StackOverflowthe approach, way to think) this problem is solved, not what is used to solve this; this is because I'm tasked to come up with my own solution to solve this problem. Though pointing out libraries/framework is great, it would be ideal if answers are posted from people who have done something like this before (however rare).
You ask about strong mobility, but your requirements are fulfilled with weak mobility, which with some limitations is provided by the RMI protocol. RMI does not only support RPC, object serialization and distributed object graphs, but also code sharing usually used so that the client can load the bytecode of classes only known to the server and execute that bytecode locally.
Strong mobility is not supported by Java and I can't think of a way to implement it without making proprietary extensions to the VM. Essentially, strong mobility in a Java context would mean that you suspend or pause a thread in one VM, transfer all object instances reachable from that thread, potentially bytecode required for the execution and the internal thread st (call stack, etc.) to a different VM and make it recreate the thread state and continue execution at the point where the thread was paused in the original VM.
I have written an open source library which supports Code Mobility exactly as asked above. Actually it supports RPC-type usage as well.
See: Mobility-RPC - Seamless Code Mobility and RPC for the Java platform
In terms of where this stands on weak mobility versus strong mobility: in the middle.
When you transfer an object to a remote machine, you can control which method on the object gets invoked, and with which arguments, when it arrives on the remote machine. So if you're writing a mobile agent, then it can decide itself how it wants to resume execution on the next machine before it transfers itself, it doesn't have to resume from the same place.
There is a project called cajo which can move objects dynamically over the network. I am not sure about the execution state though.
In normal Java you'd need some way to have App B load the Class for the object, then you need to serialize the object from App A to App B. You could do this, perhaps, if the classes are available in some central location such as an HTTP server. But in the general case where you want to transfer a completely new object to App B you'd need to implement your own classloader (or find a library that does this).
If all your objects are Serializable and you have a central location to store the classes, this should be fairly straightforward to implement. You could use the URLClassLoader to load classes from an http server, then normal Java Serialization to transfer over the serialized object. Some coordination between Apps A and B would be required so that B knows which class to load and A knows when to send the object, and B knows how to continue execution of the object's methods. With this approach there probably is no way for the object X to be in-progress of executing a method; it would have to stop and then restart its execution in cooperation with App A.
You need TWO things transferred from A to B in order to move an instance I of the class C.
First the class definition of C (usually in form of a list of byte codes) and then the serialized form of I. Please note that you should use XML serialization instad of the old binary serialization.
The really tricky part is getting the dependencies of C transferred as you need to essentially transfer all the superclasses of C too, plus all the return types and field types, and THEIR superclasses and return/field types etc. etc. etc.
If you really need to do this for all possible values of C your best bet is using a framework designed to do this like a grid one or Terracotta. If you can restrain yourself to e.g. a given and narrow interface, you will probably be much better of. Also consider just using properties for this, as they are very simple and can get you far.
If you are using JDK6 you can send source code over, compile it, so now the classloader can find this new class, as it was compiled dynamically.
The trick then is that you may need to use some DI to get this loaded into your application, so you need a DI framework that can work dynamically.
Then, when it is injected into your class, you set the properties at that point.
These should have a known interface. There needs to be a contract that both can depend on.
I haven't tried it, and I don't think Java is the correct language for this. If you must have this functionality you may want to look at something like one of the jvm scripting languages or Clojure, as I expect that it will also work with this, and then have your java application interact with this other dynamic framework, as it would all be running on the jvm.
UPDATE:
Here is a link on on-the-fly compiling,with JDK5 as it something that many people may not be familiar with.
http://fivedots.coe.psu.ac.th/~ad/jg/javaArt1/index.html
精彩评论