Let me put it another way:
I want to work toward a cooperative distributed computing platform using
Java & Jini / River, continuing from where Sun left, using lessons learned.
1. I'd like to set up a class loader framework building on
classworlds, to segregate incompatible class versions with the
same name, while allowing compatible implementations to
interoperate, based on Class loader visibility.
2. I'd like to utilise the ASM bytecode library to perform static
analysis on bytecode to identify Package & Class API to determine
compatibility.
3. I'd like to solve the lost code base problem using codebase
services combined with the suggested Class loading framework.
4. I'd like to use codebase servcies to provide codebase proxy's for
often disconnected clients.
5. I'd like to allow bytecode to evolve organically by taking
advantage of the flexibility of binary compatibility.
6. I'd like some metadata to identify at the minimum ,Package
Versions, I could generate checksums based on Package API, however
this wouldn't identify which version is the latest, only which
Package implementations can substitute another's API where those
packages share the same name. Or identify packages with the same
name that are incompatible and segregate these in separate
Classloaders.
7. If possible due to concerns about the performance impact of many
Classloaders, group some packages together when the author doesn't
intend those packages to evolve separately. Eg libraries.
8. I'd like to make it possible to transfer class version and package
version information with serialized object instances for
compatible re-instantiation with the latest evolution of
compatible classes. All suggestions are welcome.
Does anyone have any suggestions for suitable existing formats for
Containers with Version Metadata that might be utilised? If so what issues
are there to be aware of? What are the arguments for and Against?
Note, I'm aware of the existing Java Version Spec that applies to
packages.
I believe I made the mistake of suggesting a solution without properly
formulating or posing the problem, my apologies for any confusion this might
have caused, I should have raised a new thread / topic, In the original
thread, Gregg is looking at classloader dependency issues implementing a
plugin for Netbeans to make River more accessible to IDE developers, please
feel free to make suggestions, we need your help.
I made a suggestion earlier to utilise the OSGi bundle metadata
specification, these are ordinary jar files with package version, exports
and dependency metadata. They are otherwise ordinary plain old jar
archives, quite useable as a jar file containing java class files that can
be utilised without the OSGi framework, which is what I was suggesting. I
attempted to imply that the exported packages could have their API
identified and shared in a compatible manner with other packages, using
Class loader isolation perhaps this is not a suitable solution due to the
confusion that it would cause with developers expecting an OSGi
implementation, utilising OSGi service interfaces. If this format was to be
utilised, it might have to be renamed, to River Codebase Bundles (for
uploading to codebases) whilst sharing the same format to avoid confusion.
It might be a subset of the OSGi bundle format, such that OSGi bundles, like
those on the Spring Source Repository could be utilised. It might also be a
component in an eventual Container spec, if we can sort that out. Gregg has
asked for container suggestions more than once, I'd like to see that
conversation continued.
If this solution was adopted, the dependency version metadata (Import
Package) in the bundle would be noted, considered a minimum version as per
the OSGi spec, but a later version would be utilized if it were found API
compatible. However additional protection by static analysis would
guarantee that a later version that wasn't API compatible would not be
utilised. The reason I'm considering this compromise is that a bundle
author cannot know in advance that later import packages will be compatible,
hence Static Analysis can verify API compatibility. It is still possible
for identical named classes to be loaded in the same jvm, in another
classloader, this might occur if an earlier package version already exists
but doesn't satisfy the Import Package version criteria; it wont be used as
it is earlier than the minimum required version. The Classloader
responsible for the bundle would keep a copy of the metadata available
while it remains loaded, it would not utilise the OSGi interfaces to access
the metadata. I envision Immutable Mirror Objects that can be transferred
with marshalled instances and utilised for API compatibility checking. The
Mirror objects would be created by a codebase service and stored in memory
by the Classloader that download the class bytecode (River Bundles) being
Mirrored, the mirror objects would contain the metadata from the bundle as
well as the API, the mirror objects would be used by the classloader to
determine which packages to export as well as check for import package
compatibility, and by other Classloader's for compatibility. If no
compatible packages are found loaded then the codebase services would be
consulted, the import package mirror object would be submitted to the
codebase services to locate a compatible package or bundle.
In principle, if this is still objectionable, I'm happy to create an
implementation utilising another container or bundle format that satisfies
the requirements, provided that one is recommended. This list does have a
history of heated debate regarding OSGi and Jini, I'd like to avoid any such
unproductive arguments if possible.
Regards,
Peter.
Niclas Hedhman wrote:
On Mon, Oct 19, 2009 at 7:40 AM, Peter Firmstone <[email protected]>
wrote:
Thanks Nic for your comments, pls see reply below.
I think we have diverged and discussing different things.
Some time ago, it was said that the classloader of a class could be
retrieved by calling a static method. I have tried to point out that
this is fairly "impossible" in OSGi without collaboration with the
OSGi framework implementation, as multiple (even fully compatible, or
even exact same versions) instance of the same classes can be present
in different class spaces within the OSGi framework, and which package
got resolved to which bundle (and hence the classloader) is an
implementation detail in OSGi. There is no theory around that fact. I
am speaking of "locating a classloader of an existing class already
present", and not how to locate one externally to the JVM and OSGi
framework.
See the difference?
So if ClassA wants to load an implementation of InterfaceB, then that
implementation must be chosen from the class space that ClassA and
InterfaceB belongs to, and not only that it implements
InterfaceB+constraints.
Cheers