felix-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simon Chemouil <schemo...@gmail.com>
Subject Re: [SCR] Selecting services without giving a service interface
Date Fri, 08 Apr 2016 15:07:59 GMT
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
For additional commands, e-mail: users-help@felix.apache.org


Mime
View raw message