With River, we execute separately compiled bytecodes at runtime by taking advantage of discovery and lookup services - distributed dependency injection. Service API, Java and Jini Platforms provide compatibility, for separately compiled components, these are the parent classes and interfaces that clients and services use for communicating across compile time boundaries, demarcated by Service API.

Determining classes to be shared between proxy and client namespaces and identifying what shouldn't be creates challenges for developers, who currently need to define preferred class lists.

My personal preference is to share as little as possible, how selfish!

The Java platform itself presents issues with Memory isolation, namespace visibility, class resolution and codebase annotation loss for proxy's or distributed objects.

proxy - remote reference, implements Remote
distributed object - local copy of an object, serialized, implements Serializable.

If we share only the Service API, Java and Jini Platform classes and objects, then we minimise Java platform issues.

Proxy classes that extend services API, java or Jini platform classes don't need to be visible to the client (the reverse holds true also), since client code uses the super classes and interfaces in the Service API, Java or Jini Platform.

In reality client classes and any other libraries are loaded into the application ClassLoader with the Service API and Jini Platform, so all these additional classes are also visible to proxy's.

If the proxy uses libraries or has classes in the same namespace as the client, unless the proxy's classes are preferred, they will be resolved by the application ClassLoader (the classes may or may not be compatible), if the proxy is later transferred to another node in the network, the codebase annotations have been lost because the classes were loaded by the application class loader and resolved from the class path. If the 2nd remote node doesn't have the required classes on its classpath, it's game over.

This problem could be solved if the Classpath isn't visible to the proxy, only the ServiceAPI, Java and Jini Platform classes, so developers don't have to understand ClassLoader visibility and preferred classes and may instead just focus on developing services and getting their OS and network to support multicast discovery.

Some options:

  1. Use the extension classloader (command line option, not
     /jre/lib/ext/) for ServiceAPI and Jini Platform classses, the
     classpath will then not be visible to the proxy's that reside in
     child classloaders of the extension classloader.  Note classes in
     the extension classloader can have reduced permission and don't
     have to be AllPermission.
  2. OR Create a new child classloader, for the application and all
     libraries.
  3. OR Use a Subprocess JVM for all smart proxy's (identified as
     classes implementing Remote and having codebase annotations), the
     JVM has been optimised to share platform class files with
subprocess jvm's for fast startup and less memory consumption. However this requires reflective proxy's to represent smart
     proxy's in the main jvm, the part I haven't figured out yet is how
     to have a reflective proxy replaced by a smart proxy when it gets
     transferred to another machine.  Perhaps it might be possible
     using a marker interface on the reflective proxy, however I'll
     save that discussion for another thread.


To have any of these work properly would require a container, Tim Blackman's Jini in a jar https://issues.apache.org/jira/browse/RIVER-342 solves a number of the configuration, command line options and classpath visibility issues using a new URL scheme, which enables a Jini application to be run from a jar file.

Do you think it's time we work towards a standard container? So that at some point in the future all the downstream projects will be able to support it as well as their existing container?

What are the requirements for such a container?

Regards,

Peter.

Reply via email to