You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@aries.apache.org by Kirk Knoernschild <pr...@kirkk.com> on 2010/08/26 17:17:16 UTC

Spring DM/Blueprint Services

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





Re: Spring DM/Blueprint Services

Posted by Kirk Knoernschild <pr...@kirkk.com>.
thanx all for your insight on this one. I've tried a few different solutions, including the one from Tim, except I wasn't able to get the listener methods to invoke. I'll have to keep working on that one.

In the end, I kept the Interface1 service but handle the injection of the Interface2 instances programmatically. It works, though doesn't offer the level of flexibility I'd prefer and exposes an API that isn't as clean.

I intend to keep exploring with alternative designs until I find the one that fits best. When I do, I'll let folks know what I've come up with.

If anyone is interested in the code, let me know. It's on github.

Kirk Knoernschild
http://www.kirkk.com
http://techdistrict.kirkk.com
http://planet.kirkk.com
twitter: pragkirk




On Aug 27, 2010, at Aug 27, 5:41 AM, Alasdair Nottingham wrote:

> We could do it only when the service properties are explicitly listed
> as primitives in the blueprint. So if you include more complex
> properties it wouldn't work. Matching shouldn't be a problem because
> we can use the Filter class in OSGi.
> 
> The only catch would be whether the CT has a test for this scenario or not.
> 
> Alasdair
> 
> On 27 August 2010 11:27, Guillaume Nodet <gn...@gmail.com> wrote:
>> I think the spec says it's a programming error from the user, but i
>> don't think it requires the implementation to throw any exception.
>> I don't see why we could not enhance the aries blueprint
>> implementation to support such a use case.  This would require to
>> perform some kind of matching before the grace period to ignore
>> references that could be satisfied by exported services.  However,
>> this may not be possible by only looking at the metadata, as the
>> reference could have a filter that would have to be matched against
>> properties (which could be beans ...).
>> 
>> On Fri, Aug 27, 2010 at 11:26, Alasdair Nottingham <no...@apache.org> wrote:
>>> My personal view is that a blueprint should be able to reference a
>>> service it defines, however not to support the scenario you describe.
>>> I think it should be supported to allow flexibility in refactoring, so
>>> you can easily merge and split bundles. Alas the alliance disagrees.
>>> 
>>> The defaulting scenario you describe doesn't really work in blueprint
>>> because of the way service damping works. It will select an
>>> implementation and then use it until it goes away. In your case should
>>> it select the default it will never go away until the blueprint bundle
>>> goes away. The only way to make this work would be to ensure that the
>>> bundle with Interface2Impl2 in it is installed and processed by
>>> blueprint first. This introduces an ordering constraint which given we
>>> are in OSGi is, I think, a design flaw.
>>> 
>>> That said it sucks that to make your scenario work the code is so yucky.
>>> 
>>> Alasdair
>>> 
>>> On 26 August 2010 18:37, Kirk Knoernschild <pr...@kirkk.com> 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 <no...@apache.org> 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 <pr...@kirkk.com> 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
>>>>>> not@apache.org
>>>>>> 
>>>> 
>>>> 
>>> 
>>> 
>>> 
>>> --
>>> Alasdair Nottingham
>>> not@apache.org
>>> 
>> 
>> 
>> 
>> --
>> Cheers,
>> Guillaume Nodet
>> ------------------------
>> Blog: http://gnodet.blogspot.com/
>> ------------------------
>> Open Source SOA
>> http://fusesource.com
>> 
> 
> 
> 
> -- 
> Alasdair Nottingham
> not@apache.org


Re: Spring DM/Blueprint Services

Posted by Alasdair Nottingham <no...@apache.org>.
We could do it only when the service properties are explicitly listed
as primitives in the blueprint. So if you include more complex
properties it wouldn't work. Matching shouldn't be a problem because
we can use the Filter class in OSGi.

The only catch would be whether the CT has a test for this scenario or not.

Alasdair

On 27 August 2010 11:27, Guillaume Nodet <gn...@gmail.com> wrote:
> I think the spec says it's a programming error from the user, but i
> don't think it requires the implementation to throw any exception.
> I don't see why we could not enhance the aries blueprint
> implementation to support such a use case.  This would require to
> perform some kind of matching before the grace period to ignore
> references that could be satisfied by exported services.  However,
> this may not be possible by only looking at the metadata, as the
> reference could have a filter that would have to be matched against
> properties (which could be beans ...).
>
> On Fri, Aug 27, 2010 at 11:26, Alasdair Nottingham <no...@apache.org> wrote:
>> My personal view is that a blueprint should be able to reference a
>> service it defines, however not to support the scenario you describe.
>> I think it should be supported to allow flexibility in refactoring, so
>> you can easily merge and split bundles. Alas the alliance disagrees.
>>
>> The defaulting scenario you describe doesn't really work in blueprint
>> because of the way service damping works. It will select an
>> implementation and then use it until it goes away. In your case should
>> it select the default it will never go away until the blueprint bundle
>> goes away. The only way to make this work would be to ensure that the
>> bundle with Interface2Impl2 in it is installed and processed by
>> blueprint first. This introduces an ordering constraint which given we
>> are in OSGi is, I think, a design flaw.
>>
>> That said it sucks that to make your scenario work the code is so yucky.
>>
>> Alasdair
>>
>> On 26 August 2010 18:37, Kirk Knoernschild <pr...@kirkk.com> 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 <no...@apache.org> 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 <pr...@kirkk.com> 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
>>>>> not@apache.org
>>>>>
>>>
>>>
>>
>>
>>
>> --
>> Alasdair Nottingham
>> not@apache.org
>>
>
>
>
> --
> Cheers,
> Guillaume Nodet
> ------------------------
> Blog: http://gnodet.blogspot.com/
> ------------------------
> Open Source SOA
> http://fusesource.com
>



-- 
Alasdair Nottingham
not@apache.org

Re: Spring DM/Blueprint Services

Posted by Guillaume Nodet <gn...@gmail.com>.
I think the spec says it's a programming error from the user, but i
don't think it requires the implementation to throw any exception.
I don't see why we could not enhance the aries blueprint
implementation to support such a use case.  This would require to
perform some kind of matching before the grace period to ignore
references that could be satisfied by exported services.  However,
this may not be possible by only looking at the metadata, as the
reference could have a filter that would have to be matched against
properties (which could be beans ...).

On Fri, Aug 27, 2010 at 11:26, Alasdair Nottingham <no...@apache.org> wrote:
> My personal view is that a blueprint should be able to reference a
> service it defines, however not to support the scenario you describe.
> I think it should be supported to allow flexibility in refactoring, so
> you can easily merge and split bundles. Alas the alliance disagrees.
>
> The defaulting scenario you describe doesn't really work in blueprint
> because of the way service damping works. It will select an
> implementation and then use it until it goes away. In your case should
> it select the default it will never go away until the blueprint bundle
> goes away. The only way to make this work would be to ensure that the
> bundle with Interface2Impl2 in it is installed and processed by
> blueprint first. This introduces an ordering constraint which given we
> are in OSGi is, I think, a design flaw.
>
> That said it sucks that to make your scenario work the code is so yucky.
>
> Alasdair
>
> On 26 August 2010 18:37, Kirk Knoernschild <pr...@kirkk.com> 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 <no...@apache.org> 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 <pr...@kirkk.com> 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
>>>> not@apache.org
>>>>
>>
>>
>
>
>
> --
> Alasdair Nottingham
> not@apache.org
>



-- 
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com

Re: Spring DM/Blueprint Services

Posted by Alasdair Nottingham <no...@apache.org>.
My personal view is that a blueprint should be able to reference a
service it defines, however not to support the scenario you describe.
I think it should be supported to allow flexibility in refactoring, so
you can easily merge and split bundles. Alas the alliance disagrees.

The defaulting scenario you describe doesn't really work in blueprint
because of the way service damping works. It will select an
implementation and then use it until it goes away. In your case should
it select the default it will never go away until the blueprint bundle
goes away. The only way to make this work would be to ensure that the
bundle with Interface2Impl2 in it is installed and processed by
blueprint first. This introduces an ordering constraint which given we
are in OSGi is, I think, a design flaw.

That said it sucks that to make your scenario work the code is so yucky.

Alasdair

On 26 August 2010 18:37, Kirk Knoernschild <pr...@kirkk.com> 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 <no...@apache.org> 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 <pr...@kirkk.com> 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
>>> not@apache.org
>>>
>
>



-- 
Alasdair Nottingham
not@apache.org

Re: Spring DM/Blueprint Services

Posted by Justin Edelson <ju...@justinedelson.com>.
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 <pr...@kirkk.com> 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 <no...@apache.org> 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 <pr...@kirkk.com> 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
>>> not@apache.org
>>>
>
>

RE: Spring DM/Blueprint Services

Posted by Timothy Ward <ti...@hotmail.com>.

Kirk,

You could try something like the following, which I'll try to keep as brief as possible:


<blueprint....>

<bean id="defaultImpl" class=..../>

<service ref="defaultImpl" interface="IFace1"/>

<reference id="updatedImpl" availability="optional" interface="IFace1">
   <reference-listener bind-method=”available” unbind-method=”unavailable” ref="usingBean">
</reference>

<bean id="usingBean" class=....>
  <property name="defaultService" ref="defaultImpl"/>
  <property name="overrideService" ref="updatedImpl"/>
</bean>

</blueprint>


Using the above xml, a bundle will export a service using IFace1, and optionally consume a service using IFace1. The "usingBean" will have the implementation bean for the default service injected and an override service proxy.

When the proxy is bound to a backing service the "usingBean" will have the available(IFace1 svc) method driven (there are some other allowable signatures too). This will allow the "usingBean" to use the injected override service until such time as:

a) available is driven again, indicating that the original override service has been unregistered and has been transparently replaced with a new service, no action is necessary

b) unavailable(IFace1 svc) is driven, indicating that the override service has been unregistered and no replacement is available, at this point the default implementaion should be used again.


This is a reasonably simple model, which avoids some of the lifecycle issues around trying to expose a service that needs to consume itself. I hope it is useful to you.

Regards,

Tim


----------------------------------------
> Subject: Re: Spring DM/Blueprint Services
> From: pragkirk@kirkk.com
> Date: Thu, 26 Aug 2010 12:56:15 -0500
> To: aries-user@incubator.apache.org
>
> Tim,
>
> That is an alternative solution I tried. But I didn't use a listener and so it had a pretty bad smell.
>
> Essentially what I did was that when Bundle C started, it got a reference to the Interface2 service that was backed by the Interface2Impl2 class and I injected that into the client which it turned called the set method on the Interface1 service. That just didn't seem right.
>
> Is there a way to use the listener approach you describe below and swap out the default implementation bean (Interface2Impl1) with the service (Interface2Impl2) via blueprint configuration? Or at least create a listener class that gets invoked when the Interface2 service backed by Interface2Impl2 is registered, but where the listener class is not dependent on the OSGi framework?
>
> Kirk Knoernschild
> http://www.kirkk.com
> http://techdistrict.kirkk.com
> http://planet.kirkk.com
> twitter: pragkirk
>
>
>
>
> On Aug 26, 2010, at Aug 26, 12:43 PM, Timothy Ward wrote:
>
>>
>> I would like to ask, why would you expose a service to provide a default implementation within a bundle? The default implementation bean can be wired in directly using blueprint, and a listener can be used to switch in the optional "replacement service" if it becomes available. The default service can still be exposed in the service registry for use by other bundles.
>>
>> Regards,
>>
>> Tim
>>
>> ----------------------------------------
>>> Subject: Re: Spring DM/Blueprint Services
>>> From: pragkirk@kirkk.com
>>> Date: Thu, 26 Aug 2010 12:37:53 -0500
>>> To: aries-user@incubator.apache.org
>>>
>>> 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 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:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> id="bean1">
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> availability="optional">
>>>>>
>>>>>
>>>>>
>>>>> 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 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
>>>>> not@apache.org
>>>>>
>>>
>>
>
 		 	   		  

Re: Spring DM/Blueprint Services

Posted by Kirk Knoernschild <pr...@kirkk.com>.
Tim,

That is an alternative solution I tried. But I didn't use a listener and so it had a pretty bad smell.

Essentially what I did was that when Bundle C started, it got a reference to the Interface2 service that was backed by the Interface2Impl2 class and I injected that into the client which it turned called the set method on the Interface1 service. That just didn't seem right.

Is there a way to use the listener approach you describe below and swap out the default implementation bean (Interface2Impl1) with the service (Interface2Impl2) via blueprint configuration? Or at least create a listener class that gets invoked when the Interface2 service backed by Interface2Impl2 is registered, but where the listener class is not dependent on the OSGi framework?

Kirk Knoernschild
http://www.kirkk.com
http://techdistrict.kirkk.com
http://planet.kirkk.com
twitter: pragkirk




On Aug 26, 2010, at Aug 26, 12:43 PM, Timothy Ward wrote:

> 
> I would like to ask, why would you expose a service to provide a default implementation within a bundle? The default implementation bean can be wired in directly using blueprint, and a listener can be used to switch in the optional "replacement service" if it becomes available. The default service can still be exposed in the service registry for use by other bundles.
> 
> Regards,
> 
> Tim
> 
> ----------------------------------------
>> Subject: Re: Spring DM/Blueprint Services
>> From: pragkirk@kirkk.com
>> Date: Thu, 26 Aug 2010 12:37:53 -0500
>> To: aries-user@incubator.apache.org
>> 
>> 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  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:
>>>> 
>>>> 
>>>> 
>>>> 
>>>> id="bean1">
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> 
>>>> availability="optional">
>>>> 
>>>> 
>>>> 
>>>> 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  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
>>>> not@apache.org
>>>> 
>> 
> 		 	   		  


RE: Spring DM/Blueprint Services

Posted by Timothy Ward <ti...@hotmail.com>.
I would like to ask, why would you expose a service to provide a default implementation within a bundle? The default implementation bean can be wired in directly using blueprint, and a listener can be used to switch in the optional "replacement service" if it becomes available. The default service can still be exposed in the service registry for use by other bundles.

Regards,

Tim

----------------------------------------
> Subject: Re: Spring DM/Blueprint Services
> From: pragkirk@kirkk.com
> Date: Thu, 26 Aug 2010 12:37:53 -0500
> To: aries-user@incubator.apache.org
>
> 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  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:
>>>
>>> 
>>> 
>>> 
>>> id="bean1">
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> availability="optional">
>>> 
>>> 
>>>
>>> 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  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
>>> not@apache.org
>>>
>
 		 	   		  

Re: Spring DM/Blueprint Services

Posted by Kirk Knoernschild <pr...@kirkk.com>.
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 <no...@apache.org> 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 <pr...@kirkk.com> 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
>> not@apache.org
>> 


Re: Spring DM/Blueprint Services

Posted by Mark Nuttall <mn...@apache.org>.
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 <no...@apache.org> 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 <pr...@kirkk.com> 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
> not@apache.org
>

Re: Spring DM/Blueprint Services

Posted by Kirk Knoernschild <pr...@kirkk.com>.
Purportedly Spring DM allows it if it's declared as optional when using the cardinality property. Alas, it did not work for me.

Kirk Knoernschild
http://www.kirkk.com
http://techdistrict.kirkk.com
http://planet.kirkk.com
twitter: pragkirk




On Aug 26, 2010, at Aug 26, 11:26 AM, Alasdair Nottingham 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 <pr...@kirkk.com> 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
> not@apache.org


Re: Spring DM/Blueprint Services

Posted by Alasdair Nottingham <no...@apache.org>.
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 <pr...@kirkk.com> 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
not@apache.org