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]
>>>
>
>

Reply via email to