In org.osgi.util.tracker.ServiceTracker
there is a method open(boolean)
.
The documentation says that you can give true
in which case the tracker "will track all matching services regardless of class loader accessibility".
I don't really understand this part. As far as I understand, the common use case for services is that
SI
(for Service Interface) contains a service interface,SP
(for Service Provider) contains a service component / implementation class (e.g., as a Declarative Service / @Component
), andSU
(for Service User) wants to use the service, so it basically uses var st = new ServiceTracker(bundleContext, IService.class, null); st.open();
to track and use the service (if, for some reason, it cannot use DS...).So both SU
and SP
depend on SI
, but SU
does not depend on SP
. (as far as I understand, that's one of the key points that the SU
does not need to know about the SP
...)
So, how can it happen that open(true)
would track a service that is not "class loader accessible"? What does "class loader accessibility" mean in such a scenario? Because, since SU
does not depend on SP
, but the above scenario still works, the service implementation does not need to be known to SP
, obviously.
Could someone outline an example how this could happen?
And, while I am asking, what would even be a use case for open(true)
? If there is a scenario where I cannot access the service implementation, what's the point of tracking such a service anyways?
There can be different providers of the package of a service interface. For example, org.foo.service version=1.0 and org.foo.service version 1.2. There can also be two providers of the service registered, one using the version 1.0 package and another using the version 1.2 package for the service interface. As a user of the service, a bundle importing the org.foo.service package can only be wired to one of the providers of the package. This means it can only be type-compatible with one of the services.
open()
and open(false)
is the normal way to use ServiceTracker as you only track services which use the same package for the service interface as your bundle. That is, you can safely cast the service object to the service interface type to which your bundle has access.
open(true)
is a special case where the bundle does not have a need to cast the service objects to a service interface type. This use case is rare and generally should not be used.