Taking a step back because I'm getting confused... it seems the problem might be as follows.
You (an RSA bundle) want to proxy the org.foo.IFoo, so you need register your service factory against the interface name "org.foo.IFoo". You can't register it using your RSA bundle's own BundleContext because your RSA bundle doesn't import the "org.foo" package, so the framework will see that it is not compatible with the client bundle. As per BJ's checklist for compatibility: "Are the client bundle and the registering bundle (note that in both cases it the bundle context used which established the bundle) wired to the same service type?" I.e, the registering bundle (or rather the bundle whose BundleContext is used to register the service factory) must be *wired* to the service package using Import-Package, which is obviously not true for the RSA bundle. And you can't register using the client's context because the client may not exist yet. It seems you have three options: 1) Use the BC of the API bundle itself, i.e. the bundle that exports package "org.foo". This should work because it will be compatible with any client bundle that imports the package, but it may be confusing for users since the service registration will appear to be coming from the API bundle. 2) Use Service Hooks to detect when a client bundle goes looking for the service, and dynamically register the proxy using the client's own BundleContext. Again possibly confusing because the client will seem to be getting the service from itself! 3) Use the BundleContext of a bundle created on the fly that imports package "org.foo". I hope BJ can confirm that my reasoning is sound. Assuming it is then I would proceed by testing option (1) to ensure it gets rid of the service compatibility problems, then implementing (3) since this appears to be the proper way. My great concern, if this is indeed the Right Way, is that it is much too hard to implement an RSA bundle! Any bundle that wants to provide a new remoting transport is expected to act as an RSA, so ideally it should not require the same level of sophistication as implementing a Topology Manager. Regards Neil On Mon, Feb 21, 2011 at 1:40 AM, Scott Lewis <[email protected]> wrote: > On 2/20/2011 5:12 PM, BJ Hargrave wrote: > >> What we are currently doing to solve this (which is hinted at in >> 122.5.6) is to register a ServiceFactory for proxy creation...and >> then when a given client bundle first requests access to a proxy, >> the ServiceFactory.getService method is called by the framework...i.e. >> >> Could our problem be because of the use of a ServiceFactory at all? > > No. There are 2 checks: > > 1) Are the client bundle and the registering bundle (note that in both cases > it the bundle context used which established the bundle) wired to the same > service type? > > In the case of RSA's registration of a ServiceFactory (for creating proxies > of a remote service), the service type (Class) is not even loaded. It's > only actually loaded when the ServiceFactory.getService(Bundle...) is called > later. So in this case, how can the framework compare the types (since no > Classes have actually been loaded at this point)? > > > If (1) passes then the client bundle will see the service and can request > the service object. If the service object is a service factory, then the > framework will request the factory to manufacture the service object. > > 2) The service object manufactured by the factory must be an instanceof all > the types under which the service was originally registered. > >> I notice that when I use ServiceTracker.open() none of our >> ServiceFactory.getService code is even *called* (and so no proxy >> service classes are even *loaded*). > > This is because check (1) is failing. > > Right. But given that a ServiceFactory is registered (by the distribution > system on RSA.importService), and the service types haven't been loaded, how > could/should it pass? > > >> So it seems that the class >> compatibility check that's going on must be somehow based upon the >> ServiceFactory instance...and it's failing that check simply because >> it's a service factory (and not because of actual class >> incompatibility...as the service interface class hasn't even been >> loaded via the ServiceFactory.getService call). >> >> Shouldn't ServiceFactorys be treated specially WRT the class >> compatibility check that's going on in the framework? (since they >> don't implement the service interfaces at all)? Or if this is >> expected for ServiceFactorys...does this make it impossible to use a >> ServiceFactory/this approach for ensuring class compatibility? If >> the latter (this approach won't work) it would be good to remove >> some of the prose suggesting this approach for achieving proxy >> service class compatibility from 122.5.6. > > It is generally assumed that the bundle which registered the service is also > the same bundle which implements the service factory. So if the client > bundle and the registering bundle are wired to the same service types (check > (1)), then the factory (assuming check (2) passes) will be using the types > which are the proper types for the client. > > But in this case (RSA.importService) I think that assumption is > violated...because the bundle that implements the service factory (RSA impl) > is not the same bundle that registered the service (i.e. the topology > manager impl...i.e. org.eclipse.ecf.osgi.services.distribution). > > > RSA impls are a special beast. So they have to be more careful. > > I see that :). > > > I think this all comes down to what bundle's context is used to register the > service? Is that bundle wired to the same service type as the client bundle? > > Right...but I guess I don't understand who any/either bundle can be wired to > the service type...since with a ServiceFactory the service type classes > haven't even been necessarily loaded. I understand in the typical (local) > case the service classes have at least been loaded prior to the > ServiceFactory registration, but in this case/RSA they haven't been. > > I suppose that prior to the proxy ServiceFactory registration, I could load > the service type classes by the topology manager bundle...would that allow > the necessary checks to succeed? > > Thanks, > > Scott > > > _______________________________________________ > OSGi Developer Mail List > [email protected] > https://mail.osgi.org/mailman/listinfo/osgi-dev > _______________________________________________ OSGi Developer Mail List [email protected] https://mail.osgi.org/mailman/listinfo/osgi-dev
