As most are probably aware, we are progressing with the Maven build of River, all packages have been moved and now it's time to commence moving the junit tests to their maven modules.

The maven build structure is based on the work we've done in JGDMS, but there's no java code coming in from JGDMS at this time, just the module structure. At this time, it seems to make sense to also make maven modules OSGi bundles. However it is important to realise that making the modules into bundles isn't sufficient in iteself to support OSGi. This is due to a number of ServiceLoader Provider services being utilised within River. It's also an option to delay making these modules bundles until OSGi can be supported fully.

I've recently got to the point where JGDMS supports OSGi, so maven modules are also OSGi bundles, but in addition all service loader services are now also OSGi services and either the service loader or OSGi service registry can be used to load them.

River has two custom implementations of the service loader mechanism, one is org.apache.river.resources.Service the other net.jini.config.ConfigurationProvider. org.apache.river.resources.Service was practically identical to java.util.ServiceLoader up until Java 8, and service implementations must provide a zero argument constructor. ConfigurationProvider requires implementations to have constructors that have one or two arguments. For OSGi we needed a level of indirection to get around the constructor arguments, for this I have provided another interface that has a method that accepts the constructor arguments, Configuration providers implement this, consumers continue to use ConfigurationProvider::getConfiguration, even those using OSGi.

For Java 9 and later, if we decide to make our River modules jpms modules as well, we will need to convert these providers to use ServiceLoader for module visibility.

Long term I think it makes sense to have org.apache.river.resources.Service use ServiceLoader internally, rather than the current implementation, also it has been very useful as a common mechanism to consume service provider or osgi based services and leave the decision which to use to the developer.

Note that I am not making any attempts to register Remote Jini Services as OSGi services.

Anyone willing to assist with testing OSGi or writing some tests for it would be greatly appreciated.

The OSGi platform recommends avoiding the thread context ClassLoader, this can be avoided by following advice below.

Jini service implementations using the OSGi platform:

  1. Must be configured to use net.jini.jeri.AtomicILFactory
     
https://pfirmstone.github.io/JGDMS/jgdms-jeri/apidocs/net/jini/jeri/AtomicILFactory.html
         * AtomicILFactory requires a class argument in its
           Configuration, the ClassLoader of this class will be used
           for deserialization.
         * Codebase strings are not annotated in the stream by default.
  2. Jini Services must implement the following:
         * ProxyAccessor
           
https://pfirmstone.github.io/JGDMS/jgdms-platform/apidocs/net/jini/export/ProxyAccessor.html
         * CodebaseAccessor
           
https://pfirmstone.github.io/JGDMS/jgdms-platform/apidocs/net/jini/export/CodebaseAccessor.html
         * Service parameters or any classes that will be serialized
must implement AtomicSerial. https://pfirmstone.github.io/JGDMS/jgdms-platform/apidocs/org/apache/river/api/io/AtomicSerial.html
  3. The net.jini.loader.ProxyCodebaseSpi implementation must be loaded
     (one is provided, it will be discovered from the OSGi service
     registry).
  4. Proxy codebase URI Strings provided by CodebaseAccessor, must be
     bundles, they may be resolved using a provisioning URI mechanism.
         * In secure environments bundles should be signed.
         * The client need not trust the bundle certificates, these may
           be self signed, instead the service should be authenticated
           and the client trust the server certificates.  Once the
           server is authenticated, the ProxyCodebaseSpi implementation
           will dynamically grant DeSerializationPermission to
           codebases signed with the certificates and URL's in the
           codebase annotation.
  5. Once the bundle has been resolved, the service proxy will be
     deserialized into the bundle's ClassLoader, this bundle should be
     identical to that at the server endpoint, so that both endpoints
     have identical class visibility.   This is the service proxy
     bundle, the service implementation at the server will depend on it
     and all serialized object classes will be contained within the
     service proxy bundle or one of its dependencies.
  6. Note that it is advisable to sign proxy bundles.

To avoid the overhead of NP Complete dependency provisioning, ServiceDiscoveryManager should be utilised.

See also https://github.com/pfirmstone/JGDMS/wiki/OSGi-and-JGDMS

Note this is separate to River, the integration of these features into River is dependant on community review and acceptance.

Regards,

Peter.

Reply via email to