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 <[email protected]> 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: [email protected]
For additional commands, e-mail: [email protected]




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to