Hi,
“Typical
developer-decision is then to introduce some static
setInstance/getInstance methods somewhere where the DS
component registers itself when activated.
Which of course only
works for singleton components.”
Such a statement really
scares me. It shows that the usage of static methods/fields
are still quite misunderstood by a lot of people. When
developers use it this way, they mostly think static is a
way to access an instance from anywhere, but they are
missing the thing that all instances of that class will
share the same value (as it is on class level, not on the
instance). Actually it will create several issues in a
multithreaded environment. And I highly recommend to skip
such approaches!
If you want to use OSGi
services from non-OSGi components, you need to use low-level
OSGi mechanisms. Typically by getting the ServiceReference
from the BundleContext or better using a ServiceTracker for
example.
https://mnlipp.github.io/osgi-getting-started/AccessingAService.html
https://mnlipp.github.io/osgi-getting-started/TrackingAService.html
https://www.knopflerfish.org/osgi_service_tutorial.html#accessing
The BundleContext can be retrieved via
Bundle bundle =
FrameworkUtil.getBundle(requestor.getRequestingObjectClass());
BundleContext context =
bundle.getBundleContext();
At least if you are running an OSGi framework,
otherwise bundle will be null.
Since you need to use low-level OSGi API to
retrieve a DS component from a non-OSGi component, the
following chapter of the specification should help answering
your question:
https://docs.osgi.org/specification/osgi.core/7.0.0/framework.service.html#framework.service.getting
Mit freundlichen Grüßen / Best regards
Dirk Fauth
Cross-Domain Computing Solutions, Cross Automotive Platforms
- System, Software and Tools Engineering Engineering
Software Methods and Tools1 (XC-ECO/ESM1)
Robert Bosch GmbH | Postfach 30 02 40 | 70442 Stuttgart |
GERMANY | www.bosch.com
Tel. +49
711 811-57819 | Telefax +49 711 811 |
Dirk.Fauth@xxxxxxxxxxxx
Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart, HRB
14000;
Aufsichtsratsvorsitzender: Franz Fehrenbach;
Geschäftsführung: Dr. Volkmar Denner,
Prof. Dr. Stefan Asenkerschbaumer, Filiz Albrecht, Dr.
Michael Bolle, Dr. Christian Fischer,
Dr. Stefan Hartung, Dr. Markus Heyn, Harald Kröger, Rolf
Najork, Uwe Raschke
PROTOTYPE
scopes is intended to align with those cases where
unique instances are needed, where the instance might
keep state and/or be modified (injection in this case)
by an external actor along an axis which OSGi does not
have insight into or control over (e.g. like DS).
For
example, JAX-RS implementations would normally only know
the classname of the resource and do a _new_ to get an
instance _on demande_ then do some things like injection
or proxy and then execute it and then throw away the
instance at the end of the request. So the vehicle to
protect against that usage in OSGi is to implement the
"production" of these instances using PROTOTYPE scope.
- Ray
This touches on a
situation we've often encountered before: how to
interact with a DS component from something that is
not an OSGi component?
Typical
developer-decision is then to introduce some static
setInstance/getInstance methods somewhere where the DS
component registers itself when activated.
Which of course
only works for singleton components.
For PROTOTYPE it
appears the DS infrastructure is able to understand
when a new instance is needed and/or there is some
facility somewhere in DS to allow an external actor to
ask for a new component creation and get a reference
to it to inject/interact with it. Is this the case and
if so could you point me to some info about this?
Or do I
misunderstand the above and is the only standard
approach always to have a consumer component with
ReferenceScope.PROTOTYPE_REQUIRED in the @Reference?
Many thanks,
erwin