My point throughout the whole thread is that to support these scenarios:
1. Manipulating class streams (like in Voyager) is not necessary (quite
franky - I think it is a bad idea actually since it assumes a single
namespace for classes what precludes class evolution)
2. Dictating a particular "class conveyance mechanism" is not necessary
either
What I am proposing is:
1. Abstract over a "class conveyance mechanism" (by making codebases
serializable objects which classes implement a specific contract)
2. Change ClassProvider API to support the above (accept abstract
codebases instead of only Strings)
3. (Optionally) - provide a default class conveyance mechanism that:
a) allows resolving classes in non-hierarchical way (similar to
ClassWorlds or JBossModules or... OSGI)
b) supports coexisting of other "class conveyance mechanisms" in the
same JVM
Point 1 and 3b) will make the whole solution really dynamic allowing a
"class conveyance mechanism" to be dynamically downloaded by the client.
So - how do you make sure a service deployed in OSGi container may send
its proxy to a non-OSGI client? Yes! You let the client download the
OSGI container dynamically!
What's more - once you abstract over how the classes are downloaded - it
is possible to support downloading code through relays etc.
Thanks,
Michal
Gregg Wonderly wrote:
The annotation for the exported services/classes is what is at issue here.
Here’s the perspectives I’m trying to make sure everyone sees.
1) Somehow, exported classes from one JVM need to be resolved in another JVM
(at a minimum). The source of those classes today, is the codebase specified
by the service. A directed graph of JVMs exchanging classes demands that all
service like JVMs provide a codebase for client like JVMs to be able to resolve
the classes for objects traveling to the client form the service. This is
nothing we all don’t already know I believe.
2) If there is a 3rd party user of a class from one JVM which is handed objects
resolved by a middle man JVM (as Michal is mentioning here), there is now a
generally required class which all 3 JVMs need to be able to resolve. As we
know, Jini’s current implementation and basic design is that a services
codebase has to provide a way for clients to resolve the classes it exports in
its service implementation. In the case Michal is mentioning, the demand would
be for the middle man service to have the classes that it wants the 3rd service
to resolve, in some part of its codebase. This is why I mentioned Objectspace
Voyage earlier. I wanted to use it as an example of a mechanism which always
packages class definitions into the byte stream that is used for sending
objects between VMs. Voyager would extract the class definitions from the
jars, wrap them into the stream, and the remote JVM would be able to then
resolve the classes by constructing instances of the class using the byte[]
data for the class definition.
Ultimately, no matter what the source of the byte[] data for the class
definition is, it has to be present, at some point in all VMs using that
definition/version of the class. That’s what I am trying to say. The issue is
simply where would the class resolve from? I think that class definition
conveyance, between JVMs is something that we have choices on. But,
practically, you can’t change “annotations” to make this work. If the middle
man above is a “proxy” service which bridges two different networks, neither
JVM on each network would have routing to get to the one on the other side of
the proxy JVM. This is why a mechanism like Objectspace Voyager would be one
way to send class definitions defined on one network to another JVM on another
network via this proxy service.
Of course other mechanisms for class conveyance are possible and in fact
already exist. Maven and even OSGi provide class, version oriented conveyance
from a distribution point, into a particular JVM instance. Once the class
definition exists inside of one of those JVMs then we have all the other
details about TCCL and creation of proper versions and resolution from proper
class loaders.
I don’t think we have to dictate that a particular class conveyance mechanism
is the only one. But, to solve the problem of how to allow classes hop between
multiple JVMs, we have to specify how that might work at the level that
service instances are resolved and some kind of class loading context is
attached to that service.
The reason I am talking specifically about directed graphs of class loading is
because I am first focused on the fact that there is a lot less flexibility in
trying to resolve through a large collection of specific classes rather than an
open set of classes resolved through a directed graph of the code execution
path which exposes the places and moments of object use in a much more
controlled and natural way to me.
Gregg