You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Simon Kitching <si...@vonos.net> on 2015/05/21 16:52:44 UTC

DependencyManager and bundle-private components

Hi,

In blueprint it is possible to define arbitrary objects (beans) which 
are not published to the service registry but nevertheless can be 
injected into other beans.

AFAICT, in both declarative-services and felix-dm, the only objects that 
can be injected are references to services from the OSGi registry. Is 
this correct?

I understand that with DS and DM, components follow the standard OSGi 
lifecycles, in contrast to the Blueprint approach of "hiding" the 
lifecycle. In particular, in DS and DM when a component's mandatory 
dependency is deregistered then the component is also deregistered 
(which can cascade further). And the kind of tracking of dependencies 
required to make this happen is exactly what a service registry does.

However it's common for a bundle to have objects which are purely 
internal implementation details of the bundle, and are not for external 
use. Yet as far as I can see, in order to manage them with DS or DM, 
such internal objects need to be published into the global service 
registry - just to be able to then inject them back into components in 
the same bundle.

Have I misunderstood something?

Thanks,
Simon

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: DependencyManager and bundle-private components

Posted by Raymond Auge <ra...@liferay.com>.
I have to agree with Neil, but I have a variation to suggest.

Traditional DI/IOC containers are fundamentally static singletons and
should be treated as such.

That being the case, continue to use "spring" or "guice" or whatnot inside
your bundle.

However, associate it with any single DS component which acts as it's
controller. This already happens in every use case of those frameworks to
date.

- whenever you use spring, guice, CDI or whatever there is one single
moment when suddenly the entire context is ready, just like if you
instantiated a single class. Destruction is the same (in fact these are
almost always implemented as a huge synchronized operation).

The technique I'm suggesting allows you to still "benefit" from isolated
internal wiring, while also benefiting from services around it's outer
edges.

But don't expect the wiring to suddenly be "dynamic" because it obviously
will never be. When the controller DS component can no longer be satisfied
then you must tear it down which is exactly what you'd have to do outside
osgi anyway.

FYI, this should be extremely simple to do as a DS component (spring
example):

(never tried any of this, but in theory...)

-  create a DS component that extends
org.springframework.context.annotation.AnnotationConfigApplicationContext
- which calls it's scan(packages) method during @Activate
- but first it could create an ApplicationContext from all it's @Reference
"beans" and set it as the parent context
- call refresh()
- the main context is now ready
- publish any "beans" matching whatever logic you please as services
- reverse the process on @Deactivate

Repeat this pattern for any traditional DI/IOC container.

Thinking about it, you could even gain some dynamics in your beans if you
have for instance a managed collection using a complex dynamic reference
like:

    @Reference(
        cardinality = ReferenceCardinality.MULTIPLE,
        policy = ReferencePolicy.DYNAMIC,
        policyOption = ReferencePolicyOption.GREEDY
    )
    protected void setSomething(Something something) {
        this.somethings.add(something);
    }

    private final Collection<Something> somethings = new
CopyOnWriteArrayList<>();

and just supply the collection as a bean (wrapped in unmodifiable) in the
parent context.

Almost sounds reasonable.

- Ray



On Thu, May 21, 2015 at 11:28 AM, Neil Bartlett <nj...@gmail.com>
wrote:

> Hi Simon,
>
> You’re essentially correct, at least in the difference between Blueprint
> and DS. I can’t comment on DM since I don’t use it. However the wording of
> your email implies that this is a failing of DS and a win for Blueprint,
> whereas I tend to see it as the exact opposite!
>
> For me, Blueprint does not successfully hide the OSGi lifecycle but adds
> an additional lifecycle within the OSGi one. For example, Blueprint
> containers cannot be activated until all of the mandatory references within
> the container are satisfied… but there can be beans in the container that
> are fully satisfied because they do not need the unsatisfied references.
> Why not start just those beans? It doesn’t make sense. Still, if that is
> the Blueprint policy then you would at least expect it to be consistent, so
> that when a mandatory reference from an active container becomes
> unsatisfied, the container will be deactivated. But Blueprint doesn’t
> actually do this, it merely puts the container into a kind of suspended
> state. Again it doesn’t make sense.
>
> Well actually it makes sense when you realise that Blueprint represents a
> legacy container concept that has been crowbarred to fit into OSGi…
>
> Regarding your last point; you are right that components (beans if you
> prefer) often need to use other objects from within the bundle, and those
> objects should not escape from the bundle. In DS I find it perfectly
> acceptable to instantiate these components with the “new” keyword. I don’t
> really see why I would want to use a type-unsafe XML descriptor to do this
> rather than Java code.
>
> Regards,
> Neil
>
> > On 21 May 2015, at 15:52, Simon Kitching <si...@vonos.net> wrote:
> >
> > Hi,
> >
> > In blueprint it is possible to define arbitrary objects (beans) which
> are not published to the service registry but nevertheless can be injected
> into other beans.
> >
> > AFAICT, in both declarative-services and felix-dm, the only objects that
> can be injected are references to services from the OSGi registry. Is this
> correct?
> >
> > I understand that with DS and DM, components follow the standard OSGi
> lifecycles, in contrast to the Blueprint approach of "hiding" the
> lifecycle. In particular, in DS and DM when a component's mandatory
> dependency is deregistered then the component is also deregistered (which
> can cascade further). And the kind of tracking of dependencies required to
> make this happen is exactly what a service registry does.
> >
> > However it's common for a bundle to have objects which are purely
> internal implementation details of the bundle, and are not for external
> use. Yet as far as I can see, in order to manage them with DS or DM, such
> internal objects need to be published into the global service registry -
> just to be able to then inject them back into components in the same bundle.
> >
> > Have I misunderstood something?
> >
> > Thanks,
> > Simon
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> > For additional commands, e-mail: users-help@felix.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>


-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)

Re: DependencyManager and bundle-private components

Posted by Neil Bartlett <nj...@gmail.com>.
Hi Simon,

You’re essentially correct, at least in the difference between Blueprint and DS. I can’t comment on DM since I don’t use it. However the wording of your email implies that this is a failing of DS and a win for Blueprint, whereas I tend to see it as the exact opposite!

For me, Blueprint does not successfully hide the OSGi lifecycle but adds an additional lifecycle within the OSGi one. For example, Blueprint containers cannot be activated until all of the mandatory references within the container are satisfied… but there can be beans in the container that are fully satisfied because they do not need the unsatisfied references. Why not start just those beans? It doesn’t make sense. Still, if that is the Blueprint policy then you would at least expect it to be consistent, so that when a mandatory reference from an active container becomes unsatisfied, the container will be deactivated. But Blueprint doesn’t actually do this, it merely puts the container into a kind of suspended state. Again it doesn’t make sense.

Well actually it makes sense when you realise that Blueprint represents a legacy container concept that has been crowbarred to fit into OSGi…

Regarding your last point; you are right that components (beans if you prefer) often need to use other objects from within the bundle, and those objects should not escape from the bundle. In DS I find it perfectly acceptable to instantiate these components with the “new” keyword. I don’t really see why I would want to use a type-unsafe XML descriptor to do this rather than Java code.

Regards,
Neil

> On 21 May 2015, at 15:52, Simon Kitching <si...@vonos.net> wrote:
> 
> Hi,
> 
> In blueprint it is possible to define arbitrary objects (beans) which are not published to the service registry but nevertheless can be injected into other beans.
> 
> AFAICT, in both declarative-services and felix-dm, the only objects that can be injected are references to services from the OSGi registry. Is this correct?
> 
> I understand that with DS and DM, components follow the standard OSGi lifecycles, in contrast to the Blueprint approach of "hiding" the lifecycle. In particular, in DS and DM when a component's mandatory dependency is deregistered then the component is also deregistered (which can cascade further). And the kind of tracking of dependencies required to make this happen is exactly what a service registry does.
> 
> However it's common for a bundle to have objects which are purely internal implementation details of the bundle, and are not for external use. Yet as far as I can see, in order to manage them with DS or DM, such internal objects need to be published into the global service registry - just to be able to then inject them back into components in the same bundle.
> 
> Have I misunderstood something?
> 
> Thanks,
> Simon
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: DependencyManager and bundle-private components

Posted by Neil Bartlett <nj...@gmail.com>.
> On 22 May 2015, at 09:12, Simon Kitching <si...@vonos.net> wrote:
> 
> Thanks Pierre and Neil for your replies!
> 
> To avoid splitting this thread, I'll also reply to Neil's email here.
> 
> I agree with Neil completely about the Blueprint lifecycle (ugly). I much prefer the DS lifecycle management - but miss the ability in DS or DM to manage bundle-private objects. I find it interesting that OSGi has solved the problem of a global class namespace (via Export-Package), but has then created a single global service namespace.
> 
> Regarding the use of "new":
> 
> (a) It would be nice to share code between OSGi and non-OSGi environments. In non-OSGi environments, use of dependency injection (rather than explicit use of new) is wide-spread.
> 
> Do you not have problems when trying to share code between OSGi and non-OSGi environments?

No. Declarative Services components are POJOs and follow the traditional JavaBeans get/set/add/remove method pattern, so they can easily be integrated in non-OSGi code and with DI frameworks like Spring.

> 
> (b) DI isn't usually used to inject things that can be created with "new". Instead, it is predominantly used to inject singleton objects that are used by many other objects. As an example, a common _cache_ may be injected, or a serialization-helper. The alternative to DI in this case is not "new", but instead the old "static singleton" pattern, or lookup via JNDI or similar. Or to retrieve the object from the OSGi service registry - but that leads to "polluting" of the global service registry which I am concerned about.
> 
> Do you not have problems when sharing a "bundle-private" object between multiple DS-managed objects?

It sounds like you’re talking about some kind of common initialisation for the bundle before each component is started. For this I use the “gatekeeper” pattern, where you have all but one of the DS components initially disabled, and the one enabled component performs common initialisation and then starts the other components.

I almost never need to use static singletons, indeed I avoid them because they couple my program state to the classloader, which is completely unpredictable. You also mention JNDI, which is really just an alternative service registry, and the proper way to deal with this is to build an adapter between the two registries. 

> 
> (c) One major motivation for using DI is to support unit testing. When a class uses DI properly, then a unit test can instantiate that class with mocks for the various other objects it interacts with. The test can then verify that the class under test interacts with mock objects as expected. It can also emulate various failures in the mocked systems, eg returning error-codes or throwing exceptions. When a class uses "new" to instantiate a helper object, no mocking of the external class is possible.
> 
> When you use "new" in your code, does this not cause you problems with unit test coverage?

No, but it depends on your definition of unit testing, specifically what you consider to be a “unit”. I do NOT consider a single class to be a unit that must be tested in isolation of all other classes, as in my experience this leads to very inflexible code, because any tiny change in the layout of your classes breaks almost all of your tests. Instead I consider Components to be my units, which maps to a cluster of classes within the bundle.

> 
> Because of the above, I don't currently see using "new" as an alternative to DI for wiring up objects inside a bundle.

And I don’t see DI as an alternative for “new” ;-)

DI is most useful where you anticipate the need to provide an alternative implementation of a dependency, even if only for testing purposes. Since we’re talking about the internals of a bundle, there should never be an alternative implementation, and in fact the code depends on getting exactly the implementation it expects.

- Neil

> 
> Pierre, many thanks for your very detailed reply.
> 
> Re link to iPojo - that's next on my list of things to investigate; I've been using spring-dm, blueprint and felix-dm up to now but haven't yet taken time to investigate ipojo. And thanks for link [1] - Christian Schneider is asking exactly the same question as I am, in Feb 2014. Sadly Felix Meshberger's reply is clear : not supported in DS. I don't yet understand why some people think this is important (Christian, myself for example) while others don't. See https://mail.osgi.org/pipermail/osgi-dev/2014-February/004295.html and the followup emails.
> 
> The Felix-DM CompositionManager example you linked to looks very interesting, thanks. Unfortunately javadoc for "Component.setComposition" is pretty unhelpful. As far as I can tell, the "composition" feature allows a developer to define in DM:
> * a single Component
> * with all the dependencies that need to be injected into it
> except that
> * instead of DM instantiating a single object when the dependencies are met, it invokes a factory method that returns a collection of objects, and
> * instead of injection of these dependencies being performed on a single object, it is performed on the collection of objects
> Have I understood? If so, that is interesting but not AFAICT what I am looking for.
> 
> While searching for info on "composition", I came across http://de.slideshare.net/mfrancis/the-ultimate-dependency-manager-shoot-out-x-uiterlinden-s-mak . In particular, slide 19 talks about support in ipojo for "intra-bundle mechanism" and "scoped service registry" which look exactly like what I am missing in DS. Sadly, the topic isn't mentioned again in the slideshow. However searching for those terms led me to this page:
> * http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/ipojo-composition-tutorial.html
> 
> And this section from the ipojo "composition" documentation (which appears to be not related to the felix-dm composition feature) is exactly what I think is missing from DS/DM:
> > OSGi defines only one service registry, accessible by any bundles. iPOJO splits these two interaction types. Instances receive an iPOJO Bundle
> > Context delegating bundle-related methods to the "regular" bundle context, and service-related methods to a service context. This service context
> > can access to the OSGi service registry or to a new one. Each composition instances have a service registry.
> 
> I'm not so concerned about "too many services in the registry" as I am about *bundle-private* services being present in the global registry.
> 
> Do you see any reason why DM and DS could not adopt the same approach as iPojo, ie a per-composition (or at least per-bundle) service registry? I could imagine the following enhancement for DS:
>  <component>
>    <service>
>      <provide interface="..." scope="local"/>
> where the new "scope" attribute indicates that this particular component should be placed into the per-bundle service registry rather than the global one. All <reference> elements would then look first in the per-bundle registry before looking in the global one.
> 
> For DM, something similar could be done with:
>  createComponent().setInterface("..", Scope.LOCAL)
> 
> Maybe another solution is to take advantage of felix-dm's ability to define "dependency handlers", and add another kind of dependency called "local" or similar? [as suggested by Karl Pauls in the email pointed out by Pierre]
> 
> All opinions gratefully accepted!
> 
> Regards, Simon
> 
> On 05/22/2015 08:34 AM, Pierre De Rop wrote:
>> Hello Simon,
>> 
>> DM, like DS does not implement a private service registry to intra-bundle
>> components (well, except for optimized DM filter indices, but this is
>> another story).
>> 
>> I think Ipojo do support what you are describing, but I prefer to let other
>> people respond about this since I'm not enough experienced in iPojo. See
>> [1] about this, which comes from the osgi mailing list.
>> 
>> Now, I tend to agree with Neil, and intra-bundle private services can
>> simply be instantiated with the "new" keyword.
>> Alternatively, with DM, you can also use a composition of service
>> components: this allows you to:
>> 
>> - only register one single service for the bundle in the OSGi service
>> registry (or even only one DM component if it does not provide any services
>> at all, but just needs to define some dependencies to external services
>> (outside the bundle).
>> 
>> - and define a composition of objects that will get injected with the
>> external services.
>> For example, you can take a look at [2] for a concrete sample code of a
>> bundle which defines a component that is instantiated using a
>> "CompositionManager" pojo that is first injected with a configuration. And
>> from the configuration, the pojo may then create an implementation for the
>> service that the bundle provides, and also, some other pojo objects that
>> are part of the service implementation. The pojos will then be injected
>> with all the external service dependencies defined in the Activator (either
>> using field injection of bind method callbacks).
>> 
>> There is also another example which does not use a Factory, but only a
>> service composition in [3].
>> 
>> Finally, I would like to say that it's a not a real problem to have many
>> services registered in the Osgi service registry.
>> Registering services is cheap. And DM now supports an actor based thread
>> model which allows to activate, manage, and bind service components
>> concurrently, using a shared threadpool, and there is no startup time
>> degradation (I often start around 20000 services and my Felix Framework
>> starts in few of seconds). The new thread model is descriped in [4].
>> 
>> Also, regarding service diagnostics, even if you have thousands of micro
>> services registered in the OSGi registry, then DM gogo shell supports
>> advanced commands that allows you to quickly make some diagnostics (like
>> loop detection, missing service root causes, service lookup using filters,
>> etc ...).
>> 
>> [1] https://mail.osgi.org/pipermail/osgi-dev/2014-February/004310.html
>> [2]
>> http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/
>> [3]
>> http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/composite/
>> [4]
>> http://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/reference/thread-model.html
>> 
>> kind regards;
>> /Pierre
>> 
>> On Thu, May 21, 2015 at 4:52 PM, Simon Kitching <si...@vonos.net> wrote:
>> 
>>> Hi,
>>> 
>>> In blueprint it is possible to define arbitrary objects (beans) which are
>>> not published to the service registry but nevertheless can be injected into
>>> other beans.
>>> 
>>> AFAICT, in both declarative-services and felix-dm, the only objects that
>>> can be injected are references to services from the OSGi registry. Is this
>>> correct?
>>> 
>>> I understand that with DS and DM, components follow the standard OSGi
>>> lifecycles, in contrast to the Blueprint approach of "hiding" the
>>> lifecycle. In particular, in DS and DM when a component's mandatory
>>> dependency is deregistered then the component is also deregistered (which
>>> can cascade further). And the kind of tracking of dependencies required to
>>> make this happen is exactly what a service registry does.
>>> 
>>> However it's common for a bundle to have objects which are purely internal
>>> implementation details of the bundle, and are not for external use. Yet as
>>> far as I can see, in order to manage them with DS or DM, such internal
>>> objects need to be published into the global service registry - just to be
>>> able to then inject them back into components in the same bundle.
>>> 
>>> Have I misunderstood something?
>>> 
>>> Thanks,
>>> Simon
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>> 
>>> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: DependencyManager and bundle-private components

Posted by Simon Kitching <si...@vonos.net>.
On 05/25/2015 10:02 AM, Peter Kriens wrote:
> I tend to agree (actually rather violently) with Neil: ‘new’ for private objects is perfectly OK in a bundle.
>
> Why did DI frameworks got so popular? I think this was mostly because applications had grown so large and constituted of so many different parts that you needed central control to keep things apart and control their initialization in the right order.
>
> Now back to OSGi. First and foremost, you no longer (should!) have a monolith. A good bundle is cohesive. This means that everything in that bundle belongs together. So why should you make a mock if that thing is already coupled? There is no use to take the cost of abstracting because if anything changes, all its dependencies are together? I.e. the compiler will immediately tell you if you use things wrong. So by using ’new’ I get the benefit of readability, no magic, compiler checks, navigation in the IDE, and full refactoring. Best of all, no XML programming! For me one of the best things about OSGi is that the components are often so simple because they look like plain old java.
>
> Usually, in engineering, the ’truth’ is rarely at the extremes. Imho, DS found the right balance between external (dynamic) dependencies -> injection, for the rest plain old java since injection does not really provide you with anything but familiarity.
>
> And if you really absolutely want injection … just use Guice or another DI container inside your component?

I guess we'll just have to "agree to disagree" here. Maybe we work on 
different kinds of code.

I also am not a big fan of xml-based DI frameworks. Guice is properly 
type-safe, ie works fine with refactoring and provides compile-time 
safety plus the benefits I mentioned in my original email. And as I also 
mentioned in my original email, the primary use for DI is for injecting 
appropriate _singleton_ objects, not things that can be created with "new".

Blueprint has always supported full DI without needing to expose 
internal singletons as services in the global registry. It appears that 
iPojo's "composites" also support this. And it appears that the OSGi 
Subsystem service also supports "scoping" of services, but is rather 
heavy-weight to use and not really intended for this use-case.

Using Guice or similar isn't a good option due to the lack of support 
for the OSGi lifecyle. Imagine a bundle that wishes to create the 
following objects:

* exported service S1 which requires internal singleton T
* exported service S2 which also requires internal singleton T
* internal singleton T requires various other objects, including an 
instance of V
* and V requires imported service S5

It is not possible to use Guice to create T because it indirectly 
requires service S5 from the service registry. T (and V) should have a 
proper lifecycle, ie be created when S5 is available and be removed when 
S5 is no longer available. Guice cannot do that. And this is a _common 
usecase_.

In order for lifecycles to work properly, all objects (S1, S2, T, V, and 
anything else) should be tracked via a service registry - as DS, DM, etc 
do. That way, removal of a service triggers a "cascade" of removals of 
things that depend on it. The only thing I'm looking for is a way for 
internal objects T, V, etc to not be visible _container-wide_.

Thanks to the replies on this list, it appears that DS and DM cannot do 
this - ie those who wish to use any kind of DI within bundles need to 
either:
(a) use DS or DM and accept that internal singletons must be published 
globally;
(b) use Blueprint or iPojo;
(c) use a workaround.

In iPojo, the <composite> element in a config file creates a new 
service-registry which is independent of the global one. A nested 
<subservice> tag then imports a service from the global registry into 
the new one. And a nested <provides> tag exports a service from the new 
one into the global one. This approach is slightly different to the one 
I suggested earlier could be possible within DM or DS, but has the same 
effect. Note that DM also uses the word "composite"  but that appears to 
be a different thing.

Another less elegant approach I have considered is to use the 
ConditionalPermissionAdmin service; a service intended for local use 
within a bundle could be tagged with a property "service.local" or 
similar, and a rule could be added to ConditionalPermissionAdmin to make 
any service with that property visible (get-permission) only to the 
bundle that published it. That solves the "privacy" issue, though 
possibly has performance implications.

Thanks to all for your feedback.

Regards,
Simon

>> On 22 mei 2015, at 10:12, Simon Kitching <si...@vonos.net> wrote:
>>
>> Thanks Pierre and Neil for your replies!
>>
>> To avoid splitting this thread, I'll also reply to Neil's email here.
>>
>> I agree with Neil completely about the Blueprint lifecycle (ugly). I much prefer the DS lifecycle management - but miss the ability in DS or DM to manage bundle-private objects. I find it interesting that OSGi has solved the problem of a global class namespace (via Export-Package), but has then created a single global service namespace.
>>
>> Regarding the use of "new":
>>
>> (a) It would be nice to share code between OSGi and non-OSGi environments. In non-OSGi environments, use of dependency injection (rather than explicit use of new) is wide-spread.
>>
>> Do you not have problems when trying to share code between OSGi and non-OSGi environments?
>>
>> (b) DI isn't usually used to inject things that can be created with "new". Instead, it is predominantly used to inject singleton objects that are used by many other objects. As an example, a common _cache_ may be injected, or a serialization-helper. The alternative to DI in this case is not "new", but instead the old "static singleton" pattern, or lookup via JNDI or similar. Or to retrieve the object from the OSGi service registry - but that leads to "polluting" of the global service registry which I am concerned about.
>>
>> Do you not have problems when sharing a "bundle-private" object between multiple DS-managed objects?
>>
>> (c) One major motivation for using DI is to support unit testing. When a class uses DI properly, then a unit test can instantiate that class with mocks for the various other objects it interacts with. The test can then verify that the class under test interacts with mock objects as expected. It can also emulate various failures in the mocked systems, eg returning error-codes or throwing exceptions. When a class uses "new" to instantiate a helper object, no mocking of the external class is possible.
>>
>> When you use "new" in your code, does this not cause you problems with unit test coverage?
>>
>> Because of the above, I don't currently see using "new" as an alternative to DI for wiring up objects inside a bundle.
>>> OSGi defines only one service registry, accessible by any bundles. iPOJO splits these two interaction types. Instances receive an iPOJO Bundle
>>> Context delegating bundle-related methods to the "regular" bundle context, and service-related methods to a service context. This service context
>>> can access to the OSGi service registry or to a new one. Each composition instances have a service registry.
>> I'm not so concerned about "too many services in the registry" as I am about *bundle-private* services being present in the global registry.
>>
>> Do you see any reason why DM and DS could not adopt the same approach as iPojo, ie a per-composition (or at least per-bundle) service registry? I could imagine the following enhancement for DS:
>>   <component>
>>     <service>
>>       <provide interface="..." scope="local"/>
>> where the new "scope" attribute indicates that this particular component should be placed into the per-bundle service registry rather than the global one. All <reference> elements would then look first in the per-bundle registry before looking in the global one.
>>
>> For DM, something similar could be done with:
>>   createComponent().setInterface("..", Scope.LOCAL)
>>
>> Maybe another solution is to take advantage of felix-dm's ability to define "dependency handlers", and add another kind of dependency called "local" or similar? [as suggested by Karl Pauls in the email pointed out by Pierre]
>>
>> All opinions gratefully accepted!
>>
>> Regards, Simon
>>
>> On 05/22/2015 08:34 AM, Pierre De Rop wrote:
>>> Hello Simon,
>>>
>>> DM, like DS does not implement a private service registry to intra-bundle
>>> components (well, except for optimized DM filter indices, but this is
>>> another story).
>>>
>>> I think Ipojo do support what you are describing, but I prefer to let other
>>> people respond about this since I'm not enough experienced in iPojo. See
>>> [1] about this, which comes from the osgi mailing list.
>>>
>>> Now, I tend to agree with Neil, and intra-bundle private services can
>>> simply be instantiated with the "new" keyword.
>>> Alternatively, with DM, you can also use a composition of service
>>> components: this allows you to:
>>>
>>> - only register one single service for the bundle in the OSGi service
>>> registry (or even only one DM component if it does not provide any services
>>> at all, but just needs to define some dependencies to external services
>>> (outside the bundle).
>>>
>>> - and define a composition of objects that will get injected with the
>>> external services.
>>> For example, you can take a look at [2] for a concrete sample code of a
>>> bundle which defines a component that is instantiated using a
>>> "CompositionManager" pojo that is first injected with a configuration. And
>>> from the configuration, the pojo may then create an implementation for the
>>> service that the bundle provides, and also, some other pojo objects that
>>> are part of the service implementation. The pojos will then be injected
>>> with all the external service dependencies defined in the Activator (either
>>> using field injection of bind method callbacks).
>>>
>>> There is also another example which does not use a Factory, but only a
>>> service composition in [3].
>>>
>>> Finally, I would like to say that it's a not a real problem to have many
>>> services registered in the Osgi service registry.
>>> Registering services is cheap. And DM now supports an actor based thread
>>> model which allows to activate, manage, and bind service components
>>> concurrently, using a shared threadpool, and there is no startup time
>>> degradation (I often start around 20000 services and my Felix Framework
>>> starts in few of seconds). The new thread model is descriped in [4].
>>>
>>> Also, regarding service diagnostics, even if you have thousands of micro
>>> services registered in the OSGi registry, then DM gogo shell supports
>>> advanced commands that allows you to quickly make some diagnostics (like
>>> loop detection, missing service root causes, service lookup using filters,
>>> etc ...).
>>>
>>> [1] https://mail.osgi.org/pipermail/osgi-dev/2014-February/004310.html
>>> [2]
>>> http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/
>>> [3]
>>> http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/composite/
>>> [4]
>>> http://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/reference/thread-model.html
>>>
>>> kind regards;
>>> /Pierre
>>>
>>> On Thu, May 21, 2015 at 4:52 PM, Simon Kitching <si...@vonos.net> wrote:
>>>
>>>> Hi,
>>>>
>>>> In blueprint it is possible to define arbitrary objects (beans) which are
>>>> not published to the service registry but nevertheless can be injected into
>>>> other beans.
>>>>
>>>> AFAICT, in both declarative-services and felix-dm, the only objects that
>>>> can be injected are references to services from the OSGi registry. Is this
>>>> correct?
>>>>
>>>> I understand that with DS and DM, components follow the standard OSGi
>>>> lifecycles, in contrast to the Blueprint approach of "hiding" the
>>>> lifecycle. In particular, in DS and DM when a component's mandatory
>>>> dependency is deregistered then the component is also deregistered (which
>>>> can cascade further). And the kind of tracking of dependencies required to
>>>> make this happen is exactly what a service registry does.
>>>>
>>>> However it's common for a bundle to have objects which are purely internal
>>>> implementation details of the bundle, and are not for external use. Yet as
>>>> far as I can see, in order to manage them with DS or DM, such internal
>>>> objects need to be published into the global service registry - just to be
>>>> able to then inject them back into components in the same bundle.
>>>>
>>>> Have I misunderstood something?
>>>>
>>>> Thanks,
>>>> Simon
>>>>
>>>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>>> For additional commands, e-mail: users-help@felix.apache.org
>>>>
>>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: DependencyManager and bundle-private components

Posted by Peter Kriens <pk...@gmail.com>.
I tend to agree (actually rather violently) with Neil: ‘new’ for private objects is perfectly OK in a bundle.

Why did DI frameworks got so popular? I think this was mostly because applications had grown so large and constituted of so many different parts that you needed central control to keep things apart and control their initialization in the right order. 

Now back to OSGi. First and foremost, you no longer (should!) have a monolith. A good bundle is cohesive. This means that everything in that bundle belongs together. So why should you make a mock if that thing is already coupled? There is no use to take the cost of abstracting because if anything changes, all its dependencies are together? I.e. the compiler will immediately tell you if you use things wrong. So by using ’new’ I get the benefit of readability, no magic, compiler checks, navigation in the IDE, and full refactoring. Best of all, no XML programming! For me one of the best things about OSGi is that the components are often so simple because they look like plain old java.

Usually, in engineering, the ’truth’ is rarely at the extremes. Imho, DS found the right balance between external (dynamic) dependencies -> injection, for the rest plain old java since injection does not really provide you with anything but familiarity.

And if you really absolutely want injection … just use Guice or another DI container inside your component?

Kind regards,

	Peter Kriens




> On 22 mei 2015, at 10:12, Simon Kitching <si...@vonos.net> wrote:
> 
> Thanks Pierre and Neil for your replies!
> 
> To avoid splitting this thread, I'll also reply to Neil's email here.
> 
> I agree with Neil completely about the Blueprint lifecycle (ugly). I much prefer the DS lifecycle management - but miss the ability in DS or DM to manage bundle-private objects. I find it interesting that OSGi has solved the problem of a global class namespace (via Export-Package), but has then created a single global service namespace.
> 
> Regarding the use of "new":
> 
> (a) It would be nice to share code between OSGi and non-OSGi environments. In non-OSGi environments, use of dependency injection (rather than explicit use of new) is wide-spread.
> 
> Do you not have problems when trying to share code between OSGi and non-OSGi environments?
> 
> (b) DI isn't usually used to inject things that can be created with "new". Instead, it is predominantly used to inject singleton objects that are used by many other objects. As an example, a common _cache_ may be injected, or a serialization-helper. The alternative to DI in this case is not "new", but instead the old "static singleton" pattern, or lookup via JNDI or similar. Or to retrieve the object from the OSGi service registry - but that leads to "polluting" of the global service registry which I am concerned about.
> 
> Do you not have problems when sharing a "bundle-private" object between multiple DS-managed objects?
> 
> (c) One major motivation for using DI is to support unit testing. When a class uses DI properly, then a unit test can instantiate that class with mocks for the various other objects it interacts with. The test can then verify that the class under test interacts with mock objects as expected. It can also emulate various failures in the mocked systems, eg returning error-codes or throwing exceptions. When a class uses "new" to instantiate a helper object, no mocking of the external class is possible.
> 
> When you use "new" in your code, does this not cause you problems with unit test coverage?
> 
> Because of the above, I don't currently see using "new" as an alternative to DI for wiring up objects inside a bundle.
> 
> Pierre, many thanks for your very detailed reply.
> 
> Re link to iPojo - that's next on my list of things to investigate; I've been using spring-dm, blueprint and felix-dm up to now but haven't yet taken time to investigate ipojo. And thanks for link [1] - Christian Schneider is asking exactly the same question as I am, in Feb 2014. Sadly Felix Meshberger's reply is clear : not supported in DS. I don't yet understand why some people think this is important (Christian, myself for example) while others don't. See https://mail.osgi.org/pipermail/osgi-dev/2014-February/004295.html and the followup emails.
> 
> The Felix-DM CompositionManager example you linked to looks very interesting, thanks. Unfortunately javadoc for "Component.setComposition" is pretty unhelpful. As far as I can tell, the "composition" feature allows a developer to define in DM:
> * a single Component
> * with all the dependencies that need to be injected into it
> except that
> * instead of DM instantiating a single object when the dependencies are met, it invokes a factory method that returns a collection of objects, and
> * instead of injection of these dependencies being performed on a single object, it is performed on the collection of objects
> Have I understood? If so, that is interesting but not AFAICT what I am looking for.
> 
> While searching for info on "composition", I came across http://de.slideshare.net/mfrancis/the-ultimate-dependency-manager-shoot-out-x-uiterlinden-s-mak . In particular, slide 19 talks about support in ipojo for "intra-bundle mechanism" and "scoped service registry" which look exactly like what I am missing in DS. Sadly, the topic isn't mentioned again in the slideshow. However searching for those terms led me to this page:
> * http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/ipojo-composition-tutorial.html
> 
> And this section from the ipojo "composition" documentation (which appears to be not related to the felix-dm composition feature) is exactly what I think is missing from DS/DM:
> > OSGi defines only one service registry, accessible by any bundles. iPOJO splits these two interaction types. Instances receive an iPOJO Bundle
> > Context delegating bundle-related methods to the "regular" bundle context, and service-related methods to a service context. This service context
> > can access to the OSGi service registry or to a new one. Each composition instances have a service registry.
> 
> I'm not so concerned about "too many services in the registry" as I am about *bundle-private* services being present in the global registry.
> 
> Do you see any reason why DM and DS could not adopt the same approach as iPojo, ie a per-composition (or at least per-bundle) service registry? I could imagine the following enhancement for DS:
>  <component>
>    <service>
>      <provide interface="..." scope="local"/>
> where the new "scope" attribute indicates that this particular component should be placed into the per-bundle service registry rather than the global one. All <reference> elements would then look first in the per-bundle registry before looking in the global one.
> 
> For DM, something similar could be done with:
>  createComponent().setInterface("..", Scope.LOCAL)
> 
> Maybe another solution is to take advantage of felix-dm's ability to define "dependency handlers", and add another kind of dependency called "local" or similar? [as suggested by Karl Pauls in the email pointed out by Pierre]
> 
> All opinions gratefully accepted!
> 
> Regards, Simon
> 
> On 05/22/2015 08:34 AM, Pierre De Rop wrote:
>> Hello Simon,
>> 
>> DM, like DS does not implement a private service registry to intra-bundle
>> components (well, except for optimized DM filter indices, but this is
>> another story).
>> 
>> I think Ipojo do support what you are describing, but I prefer to let other
>> people respond about this since I'm not enough experienced in iPojo. See
>> [1] about this, which comes from the osgi mailing list.
>> 
>> Now, I tend to agree with Neil, and intra-bundle private services can
>> simply be instantiated with the "new" keyword.
>> Alternatively, with DM, you can also use a composition of service
>> components: this allows you to:
>> 
>> - only register one single service for the bundle in the OSGi service
>> registry (or even only one DM component if it does not provide any services
>> at all, but just needs to define some dependencies to external services
>> (outside the bundle).
>> 
>> - and define a composition of objects that will get injected with the
>> external services.
>> For example, you can take a look at [2] for a concrete sample code of a
>> bundle which defines a component that is instantiated using a
>> "CompositionManager" pojo that is first injected with a configuration. And
>> from the configuration, the pojo may then create an implementation for the
>> service that the bundle provides, and also, some other pojo objects that
>> are part of the service implementation. The pojos will then be injected
>> with all the external service dependencies defined in the Activator (either
>> using field injection of bind method callbacks).
>> 
>> There is also another example which does not use a Factory, but only a
>> service composition in [3].
>> 
>> Finally, I would like to say that it's a not a real problem to have many
>> services registered in the Osgi service registry.
>> Registering services is cheap. And DM now supports an actor based thread
>> model which allows to activate, manage, and bind service components
>> concurrently, using a shared threadpool, and there is no startup time
>> degradation (I often start around 20000 services and my Felix Framework
>> starts in few of seconds). The new thread model is descriped in [4].
>> 
>> Also, regarding service diagnostics, even if you have thousands of micro
>> services registered in the OSGi registry, then DM gogo shell supports
>> advanced commands that allows you to quickly make some diagnostics (like
>> loop detection, missing service root causes, service lookup using filters,
>> etc ...).
>> 
>> [1] https://mail.osgi.org/pipermail/osgi-dev/2014-February/004310.html
>> [2]
>> http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/
>> [3]
>> http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/composite/
>> [4]
>> http://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/reference/thread-model.html
>> 
>> kind regards;
>> /Pierre
>> 
>> On Thu, May 21, 2015 at 4:52 PM, Simon Kitching <si...@vonos.net> wrote:
>> 
>>> Hi,
>>> 
>>> In blueprint it is possible to define arbitrary objects (beans) which are
>>> not published to the service registry but nevertheless can be injected into
>>> other beans.
>>> 
>>> AFAICT, in both declarative-services and felix-dm, the only objects that
>>> can be injected are references to services from the OSGi registry. Is this
>>> correct?
>>> 
>>> I understand that with DS and DM, components follow the standard OSGi
>>> lifecycles, in contrast to the Blueprint approach of "hiding" the
>>> lifecycle. In particular, in DS and DM when a component's mandatory
>>> dependency is deregistered then the component is also deregistered (which
>>> can cascade further). And the kind of tracking of dependencies required to
>>> make this happen is exactly what a service registry does.
>>> 
>>> However it's common for a bundle to have objects which are purely internal
>>> implementation details of the bundle, and are not for external use. Yet as
>>> far as I can see, in order to manage them with DS or DM, such internal
>>> objects need to be published into the global service registry - just to be
>>> able to then inject them back into components in the same bundle.
>>> 
>>> Have I misunderstood something?
>>> 
>>> Thanks,
>>> Simon
>>> 
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>>> For additional commands, e-mail: users-help@felix.apache.org
>>> 
>>> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: DependencyManager and bundle-private components

Posted by Simon Kitching <si...@vonos.net>.
Thanks Pierre and Neil for your replies!

To avoid splitting this thread, I'll also reply to Neil's email here.

I agree with Neil completely about the Blueprint lifecycle (ugly). I 
much prefer the DS lifecycle management - but miss the ability in DS or 
DM to manage bundle-private objects. I find it interesting that OSGi has 
solved the problem of a global class namespace (via Export-Package), but 
has then created a single global service namespace.

Regarding the use of "new":

(a) It would be nice to share code between OSGi and non-OSGi 
environments. In non-OSGi environments, use of dependency injection 
(rather than explicit use of new) is wide-spread.

Do you not have problems when trying to share code between OSGi and 
non-OSGi environments?

(b) DI isn't usually used to inject things that can be created with 
"new". Instead, it is predominantly used to inject singleton objects 
that are used by many other objects. As an example, a common _cache_ may 
be injected, or a serialization-helper. The alternative to DI in this 
case is not "new", but instead the old "static singleton" pattern, or 
lookup via JNDI or similar. Or to retrieve the object from the OSGi 
service registry - but that leads to "polluting" of the global service 
registry which I am concerned about.

Do you not have problems when sharing a "bundle-private" object between 
multiple DS-managed objects?

(c) One major motivation for using DI is to support unit testing. When a 
class uses DI properly, then a unit test can instantiate that class with 
mocks for the various other objects it interacts with. The test can then 
verify that the class under test interacts with mock objects as 
expected. It can also emulate various failures in the mocked systems, eg 
returning error-codes or throwing exceptions. When a class uses "new" to 
instantiate a helper object, no mocking of the external class is possible.

When you use "new" in your code, does this not cause you problems with 
unit test coverage?

Because of the above, I don't currently see using "new" as an 
alternative to DI for wiring up objects inside a bundle.

Pierre, many thanks for your very detailed reply.

Re link to iPojo - that's next on my list of things to investigate; I've 
been using spring-dm, blueprint and felix-dm up to now but haven't yet 
taken time to investigate ipojo. And thanks for link [1] - Christian 
Schneider is asking exactly the same question as I am, in Feb 2014. 
Sadly Felix Meshberger's reply is clear : not supported in DS. I don't 
yet understand why some people think this is important (Christian, 
myself for example) while others don't. See 
https://mail.osgi.org/pipermail/osgi-dev/2014-February/004295.html and 
the followup emails.

The Felix-DM CompositionManager example you linked to looks very 
interesting, thanks. Unfortunately javadoc for 
"Component.setComposition" is pretty unhelpful. As far as I can tell, 
the "composition" feature allows a developer to define in DM:
* a single Component
* with all the dependencies that need to be injected into it
except that
* instead of DM instantiating a single object when the dependencies are 
met, it invokes a factory method that returns a collection of objects, and
* instead of injection of these dependencies being performed on a single 
object, it is performed on the collection of objects
Have I understood? If so, that is interesting but not AFAICT what I am 
looking for.

While searching for info on "composition", I came across 
http://de.slideshare.net/mfrancis/the-ultimate-dependency-manager-shoot-out-x-uiterlinden-s-mak 
. In particular, slide 19 talks about support in ipojo for "intra-bundle 
mechanism" and "scoped service registry" which look exactly like what I 
am missing in DS. Sadly, the topic isn't mentioned again in the 
slideshow. However searching for those terms led me to this page:
* 
http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-gettingstarted/ipojo-composition-tutorial.html

And this section from the ipojo "composition" documentation (which 
appears to be not related to the felix-dm composition feature) is 
exactly what I think is missing from DS/DM:
 > OSGi defines only one service registry, accessible by any bundles. 
iPOJO splits these two interaction types. Instances receive an iPOJO Bundle
 > Context delegating bundle-related methods to the "regular" bundle 
context, and service-related methods to a service context. This service 
context
 > can access to the OSGi service registry or to a new one. Each 
composition instances have a service registry.

I'm not so concerned about "too many services in the registry" as I am 
about *bundle-private* services being present in the global registry.

Do you see any reason why DM and DS could not adopt the same approach as 
iPojo, ie a per-composition (or at least per-bundle) service registry? I 
could imagine the following enhancement for DS:
   <component>
     <service>
       <provide interface="..." scope="local"/>
where the new "scope" attribute indicates that this particular component 
should be placed into the per-bundle service registry rather than the 
global one. All <reference> elements would then look first in the 
per-bundle registry before looking in the global one.

For DM, something similar could be done with:
   createComponent().setInterface("..", Scope.LOCAL)

Maybe another solution is to take advantage of felix-dm's ability to 
define "dependency handlers", and add another kind of dependency called 
"local" or similar? [as suggested by Karl Pauls in the email pointed out 
by Pierre]

All opinions gratefully accepted!

Regards, Simon

On 05/22/2015 08:34 AM, Pierre De Rop wrote:
> Hello Simon,
>
> DM, like DS does not implement a private service registry to intra-bundle
> components (well, except for optimized DM filter indices, but this is
> another story).
>
> I think Ipojo do support what you are describing, but I prefer to let other
> people respond about this since I'm not enough experienced in iPojo. See
> [1] about this, which comes from the osgi mailing list.
>
> Now, I tend to agree with Neil, and intra-bundle private services can
> simply be instantiated with the "new" keyword.
> Alternatively, with DM, you can also use a composition of service
> components: this allows you to:
>
> - only register one single service for the bundle in the OSGi service
> registry (or even only one DM component if it does not provide any services
> at all, but just needs to define some dependencies to external services
> (outside the bundle).
>
> - and define a composition of objects that will get injected with the
> external services.
> For example, you can take a look at [2] for a concrete sample code of a
> bundle which defines a component that is instantiated using a
> "CompositionManager" pojo that is first injected with a configuration. And
> from the configuration, the pojo may then create an implementation for the
> service that the bundle provides, and also, some other pojo objects that
> are part of the service implementation. The pojos will then be injected
> with all the external service dependencies defined in the Activator (either
> using field injection of bind method callbacks).
>
> There is also another example which does not use a Factory, but only a
> service composition in [3].
>
> Finally, I would like to say that it's a not a real problem to have many
> services registered in the Osgi service registry.
> Registering services is cheap. And DM now supports an actor based thread
> model which allows to activate, manage, and bind service components
> concurrently, using a shared threadpool, and there is no startup time
> degradation (I often start around 20000 services and my Felix Framework
> starts in few of seconds). The new thread model is descriped in [4].
>
> Also, regarding service diagnostics, even if you have thousands of micro
> services registered in the OSGi registry, then DM gogo shell supports
> advanced commands that allows you to quickly make some diagnostics (like
> loop detection, missing service root causes, service lookup using filters,
> etc ...).
>
> [1] https://mail.osgi.org/pipermail/osgi-dev/2014-February/004310.html
> [2]
> http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/
> [3]
> http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/composite/
> [4]
> http://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/reference/thread-model.html
>
> kind regards;
> /Pierre
>
> On Thu, May 21, 2015 at 4:52 PM, Simon Kitching <si...@vonos.net> wrote:
>
>> Hi,
>>
>> In blueprint it is possible to define arbitrary objects (beans) which are
>> not published to the service registry but nevertheless can be injected into
>> other beans.
>>
>> AFAICT, in both declarative-services and felix-dm, the only objects that
>> can be injected are references to services from the OSGi registry. Is this
>> correct?
>>
>> I understand that with DS and DM, components follow the standard OSGi
>> lifecycles, in contrast to the Blueprint approach of "hiding" the
>> lifecycle. In particular, in DS and DM when a component's mandatory
>> dependency is deregistered then the component is also deregistered (which
>> can cascade further). And the kind of tracking of dependencies required to
>> make this happen is exactly what a service registry does.
>>
>> However it's common for a bundle to have objects which are purely internal
>> implementation details of the bundle, and are not for external use. Yet as
>> far as I can see, in order to manage them with DS or DM, such internal
>> objects need to be published into the global service registry - just to be
>> able to then inject them back into components in the same bundle.
>>
>> Have I misunderstood something?
>>
>> Thanks,
>> Simon
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
>> For additional commands, e-mail: users-help@felix.apache.org
>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org


Re: DependencyManager and bundle-private components

Posted by Pierre De Rop <pi...@gmail.com>.
Hello Simon,

DM, like DS does not implement a private service registry to intra-bundle
components (well, except for optimized DM filter indices, but this is
another story).

I think Ipojo do support what you are describing, but I prefer to let other
people respond about this since I'm not enough experienced in iPojo. See
[1] about this, which comes from the osgi mailing list.

Now, I tend to agree with Neil, and intra-bundle private services can
simply be instantiated with the "new" keyword.
Alternatively, with DM, you can also use a composition of service
components: this allows you to:

- only register one single service for the bundle in the OSGi service
registry (or even only one DM component if it does not provide any services
at all, but just needs to define some dependencies to external services
(outside the bundle).

- and define a composition of objects that will get injected with the
external services.
For example, you can take a look at [2] for a concrete sample code of a
bundle which defines a component that is instantiated using a
"CompositionManager" pojo that is first injected with a configuration. And
from the configuration, the pojo may then create an implementation for the
service that the bundle provides, and also, some other pojo objects that
are part of the service implementation. The pojos will then be injected
with all the external service dependencies defined in the Activator (either
using field injection of bind method callbacks).

There is also another example which does not use a Factory, but only a
service composition in [3].

Finally, I would like to say that it's a not a real problem to have many
services registered in the Osgi service registry.
Registering services is cheap. And DM now supports an actor based thread
model which allows to activate, manage, and bind service components
concurrently, using a shared threadpool, and there is no startup time
degradation (I often start around 20000 services and my Felix Framework
starts in few of seconds). The new thread model is descriped in [4].

Also, regarding service diagnostics, even if you have thousands of micro
services registered in the OSGi registry, then DM gogo shell supports
advanced commands that allows you to quickly make some diagnostics (like
loop detection, missing service root causes, service lookup using filters,
etc ...).

[1] https://mail.osgi.org/pipermail/osgi-dev/2014-February/004310.html
[2]
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/compositefactory/
[3]
http://svn.apache.org/viewvc/felix/trunk/dependencymanager/org.apache.felix.dependencymanager.samples/src/org/apache/felix/dependencymanager/samples/composite/
[4]
http://felix.apache.org/documentation/subprojects/apache-felix-dependency-manager/reference/thread-model.html

kind regards;
/Pierre

On Thu, May 21, 2015 at 4:52 PM, Simon Kitching <si...@vonos.net> wrote:

> Hi,
>
> In blueprint it is possible to define arbitrary objects (beans) which are
> not published to the service registry but nevertheless can be injected into
> other beans.
>
> AFAICT, in both declarative-services and felix-dm, the only objects that
> can be injected are references to services from the OSGi registry. Is this
> correct?
>
> I understand that with DS and DM, components follow the standard OSGi
> lifecycles, in contrast to the Blueprint approach of "hiding" the
> lifecycle. In particular, in DS and DM when a component's mandatory
> dependency is deregistered then the component is also deregistered (which
> can cascade further). And the kind of tracking of dependencies required to
> make this happen is exactly what a service registry does.
>
> However it's common for a bundle to have objects which are purely internal
> implementation details of the bundle, and are not for external use. Yet as
> far as I can see, in order to manage them with DS or DM, such internal
> objects need to be published into the global service registry - just to be
> able to then inject them back into components in the same bundle.
>
> Have I misunderstood something?
>
> Thanks,
> Simon
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>