I'm not sure if this counts as an "alternate solution" in your eyes, but OSGi Declarative Services can do what you are describing.
Justin On Thu, Aug 26, 2010 at 1:37 PM, Kirk Knoernschild <[email protected]> wrote: > Ah yes. The same phrase is found in the Spring DM documentation, and now I > see it's also in the blueprint spec. Thank you for pointing that out. > > So in general, my design below is not supported. However, I don't perceive it > as a design flaw. > > It seems reasonable that a bundle would define a default implementation for > one of it's services where that service is also used by that bundle. It also > seems reasonable that I might want to change the implementation at runtime so > that the bundle now uses a different implementation of that service. I can > easily do that if I separate it all out into separate bundles. > > Like this: > Bundle A - Interface1, Interface1Impl (uses Interface2 service) > Bundle A1- Interface2, Interface2Impl1 > Bundle A2 - Interface2Impl2 > > Bundle C - uses Interface1service > > Upon deploying Bundle A and Bundle A1, Bundle C will use Interface1 with the > default Interface2Impl1 that backs Interface2. I can stop Bundle A1, deploy > and start Bundle A2 and now Bundle C uses Interface1 with the new > Interface2Impl2 that backs Interface2. Works fine. > > However, if I eliminate Bundle A1 and put those classes in Bundle A, it > doesn't work. Foremost, it doesn't work because the spec doesn't allow it. > But also, since the service lifecycle is tied to the bundle lifecycle, I > suppose I wouldn't be able to easily substitute Interface1Impl1 with > Interface2Impl2. But that is what I would prefer because the approach that > works seem to cause an unnecessary proliferation of bundles. > > At least, that is what I'm seeing. Which is why I'm wondering if I'm missing > an alternative solution. > > Kirk Knoernschild > http://www.kirkk.com > http://techdistrict.kirkk.com > http://planet.kirkk.com > twitter: pragkirk > > > > > On Aug 26, 2010, at Aug 26, 11:40 AM, Mark Nuttall wrote: > >> Enterprise 4.2 spec, section 121.7.9: >> >> "It is an error to declare a mandatory reference to a service that is >> registered by the same bundle. Such >> a definition could cause either deadlock or a timeout." >> >> Regards, >> Mark >> >> On 26 August 2010 17:26, Alasdair Nottingham <[email protected]> wrote: >>> Hi, >>> >>> I can't comment on Spring DM, because I don't have any experience >>> there, but if you use blueprint it can be possible if you define the >>> reference to have an optional availability for example: >>> >>> <?xml version="1.0" encoding="UTF-8"?> >>> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> >>> <bean class="privatepackage.Interface1Impl" init-method="init" >>> id="bean1"> >>> <property name="thing" ref="ref1"></property> >>> </bean> >>> <bean class="privatepackage.Interface2Impl" id="bean2"></bean> >>> <service ref="bean1" interface="publicpackage.Interface1"></service> >>> <service ref="bean2" interface="publicpackage.Interface2"></service> >>> <reference id="ref1" interface="publicpackage.Interface2" >>> availability="optional"> >>> </reference> >>> </blueprint> >>> >>> Having run this through the init method of Interface1Impl has the >>> reference injected by the time it is called, but of course this isn't >>> necessarily safe to assume. >>> >>> I'm going to head back to the blueprint spec to see if this cycle is >>> prohibited from working for a mandatory reference, but if it isn't >>> I'll raise a JIRA to allow this type of cycle. >>> >>> Alasdair >>> >>> On 26 August 2010 16:17, Kirk Knoernschild <[email protected]> wrote: >>>> I've been using Spring DM, and one thing that I'm struggling with is that >>>> a bundle that exports a service is unable to use that service. This seems >>>> to be a feasible design option, and I'm wondering what others have done to >>>> work around it. >>>> >>>> For instance, let's say I have three bundles. >>>> >>>> BundleA with Interface1, Interface2, Interface1Impl, and Interface2Impl1. >>>> BundleB with Interface2Impl2 >>>> BundleC with ClassC that uses Interface1. >>>> >>>> On start, BundleA registers two new services Interface1Service and >>>> Interface2Service, using Interface1Impl and Interface2Impl1 as their >>>> implementations, respectively. As it happens, the Interface1Impl requires >>>> an Interface2 type, so using Spring DM, I've tried injecting the >>>> Interface2 service into the Interface1 service. It doesn't work because >>>> Spring DM doesn't allow a bundle to use a service it registers, so I >>>> inject it as a regular bean. >>>> >>>> I want to do this because I install BundleB and register another >>>> Interface2Service service, now using Interface2Impl2. Because I cannot >>>> inject the service backed by Interface2Impl1 into the service backed by >>>> Interface1Impl, the service backed by Interface1Impl won't be able to use >>>> Interface2Impl2. >>>> >>>> FWIW, I can move Interface2 and Interface2Impl1 to a separate bundle and >>>> register it as a service. That does work, but it's not the application >>>> structure I want. >>>> >>>> Possibly there is an alternative design to this that is more suitable to >>>> this situation. I'm just not sure what that is at this point. Any >>>> suggestions are appreciated. >>>> >>>> I can send code if it would be helpful to illustrate this. >>>> >>>> Kirk Knoernschild >>>> http://www.kirkk.com >>>> http://techdistrict.kirkk.com >>>> http://planet.kirkk.com >>>> twitter: pragkirk >>>> >>>> >>>> >>>> >>>> >>> >>> >>> >>> -- >>> Alasdair Nottingham >>> [email protected] >>> > >
