I think what you mean is, it will work in the majority of cases, but corner 
cases could occur that don't, when multiple versions of a (shared class 
namespace / api) bundle are installed that could resolve to different versions.

Still I think it's wise to give Bharath the opportunity to attempt to solve / 
demonstrate it.

The bundle manifest and the current jvm wiring state influence the dependency 
wiring outcome.

The uses package declaration in a manifest and how it influences the wiring or 
resolution process is important.

Package Admin Service is another important powerful tool to consider.

Remember that the proxy has no dependants in the client jvm, so it should 
always get the version it requests therefore multiple proxy bundle versions are 
harmless.  It's the shared api bundles that must resolve correctly.

Cheers,

Peter.

Sent from my Samsung device.
 
  Include original message
---- Original message ----
From: Michał Kłeczek <michal.klec...@xpro.biz>
Sent: 01/02/2017 05:29:09 am
To: dev@river.apache.org
Subject: Re: OSGi

Unfortunately it is not going to work in the general case as I've shown in 
another message. 

The issue is that since you do not have influence on how the bundles of 
ServiceProxy and ImplementationDetailServiceProxy are resolved, you cannot 
guarantee that ImplementationDetail interface is going to be resolved from 
the same bundle for both. 

Michal 

On Tue, 31 Jan 2017 at 06:38, Bharath Kumar <bharathkuma...@gmail.com> 
wrote: 

> With help of some information from service providers,  we can implement 
> this use case in osgi environment easily. 
> 
> Suppose if we split these classes as separate bundles, we will have 2 sets 
> of bundles. 
> 
>    1. ImplementationDetail.api - contains ImplementationDetail service api 
>    class and its dependencies 
>    2. ImplementationDetail.proxy - smart proxy for ImplementationDetail 
>     service 
>    3. ImplementationDetail.service - ImplementationDetail service 
>    implementation 
>    4. ImplementationDetail.bootstrap - service bootstrap bundle for 
> ImplementationDetail 
>    service. 
> 
> ImplementationDetail.bootstrap bundle creates the service and annotate the 
> codebase location. 
> 
> 
>    1. forClient.api - contains ForClient service and its dependencies 
>    2. forClientproxy - smart proxy(ServiceProxy) for ForClient 
> service. It imports 
>    classes from ImplementationDetail.api bundle and forClient.api bundle. 
>    3. forClient.service - service implementation(ServiceBackend) and 
>    depends on forClient.proxy and forClient.api bundles 
>    4. forClient.bootstrap - service bootstrap bundle for ForClient service 
> 
> 
> Here fooClient.proxy dependens on ImplementationDetail service. So it can't 
> be created until ImplementationDetail service is available in the network. 
> So forClient.bootstrap bundle registers a ServiceTemplate instance into 
> osgi registry. This will help to find ImplementationDetail service from the 
> network. 
> 
> Once ImplementationDetail service is available in the network, 
> forClient.bootstrap 
> bundle creates the ServiceBackend and creates the proxy using 
> ImplementationDetail service's proxy. Here we can pass the proxy locations 
> of ImplementationDetail.proxy and forClient.proxy bundles. 
> 
> 
> *How to find codebase location of a service proxy?* 
> 
> Before registering the service, we can create an Entry object with code 
> location. This information can be used by any service which will wrap 
> another service proxy. As we know this information, we can create this 
> Entry object. 
> 
> 
> *Codebase information* 
> 
> If we have the below information in the codebase annotation, then 
> RMIClassLoaderSPI can use these information to install or find the correct 
> compatible bundle in the client environment. 
> 
>    - Service API bundle symbolic name, its version and location 
>    - Proxy bundle symbolic name , its version and location 
>    - Third party osgi bundles (libraries), their version and locations 
>    (optional). 
> 
> 
> Even If we annotate the JERI based proxy with service api bundle 
> information, we don't even need to patch the below classes. 
> 
>    1. BasicInvocationDispatcher 
>    2. ServiceDiscoveryManager 
> 
> Because, RMIClassLoaderSPI can find the correct compatible service api 
> bundle in client environment  using codebase annotation. 
> 
> I'll create a POC and will share my experiences. 
> 
> 
> On Tue, Jan 31, 2017 at 10:01 AM, Gregg Wonderly <ge...@cox.net> 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 
> > 
> > > On Jan 30, 2017, at 9:14 AM, Michał Kłeczek (XPro Sp. z o. o.) < 
> > michal.klec...@xpro.biz> wrote: 
> > > 
> > > It looks to me like we are talking past each other. 
> > > 
> > > Thread local resolution context is needed - we both agree on this. 
> > > What we do not agree on is that the context should be a single 
> > ClassLoader. It has to be a set of ClassLoaders to support situations 
> when 
> > dependencies are not hierarchical. 
> > > 
> > > The use case is simple - I want to implement "decorator" services that 
> > provide smart proxies wrapping (smart) proxies of other services. 
> > > I also want to have Exporters provided as dynamic services which would 
> > allow my services to adapt to changing network environment. 
> > > 
> > > And I would like to stress - I am actually quite negative about OSGI 
> > being the right environment for this. 
> > > 
> > > Thanks, 
> > > Michal 
> > > 
> > > Gregg Wonderly wrote: 
> > >> Maybe you can help me out here by explaining how it is that execution 
> > context and class visibility are both handled by OSGi bundles.  For 
> > example, one of my client applications is a desktop environment.  It does 
> > service look up for all services registrations providing a “serviceUI”. 
> It 
> > then integrates all of those services into a desktop view where the UIs 
> are 
> > running at the same time with each one imbedded in a JDesktopPane or a 
> > JTabbedPane or a JFrame or JDialog.  There are callbacks from parts of 
> that 
> > environment into my application which in turn is interacting with the 
> > ServiceUI component.  You have AWT event threads which are calling out, 
> > into the ServiceUIs and lots of other threads of execution which all, 
> > ultimately, must have different class loading environments so that the 
> > ServiceUI components can know where to load code from. 
> > >> 
> > >> It’s exactly TCCL that allows them to know that based on all the other 
> > class loading standards.  The ClassLoader is exactly the thing that all 
> of 
> > them have in common if you include OSGi bundles as well.  The important 
> > detail, is that if the TCCL is not used as new ClassLoaders are created, 
> > then there is no context for those new ClassLoaders to reference, 
> > universally. 
> > >> 
> > >> The important details are: 
> > >> 
> > >>      1) The desktop application has to be able to prefer certain Entry 
> > classes which define details that are presented to the user. 
> > >>      2) When the user double clicks on a services icon, or right 
> clicks 
> > and selects “Open in new Frame”, an async worker thread needs a TCCL 
> > pointing at the correct parent class loader for the service’s 
> > URLClassLoader to reference so that the preferred classes work. 
> > >>      3) Anytime that the AWT Event thread might be active inside of 
> the 
> > services UI implementation, it also needs to indicate the correct parent 
> > class loader if that UI component causes other class loading to occur. 
> > >>      4) I am speaking specifically in the context of deferred class 
> > loading which is controlled outside of the service discovery moment. 
> > >> 
> > >> 
> > >>> On Jan 30, 2017, at 4:04 AM, Michał Kłeczek (XPro Sp. z o. o.) < 
> > michal.klec...@xpro.biz> <mailto:michal.klec...@xpro.biz> wrote: 
> > >>> 
> > >>> What I think Jini designers did not realize is that class loading can 
> > be treated exactly as any other capability provided by a (possibly 
> remote) 
> > service. 
> > >>> Once you realize that - it is possible to provide a kind of a 
> > "universal container infrastructure" where different class loading 
> > implementations may co-exist in a single JVM. 
> > >> 
> > >> That’s precisely what ClassLoader is for.  TCCL is precisely to allow 
> > “some class” to know what context to associate newly loaded classes with, 
> > so that in such an environment, any code can load classes on behalf of 
> some 
> > other code/context.  It doesn’t matter if it is TCCL or some other class 
> > management scheme such as OSGi bundles.  We are talking about the same 
> > detail, just implemented in a different way. 
> > >> 
> > >>> What's more - these class loading implementations may be dynamic 
> > themselves - ie. it is a service that provides the client with a way to 
> > load its own (proxy) classes. 
> > >>> 
> > >>> In other words: "there not enough Jini in Jini itself”. 
> > >> 
> > >> I am not sure I understand where the short coming is at then.  Maybe 
> > you can illustrate with an example where TCCL fails to allow some piece 
> of 
> > code to load classes on behalf of another piece of code? 
> > >> 
> > >> In my desktop application environment, there is a abstract class which 
> > is used by each serviceUI to allow the desktop to know if it provides the 
> > ability to open into one of the above mentioned JComponent subclasses. 
> > That class is preferred and provided and resolved using the codebase of 
> the 
> > desktop client.  That class loading environment is then the place where 
> the 
> > service is finally resolved and classes created so that the proxy can be 
> > handed to the serviceUI component which ultimately only partially 
> resolves 
> > from the services codebase. 
> > >> 
> > >> It’s this class compatibility which needs to be lightweight. 
> > >> 
> > >>> We have _all_ the required pieces in place: 
> > >>> - dynamic code loading and execution (ClassLoaders), 
> > >>> - security model and implementation that allows restricting rights of 
> > the downloaded code, 
> > >>> - and a serialization/deserialization which allows sending arbitrary 
> > data (and yes - code too) over the wire. 
> > >>> 
> > >>> It is just the matter of glueing the pieces together. 
> > >> 
> > >> Correct, but it’s a matter of class compatibility where a client 
> > environment has to interact with a service and the serviceUI components 
> > where TCCL excels and providing the ability to create class loaders with 
> > the correct parent context, for Java based code.  OSGi introduces the 
> > opportunity for some extra bells and whistles.  But I don’t see that it 
> can 
> > completely eliminate the nature of TCCL and how it was intended to be 
> used. 
> > >> 
> > >>> Thanks, 
> > >>> Michal 
> > >>> 
> > >>> 
> > >>> Gregg Wonderly wrote: 
> > >>>> <snip> 
> > >>>> I am not an OSGi user.  I am not trying to be an OSGi opponent. 
> What 
> > I am trying to say is that I consider all the commentary in those 
> articles 
> > about TCCL not working to be just inexperience and argument to try and 
> > justify a different position or interpretation of what the real problem 
> is. 
> > >>>> 
> > >>>> The real problem is that there is not one “module” concept in Java 
> > (another one is almost here in JDK 9/Jigsaw).  No one is working together 
> > on this, and OSGi is solving problems in a small part of the world of 
> > software.   It works well for embedded, static systems.  I think OSGi 
> > misses the mark on dynamic systems because of the piecemeal loading and 
> > resolving of classes.  I am not sure that OSGi developers really 
> understand 
> > everything that Jini can do because of the choices made (and not made) in 
> > the design.  The people who put Jini together had a great deal of years 
> of 
> > experience piecing together systems which needed to work well with a 
> faster 
> > degree of variability and adaptation to the environment then what most 
> > people seem to experience in their classes and work environments which 
> are 
> > locked down by extremely controlled distribution strategies which end up 
> > slowing development in an attempt to control everything that doesn’t 
> > actually cause quality to suffer. 
> > >>>> 
> > >>>> Gregg 
> > >>>> 
> > >>>> 
> > >> 
> > > 
> > 
> > 
> 

Reply via email to