felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jens Offenbach" <wolle5...@gmx.de>
Subject Aw: Re: [SCR] Selecting services without giving a service interface
Date Sat, 09 Apr 2016 10:30:06 GMT
I think the ExtraService annotation quite nice, but when I look at my use case, I am still
in trouble. I am confronted with these two basic problems:

1. Service injection of "any" type filtered only by a filter expression in DS. This happens
when the service interface is not known in advance or when there is no common interface.
2. Service provisioning in case when the objectclass attribute cannot be specified at design
time. In my use case I am passing a type list (String based class names) to a proxy component.
The components tries to load the classes using "DynamicPackage-Import" and registers a service
proxy under these interfaces with some more attributes. I use "registerService" from the BundleContext
because there is no way to have dynamic objectclasses for provided services in DS or do I
miss someting?

Have a nice weekend.

Best regards,
Jens
 

Gesendet: Freitag, 08. April 2016 um 17:29 Uhr
Von: "David Jencks" <david_jencks@yahoo.com.INVALID>
An: users@felix.apache.org
Betreff: Re: [SCR] Selecting services without giving a service interface
(going back to top-outing, sorry)

>From your example, I really don’t like this approach. One big reason for using string-matching
rather than checking the java inheritance hierarchy when looking for services is so osgi can
be lazy about loading classes. I think that all you actually are asking for is an easier way
to get your FooProvider interface listed in the ObjectClass, which I can definitely sympathies
with :-)

So right now you can just explicitly list the classes your want to expose…

@Component(service={FooProvider.class, FooProviderChild.class})

I don’t see this as significantly more onerous that specifying a bunch of properties, and
it’s certainly more typo-resistant since you have to get the class name right in order for
it to compile.

However, I’ve often wanted the ability to use custom annotations to modify the effect of
the spec annotations. (we’re getting into bnd territory here). bnd provides a nice way to
have custom annotations to add other-namespace attributes to the component.xml (see the scr-ext-anno
project) I tried at one point to extend this so such a custom annotation could set stuff in
the actual namespace, but there were too many concerns about interference between specifying
something with the spec anno and the custom anno so I gave up. However this might be worth
revisiting. It might look like

@Component
@ExtraService(FooProvider.class)
public class FooProviderChildImpl implements FooProviderChild {…}

david jencks

> On Apr 8, 2016, at 8:07 AM, Simon Chemouil <schemouil@gmail.com> wrote:
>
> Le 08/04/2016 16:40, David Jencks a écrit :
>> I don’t get it. My understanding of your last suggestion is that all the services
you want to bind implement some interface, and that DS check type compatibility with this
interface before accepting the service event (or discovery-by-query) before binding. How is
this any different than putting that interface in the ObjectClass the service exposes, aside
from duplicating functionality already managed by the service registry?
>>
>> Why can’t you do what you want today by including Object in the ObjectClass of
all the services you want to bind, and declaring Object as the interface in all the references?
>
> Hi,
>
> You are right. I could do it that way, but I find it ugly at the
> provider side.
>
> Sometimes, a component that I want to filter on, using a property, will
> be implementing an orthogonal service and it's a shame to provide
> Object.class because DS cannot consume it otherwise (I can do it with a
> ServiceTracker). I don't think the provider should have to do that:
>
> @Component(property = "foo=true", service = { Object.class,
> FooProvider.class)
> public final MyFooProvider implements FooProvider {
>
> }
>
> ======================================================
>
> What I'd like instead:
>
> @Component(property = "foo=true")
> public final MyFooProvider implements FooProvider {
>
> }
>
> and from the consumer's side:
>
> @Reference(ignoreInterface = true, target="(foo=true)")
> public void setFoo(Object myFoo) {
> // introspect runtime annotations on myFoo
> // e.g for event delivery by topic.
> }
>
>
> ==== my proposal is *above* this line ^^^^^ ====
>
> And below the convoluted case. I am not very sure it really makes so
> much sense, but here it goes:
>
> Let's say that in my code, any service providing a service property
> foo=true must implement interface FooProvider, but is not required to
> declare it through the objectClass service property (it might, or not,
> have interfaces extending FooProvider as objectClass).
>
> If DS looked only for target filters rather than the "interface" XML
> attribute, I could have:
>
> @Reference(ignoreInterface = true, target="(foo=*)")
> public void setFoo(Object myFoo) {
> // check type, if some bundle provider uses the same property
> // wrongly.
> if (myFoo instanceof FooProvider) {
> FooProvider fp = (FooProvider) myFoo;
> // actually do something
> }
> }
>
> Now, as far as the framework is concerned, my bundle is using even
> disregarded services that have the "foo" property but don't implement my
> FooProvider interface. DS cannot know from the ServiceReference whether
> the service object implements FooProvider (and to be specific, the
> bundle's view of FooProvider), so it has, only when "assignableType !=
> interface" to make that check for me, and if it fails unget() that
> service specific from that component.
>
> Obviously, it would be simpler if my service implemented FooProvider AS
> WELL as its sub-interfaces.
>
> @Component
> public class MyFoo implements FooProvider, FooProviderChild {
>
> }
>
> which useless from a Java typing perspective,
>
> // OK with me, but not to many Java devs in my team
> // who want to write vanilla Java and have OSGi wrap around it,
> // than the other way around.
> @Component(service = { FooProvider.class })
> public class MyFoo implements FooProviderChild {
>
> }
>
> In real-life, I don't want to write in my APIs "please provide Object as
> an objectClass for that service because I'm using DS on the other end".
>
> With the support on DS side, unassignable service objects would not be
> "in-use" by the said component, and the reference method would look like:
>
> @Reference(ignoreInterface = true, target="(foo=*)")
> public void setFoo(FooProvider myFoo) {
> // actually do something
> }
>
> Basically, just relaxing the model further by allowing something else
> than Object to be as a parameter when using "ignoreInterface".
>
> Hope this makes sense,
> Simon
>
>
>
>>
>>> On Apr 8, 2016, at 6:23 AM, Simon Chemouil <schemouil@gmail.com> wrote:
>>>
>>> Hi,
>>>
>>> For the record I have had the same need as Jens in the past. As Neil
>>> suggested, I ended up using a ServiceTracker but this is a pity.
>>>
>>> BJ recently talked about a DS spec update. I have a few ideas
>>> (in-component control of service registration for one, to support
>>> asynchronous activations better!).
>>>
>>> To improve the situation Jens is describing, I would suggest making the
>>> "interface" attribute of the "reference" element optional, in which case
>>> only the "target" attribute would be taken into account for the filter.
>>>
>>> Now there are 2 options: either it would be up to the component
>>> developer to make sure the method parameter type is compatible with the
>>> service type (e.g use Object to be safe or another interface that he
>>> considers "implied" by a specific set of service properties), or that
>>> specific object type would become a new parameter (assignationType ?)
>>> and DS would test for "assignability" before actually binding the
>>> service if "attr(assignationType) != attr(interface)". The second design
>>> is nice, and backwards compatible (by default, assignationType = interface).
>>>
>>> The @Reference annotation might (or not) get that capability through a
>>> new parameter, false by default, such as "ignoreInterface".
>>>
>>> My use case: getting rid of ugly marker interfaces for services which a
>>> "dynamic interface" (discovered through reflection on runtime
>>> annotations). If needed I could show some pseudo-code to illustrate the
>>> pattern.
>>>
>>> I understand the KISS camp is urging for an opinionated 80/20 approach,
>>> but this is a very small update that would allow a bunch of new cool
>>> stuff. :)
>>>
>>> Cheers,
>>> Simon
>>>
>>> Le 08/04/2016 11:32, Neil Bartlett a écrit :
>>>> Hi Jens,
>>>>
>>>> Can you clarify please… are you saying that you want to inject services
of *any* type, using some kind of filter that looks at the other properties of the service
reference?
>>>>
>>>> This is an unusual requirement, and I don’t think you can do it with DS’s
event strategy. You should use a ServiceTracker instead.
>>>>
>>>> Regards,
>>>> Neil
>>>>
>>>>
>>>>> On 8 Apr 2016, at 10:23, Jens Offenbach <wolle5050@gmx.de> wrote:
>>>>>
>>>>> Sorry, but I am confronted with a new problem.
>>>>>
>>>>> I am declaring a Reference annotation on a method, but I cannot declare
a service interface. If I declare nothing than Object gets used and nothing is happening.
When I remove the interface definition from my XML descriptor, SCR validation fails with "An
interface must be declared for the reference". I have a filter expression that selects my
services, but they do not have an interface in common.
>>>>>
>>>>> I have to select some service based on a filter expression without indicating
a service interface. How is this achievable?
>>>>>
>>>>> Again... Thanks a lot for your help!
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> 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
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org <mailto:users-unsubscribe@felix.apache.org>
> For additional commands, e-mail: users-help@felix.apache.org <mailto:users-help@felix.apache.org>

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


Mime
View raw message