Skip to content
This repository has been archived by the owner on Dec 4, 2020. It is now read-only.

[DS] Allow @Reference to get service only by a target filter regardless of the Services ObjectClass #2934

Open
bjhargrave opened this issue Apr 10, 2018 · 6 comments
Assignees

Comments

@bjhargrave
Copy link
Member

Original bug ID: BZ#3066
From: @juergen-albert
Reported version: R7

@bjhargrave
Copy link
Member Author

Comment author: @juergen-albert

Such an option would remove one of the last needs to use servicetrackers instead of DS.

As a suggestion the injection point could look as follows:

@ Reference(serviceClassFilter = false, target = "(jaxrsendpoint=true)")
List service;

By adding a additional Marker like the named serviceClassFilter, DS has a clear distinction, when to append the objectClassFilter to the filter string. The results then must only be checked if they are assignable to the service(s) to inject, in case the injection point is not of type Object.

@bjhargrave
Copy link
Member Author

Comment author: @bjhargrave

The reference is to inject the service into a field/method/constructor parameter. These are typed entities and we need to ensure the type of the service matches the type of the injection entity.

Also, you must consider what the xml description looks like. The annotations only generate the xml. A boolean thing like serviceClassFilter is not a great design. Better would be to have a special "Reference.Any" class so you can say @ Reference(service=Reference.Any.class). This would get special treatment when seen in the xml description. We would also need to make sure the injection site is of type Object. If the injection site of the "any" reference is not of type Object, then it cannot be injected. It would be as if the target service did not match the type of the reference.

@bjhargrave
Copy link
Member Author

Comment author: @juergen-albert

A Reference Any class would also do the job as well and would negate the need for a new xml schema version. Thus I would vote for this solution.

The check of the injection point is of type Object makes sense as well and would fit my described requirement. On second thought: instead of af a general check if the injection point is of type Object, DS could check if the injectionpoint type is assignable from a object class of a incoming service provides.
This would provide a convenient mechanism to filter services in way that is not necessarily possible with a target filter. As an Example of the top of my head: JaxrsExtension are usually registered under there actual Object type. My described Mechanism would allow a nice any easy way, to get all extension that are actually MessageBodyReaders.

@ Refererence(service=Reference.Any.class, target="(jaxrs.extension=true)")
List myReaders;

@bjhargrave
Copy link
Member Author

Comment author: @bjhargrave

(In reply to Jürgen Albert from comment BZ#2)

On second thought: instead of af a
general check if the injection point is of type Object, DS could check if
the injectionpoint type is assignable from a object class of a incoming
service provides.
This would provide a convenient mechanism to filter services in way that is
not necessarily possible with a target filter. As an Example of the top of
my head: JaxrsExtension are usually registered under there actual Object
type. My described Mechanism would allow a nice any easy way, to get all
extension that are actually MessageBodyReaders.

@ Refererence(service=Reference.Any.class, target="(jaxrs.extension=true)")
List myReaders;

But the type safety cannot be validated at tool time (Bnd).

It also imposes a type safety check burden at runtime for SCR. Currently SCR only has to use the type name from the XML in the service API and the framework will make the proper type safety checks for the component bundle. With Reference.Any, SCR would need to specify no class name for the service API call. So the result can contain services which are not type compatible with the type used by the bundle. So SCR would need to perform the types checks and the type may not be one of the declared service types of the service which I think is not a good idea.

The better way to get what you want is:

@ Refererence(target="(jaxrs.extension=true)")
List myReaders;

since it uses the normal type safety checks in the framework. You get all MessageBodyReader services which are type compatible with your bundle and have the desired service property value.

@ Refererence(service=Reference.Any.class, target="(jaxrs.extension=true)")
List extensions;

Is to get all services without regard to type that have the desired service property. So I think the requirement to use Object with Reference.Any is an important choice.

@bjhargrave
Copy link
Member Author

Comment author: @juergen-albert

I've just realized, that my answer never made it here:

+1 from me for your proposed solution.

@bjhargrave
Copy link
Member Author

Comment author: @bjhargrave

CPEG call: Will do for R8.

@bjhargrave bjhargrave self-assigned this Apr 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant