You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@onami.apache.org by Simone Tripodi <si...@apache.org> on 2013/01/10 21:51:14 UTC
[spi] smarter services binding
Hi all guys,
I think the main idea of services binding[1] in SPI is good but still
a little far to be complete, because what they miss are *qualifiers*,
I mean, Guice allows binding the same interface/service to multiple
instances by qualifying them via annotations, i.e.
bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
bind(CreditCardProcessor.class).annotatedWith(Names.named("Mastercard")).to(MastercardCreditCardProcessor.class);
So users can require service injection depending on bound metadata,
rather than requiring and explicit class implementation:
@Inject
@Named("Visa")
CreditCardProcessor creditCardProcessor;
Now, coming back to the current SPI implementation, it just allows
doing silly bindings, such as bind the service to the first discovered
implementation or getting all the discovered implementations, mainly
because META-INF/services files just enlist service implementation,
i.e.
file META-INF/services/org.acme.CreditCardProcessor
-----------------------------------------------------------------
org.acme.VisaCreditCardProcessor
org.acme.MastercardCreditCardProcessor
There are not qualifiers :( While at the time of coding the first
version of SPI it made me happy, now I am not longer satisfied.
We can do something better, my proposal is:
* allows specifying a set of metadata - please remind that qualifiers,
binding annotations, can be more complex rather than just @Named - in
META-INF/services files for each service, something like
file META-INF/services/org.acme.CreditCardProcessor
-----------------------------------------------------------------
org.acme.VisaCreditCardProcessor; type=Visa; version=1.0.0;
org.acme.MastercardCreditCardProcessor; type=Mastercard; version=1.5.0;
* defining a new binding annotation, something like:
@Documented
@Retention( RetentionPolicy.RUNTIME )
public @interface Property
{
String name();
String value();
@Documented
@BindingAnnotation
@Retention( RetentionPolicy.RUNTIME )
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@interface List
{
Property[] value();
}
}
in order users can request injections specifying injections like:
@Inject
@Property.List({
@Property( name="type", value="Visa" ),
@Property( name="version", value="1.0.0" )
})
CreditCardProcessor creditCardProcessor;
WDYT? Do you have any idea?
Many thanks in advance!
-Simo
[1] http://onami.incubator.apache.org/spi/services.html
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
Re: [spi][RTC] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Documentation[1] updated as well.
Please let me know if something is not clear!
Thanks,
-Simo
[1] http://onami.incubator.apache.org/spi/services.html
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
On Tue, Jan 15, 2013 at 9:07 PM, Simone Tripodi
<si...@apache.org> wrote:
> Hi guys,
>
> no objections have been shown, I am going to checkin the proposed modifications.
>
> Thanks a lot for participating in the discussion!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
>
> On Sun, Jan 13, 2013 at 5:08 PM, Simone Tripodi
> <si...@apache.org> wrote:
>> Hi all again,
>>
>> I maybe found the solution to that issue and proposed a patch on ONAMI-51.
>> Please review, if there are no objections I intend to commit it.
>>
>> I would like also to bump to a major release and break the binary
>> compatibility, since the previous version is quiet useless :)
>>
>> Many thanks in advance, all the best!
>> -Simo
>>
>> http://people.apache.org/~simonetripodi/
>> http://simonetripodi.livejournal.com/
>> http://twitter.com/simonetripodi
>> http://www.99soft.org/
>>
>>
>> On Thu, Jan 10, 2013 at 9:51 PM, Simone Tripodi
>> <si...@apache.org> wrote:
>>> Hi all guys,
>>>
>>> I think the main idea of services binding[1] in SPI is good but still
>>> a little far to be complete, because what they miss are *qualifiers*,
>>> I mean, Guice allows binding the same interface/service to multiple
>>> instances by qualifying them via annotations, i.e.
>>>
>>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
>>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Mastercard")).to(MastercardCreditCardProcessor.class);
>>>
>>> So users can require service injection depending on bound metadata,
>>> rather than requiring and explicit class implementation:
>>>
>>> @Inject
>>> @Named("Visa")
>>> CreditCardProcessor creditCardProcessor;
>>>
>>> Now, coming back to the current SPI implementation, it just allows
>>> doing silly bindings, such as bind the service to the first discovered
>>> implementation or getting all the discovered implementations, mainly
>>> because META-INF/services files just enlist service implementation,
>>> i.e.
>>>
>>> file META-INF/services/org.acme.CreditCardProcessor
>>> -----------------------------------------------------------------
>>> org.acme.VisaCreditCardProcessor
>>> org.acme.MastercardCreditCardProcessor
>>>
>>> There are not qualifiers :( While at the time of coding the first
>>> version of SPI it made me happy, now I am not longer satisfied.
>>>
>>> We can do something better, my proposal is:
>>>
>>> * allows specifying a set of metadata - please remind that qualifiers,
>>> binding annotations, can be more complex rather than just @Named - in
>>> META-INF/services files for each service, something like
>>>
>>> file META-INF/services/org.acme.CreditCardProcessor
>>> -----------------------------------------------------------------
>>> org.acme.VisaCreditCardProcessor; type=Visa; version=1.0.0;
>>> org.acme.MastercardCreditCardProcessor; type=Mastercard; version=1.5.0;
>>>
>>> * defining a new binding annotation, something like:
>>>
>>> @Documented
>>> @Retention( RetentionPolicy.RUNTIME )
>>> public @interface Property
>>> {
>>>
>>> String name();
>>>
>>> String value();
>>>
>>> @Documented
>>> @BindingAnnotation
>>> @Retention( RetentionPolicy.RUNTIME )
>>> @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
>>> @interface List
>>> {
>>> Property[] value();
>>> }
>>>
>>> }
>>>
>>> in order users can request injections specifying injections like:
>>>
>>> @Inject
>>> @Property.List({
>>> @Property( name="type", value="Visa" ),
>>> @Property( name="version", value="1.0.0" )
>>> })
>>> CreditCardProcessor creditCardProcessor;
>>>
>>> WDYT? Do you have any idea?
>>> Many thanks in advance!
>>> -Simo
>>>
>>> [1] http://onami.incubator.apache.org/spi/services.html
>>>
>>> http://people.apache.org/~simonetripodi/
>>> http://simonetripodi.livejournal.com/
>>> http://twitter.com/simonetripodi
>>> http://www.99soft.org/
Re: [spi][RTC] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Hi guys,
no objections have been shown, I am going to checkin the proposed modifications.
Thanks a lot for participating in the discussion!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
On Sun, Jan 13, 2013 at 5:08 PM, Simone Tripodi
<si...@apache.org> wrote:
> Hi all again,
>
> I maybe found the solution to that issue and proposed a patch on ONAMI-51.
> Please review, if there are no objections I intend to commit it.
>
> I would like also to bump to a major release and break the binary
> compatibility, since the previous version is quiet useless :)
>
> Many thanks in advance, all the best!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
>
> On Thu, Jan 10, 2013 at 9:51 PM, Simone Tripodi
> <si...@apache.org> wrote:
>> Hi all guys,
>>
>> I think the main idea of services binding[1] in SPI is good but still
>> a little far to be complete, because what they miss are *qualifiers*,
>> I mean, Guice allows binding the same interface/service to multiple
>> instances by qualifying them via annotations, i.e.
>>
>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Mastercard")).to(MastercardCreditCardProcessor.class);
>>
>> So users can require service injection depending on bound metadata,
>> rather than requiring and explicit class implementation:
>>
>> @Inject
>> @Named("Visa")
>> CreditCardProcessor creditCardProcessor;
>>
>> Now, coming back to the current SPI implementation, it just allows
>> doing silly bindings, such as bind the service to the first discovered
>> implementation or getting all the discovered implementations, mainly
>> because META-INF/services files just enlist service implementation,
>> i.e.
>>
>> file META-INF/services/org.acme.CreditCardProcessor
>> -----------------------------------------------------------------
>> org.acme.VisaCreditCardProcessor
>> org.acme.MastercardCreditCardProcessor
>>
>> There are not qualifiers :( While at the time of coding the first
>> version of SPI it made me happy, now I am not longer satisfied.
>>
>> We can do something better, my proposal is:
>>
>> * allows specifying a set of metadata - please remind that qualifiers,
>> binding annotations, can be more complex rather than just @Named - in
>> META-INF/services files for each service, something like
>>
>> file META-INF/services/org.acme.CreditCardProcessor
>> -----------------------------------------------------------------
>> org.acme.VisaCreditCardProcessor; type=Visa; version=1.0.0;
>> org.acme.MastercardCreditCardProcessor; type=Mastercard; version=1.5.0;
>>
>> * defining a new binding annotation, something like:
>>
>> @Documented
>> @Retention( RetentionPolicy.RUNTIME )
>> public @interface Property
>> {
>>
>> String name();
>>
>> String value();
>>
>> @Documented
>> @BindingAnnotation
>> @Retention( RetentionPolicy.RUNTIME )
>> @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
>> @interface List
>> {
>> Property[] value();
>> }
>>
>> }
>>
>> in order users can request injections specifying injections like:
>>
>> @Inject
>> @Property.List({
>> @Property( name="type", value="Visa" ),
>> @Property( name="version", value="1.0.0" )
>> })
>> CreditCardProcessor creditCardProcessor;
>>
>> WDYT? Do you have any idea?
>> Many thanks in advance!
>> -Simo
>>
>> [1] http://onami.incubator.apache.org/spi/services.html
>>
>> http://people.apache.org/~simonetripodi/
>> http://simonetripodi.livejournal.com/
>> http://twitter.com/simonetripodi
>> http://www.99soft.org/
[spi][RTC] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Hi all again,
I maybe found the solution to that issue and proposed a patch on ONAMI-51.
Please review, if there are no objections I intend to commit it.
I would like also to bump to a major release and break the binary
compatibility, since the previous version is quiet useless :)
Many thanks in advance, all the best!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
On Thu, Jan 10, 2013 at 9:51 PM, Simone Tripodi
<si...@apache.org> wrote:
> Hi all guys,
>
> I think the main idea of services binding[1] in SPI is good but still
> a little far to be complete, because what they miss are *qualifiers*,
> I mean, Guice allows binding the same interface/service to multiple
> instances by qualifying them via annotations, i.e.
>
> bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
> bind(CreditCardProcessor.class).annotatedWith(Names.named("Mastercard")).to(MastercardCreditCardProcessor.class);
>
> So users can require service injection depending on bound metadata,
> rather than requiring and explicit class implementation:
>
> @Inject
> @Named("Visa")
> CreditCardProcessor creditCardProcessor;
>
> Now, coming back to the current SPI implementation, it just allows
> doing silly bindings, such as bind the service to the first discovered
> implementation or getting all the discovered implementations, mainly
> because META-INF/services files just enlist service implementation,
> i.e.
>
> file META-INF/services/org.acme.CreditCardProcessor
> -----------------------------------------------------------------
> org.acme.VisaCreditCardProcessor
> org.acme.MastercardCreditCardProcessor
>
> There are not qualifiers :( While at the time of coding the first
> version of SPI it made me happy, now I am not longer satisfied.
>
> We can do something better, my proposal is:
>
> * allows specifying a set of metadata - please remind that qualifiers,
> binding annotations, can be more complex rather than just @Named - in
> META-INF/services files for each service, something like
>
> file META-INF/services/org.acme.CreditCardProcessor
> -----------------------------------------------------------------
> org.acme.VisaCreditCardProcessor; type=Visa; version=1.0.0;
> org.acme.MastercardCreditCardProcessor; type=Mastercard; version=1.5.0;
>
> * defining a new binding annotation, something like:
>
> @Documented
> @Retention( RetentionPolicy.RUNTIME )
> public @interface Property
> {
>
> String name();
>
> String value();
>
> @Documented
> @BindingAnnotation
> @Retention( RetentionPolicy.RUNTIME )
> @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
> @interface List
> {
> Property[] value();
> }
>
> }
>
> in order users can request injections specifying injections like:
>
> @Inject
> @Property.List({
> @Property( name="type", value="Visa" ),
> @Property( name="version", value="1.0.0" )
> })
> CreditCardProcessor creditCardProcessor;
>
> WDYT? Do you have any idea?
> Many thanks in advance!
> -Simo
>
> [1] http://onami.incubator.apache.org/spi/services.html
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Christoph Engelbert <no...@apache.org>.
Simone maybe you think about somethink like what I already did in
the FactoryAnnotation stuff ;-) Not really sure but maybe you could
have a look at the unittests to see if it works.
Am 12.01.2013 11:30, schrieb Simone Tripodi:
> Salut Eric!
>
> please forget the *version* field for a moment, as I wrote before it
> was just fake metadata that I accidentally chose just because it was
> the first it came in my mind, the purpose is only qualifying the
> discovered services implementation
>
>> You mean the version attribute of your example can be statically loaded from a properties file for example?
> It could work as well, my initial proposal was specifying the
> qualifiers directly in the META-INF/services files, i.e.
>
> file META-INF/services/org.acme.CreditCardProcessor
> -----------------------------------------------------------------
> org.acme.VisaCreditCardProcessor; type=Visa; somethingElse=value1
> org.acme.MastercardCreditCardProcessor; type=Mastercard; somethingElse=value2
>
> but at after a second thought I realized that this format would make
> that files useless with traditional ServiceLoader API... any other
> idea?
>
>> I guess the example you gave with the version is not about loading different
>> version of a same implementation, but just defining which concrete
>> implementation to choose.
> You got it! :)
>
> Any other idea is welcome!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Eric Charles <er...@apache.org>.
Hello Simo,
Ok, I'm in line with your goal, especially if myapp has simply to
bindService( AnotherProcessor.class )[.fromClassLoader(ClassLoader)];
I will think come in a few days with hopefully ideas on way to qualify
bindings.
I guess in case on absence of qualification, autobinding could be
applied (of course, if more than 1 implementation if found, an exception
should be thrown).
Thx, Eric
On 13/01/2013 12:14, Simone Tripodi wrote:
> Salut Eric!
>
>> ... but does myapp still needs to say in its module construction the
>> following?
>
> the answer is NO :)
> You just have to create the Injector by specifying which services have
> to be automatically discovered:
>
> Injector injector = createInjector( new ServiceLoaderModule()
> {
>
> @Override
> protected void configure()
> {
> bindService( CreditCardProcessor.class )[.fromClassLoader(ClassLoader)];
> ...
> bindService( AnotherProcessor.class )[.fromClassLoader(ClassLoader)];
> }
>
> } );
>
> Services implementations are defined in
> META-INF/services/org.acme.api.CreditCardProcessor file(s) - this is
> something that is already partially working, see
> <http://onami.incubator.apache.org/spi/services.html>
>
> What is missing is "just" a way to define how to qualify bindings.
>
> Thanks in advance for more feedbacks!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
>
> On Sun, Jan 13, 2013 at 12:56 PM, Eric Charles <er...@apache.org> wrote:
>> Hello Simo,
>> Ok,
>> - put the jar you want
>> - myapp defines
>>
>> @Inject
>> @Named( "Visa" )
>> private CreditCardProcessor creditCardProcessor;
>>
>> ... but does myapp still needs to say in its module construction the
>> following?
>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
>>
>> If the answer is 'no', I understand you point and I will think about it the
>> next days.
>>
>> If the answer is 'yes, myapp still needs to explictely do it', it's just
>> classical injection and we don't need extra layer.
>>
>> Thx, yes or no? :)
>> Eric
>>
>>
>>
>> On 13/01/2013 11:51, Simone Tripodi wrote:
>>>
>>> Salut Eric!
>>>
>>> On Sun, Jan 13, 2013 at 12:27 PM, Eric Charles <er...@apache.org> wrote:
>>>>
>>>> However, I miss the problem you are trying to resolve...
>>>> Are you looking for a way to put in acme-visa.jar some 'stuff', and reuse
>>>> it
>>>> in myapp.jar in the annotations, without having to redefine them in the
>>>> guide module creation.
>>>>
>>>> For example, acme-visa would define the conditions for which
>>>> VisaCreditCardProcessor would be chosen, and you simply have to call (not
>>>> definining) those?
>>>
>>>
>>> Once services are automatically discovered and bound - with qualifiers
>>> - in my application I could require for injections such as, for
>>> example:
>>>
>>> class MyApp
>>> {
>>>
>>> @Inject
>>> @Named( "Visa" )
>>> private CreditCardProcessor creditCardProcessor;
>>>
>>> }
>>>
>>> without knowing the CreditCardProcessor implementation details - just
>>> put your jars in the classpath and let's bind services without
>>> explicitly specify them.
>>>
>>> Does it help on clarifying it?
>>> TIA, all the best!
>>> -Simo
>>>
>>> http://people.apache.org/~simonetripodi/
>>> http://simonetripodi.livejournal.com/
>>> http://twitter.com/simonetripodi
>>> http://www.99soft.org/
>>>
>>
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Salut Eric!
> ... but does myapp still needs to say in its module construction the
> following?
the answer is NO :)
You just have to create the Injector by specifying which services have
to be automatically discovered:
Injector injector = createInjector( new ServiceLoaderModule()
{
@Override
protected void configure()
{
bindService( CreditCardProcessor.class )[.fromClassLoader(ClassLoader)];
...
bindService( AnotherProcessor.class )[.fromClassLoader(ClassLoader)];
}
} );
Services implementations are defined in
META-INF/services/org.acme.api.CreditCardProcessor file(s) - this is
something that is already partially working, see
<http://onami.incubator.apache.org/spi/services.html>
What is missing is "just" a way to define how to qualify bindings.
Thanks in advance for more feedbacks!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
On Sun, Jan 13, 2013 at 12:56 PM, Eric Charles <er...@apache.org> wrote:
> Hello Simo,
> Ok,
> - put the jar you want
> - myapp defines
>
> @Inject
> @Named( "Visa" )
> private CreditCardProcessor creditCardProcessor;
>
> ... but does myapp still needs to say in its module construction the
> following?
> bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
>
> If the answer is 'no', I understand you point and I will think about it the
> next days.
>
> If the answer is 'yes, myapp still needs to explictely do it', it's just
> classical injection and we don't need extra layer.
>
> Thx, yes or no? :)
> Eric
>
>
>
> On 13/01/2013 11:51, Simone Tripodi wrote:
>>
>> Salut Eric!
>>
>> On Sun, Jan 13, 2013 at 12:27 PM, Eric Charles <er...@apache.org> wrote:
>>>
>>> However, I miss the problem you are trying to resolve...
>>> Are you looking for a way to put in acme-visa.jar some 'stuff', and reuse
>>> it
>>> in myapp.jar in the annotations, without having to redefine them in the
>>> guide module creation.
>>>
>>> For example, acme-visa would define the conditions for which
>>> VisaCreditCardProcessor would be chosen, and you simply have to call (not
>>> definining) those?
>>
>>
>> Once services are automatically discovered and bound - with qualifiers
>> - in my application I could require for injections such as, for
>> example:
>>
>> class MyApp
>> {
>>
>> @Inject
>> @Named( "Visa" )
>> private CreditCardProcessor creditCardProcessor;
>>
>> }
>>
>> without knowing the CreditCardProcessor implementation details - just
>> put your jars in the classpath and let's bind services without
>> explicitly specify them.
>>
>> Does it help on clarifying it?
>> TIA, all the best!
>> -Simo
>>
>> http://people.apache.org/~simonetripodi/
>> http://simonetripodi.livejournal.com/
>> http://twitter.com/simonetripodi
>> http://www.99soft.org/
>>
>
Re: [spi] smarter services binding
Posted by Eric Charles <er...@apache.org>.
Hello Simo,
Ok,
- put the jar you want
- myapp defines
@Inject
@Named( "Visa" )
private CreditCardProcessor creditCardProcessor;
... but does myapp still needs to say in its module construction the
following?
bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
If the answer is 'no', I understand you point and I will think about it
the next days.
If the answer is 'yes, myapp still needs to explictely do it', it's just
classical injection and we don't need extra layer.
Thx, yes or no? :)
Eric
On 13/01/2013 11:51, Simone Tripodi wrote:
> Salut Eric!
>
> On Sun, Jan 13, 2013 at 12:27 PM, Eric Charles <er...@apache.org> wrote:
>> However, I miss the problem you are trying to resolve...
>> Are you looking for a way to put in acme-visa.jar some 'stuff', and reuse it
>> in myapp.jar in the annotations, without having to redefine them in the
>> guide module creation.
>>
>> For example, acme-visa would define the conditions for which
>> VisaCreditCardProcessor would be chosen, and you simply have to call (not
>> definining) those?
>
> Once services are automatically discovered and bound - with qualifiers
> - in my application I could require for injections such as, for
> example:
>
> class MyApp
> {
>
> @Inject
> @Named( "Visa" )
> private CreditCardProcessor creditCardProcessor;
>
> }
>
> without knowing the CreditCardProcessor implementation details - just
> put your jars in the classpath and let's bind services without
> explicitly specify them.
>
> Does it help on clarifying it?
> TIA, all the best!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Salut Eric!
On Sun, Jan 13, 2013 at 12:27 PM, Eric Charles <er...@apache.org> wrote:
> However, I miss the problem you are trying to resolve...
> Are you looking for a way to put in acme-visa.jar some 'stuff', and reuse it
> in myapp.jar in the annotations, without having to redefine them in the
> guide module creation.
>
> For example, acme-visa would define the conditions for which
> VisaCreditCardProcessor would be chosen, and you simply have to call (not
> definining) those?
Once services are automatically discovered and bound - with qualifiers
- in my application I could require for injections such as, for
example:
class MyApp
{
@Inject
@Named( "Visa" )
private CreditCardProcessor creditCardProcessor;
}
without knowing the CreditCardProcessor implementation details - just
put your jars in the classpath and let's bind services without
explicitly specify them.
Does it help on clarifying it?
TIA, all the best!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Eric Charles <er...@apache.org>.
Hi Simo,
I'm with you regarding the scenario setup you described.
I will take some time next week to further dig into onami modules and
also in the links Christoph sent (Mycilia...)
However, I miss the problem you are trying to resolve...
Are you looking for a way to put in acme-visa.jar some 'stuff', and
reuse it in myapp.jar in the annotations, without having to redefine
them in the guide module creation.
For example, acme-visa would define the conditions for which
VisaCreditCardProcessor would be chosen, and you simply have to call
(not definining) those?
Thx, Eric
On 13/01/2013 09:55, Simone Tripodi wrote:
> Salut Eric,
>
> thanks a lot for your thoughts, much more than appreciated! This
> helped me understanding that adding some extra metadata in
> META-INF/services files is not the right direction to address that
> problem :)
>
> Let's recap: what I wanted to add to guice, in the SPI module, is the
> ability to binding services implementation by discovering them via the
> "ServiceLoader".
> So, let's suppose we have the following service:
>
> package org.acme.api;
> public interface CreditCardProcessor {
> void doSomething();
> }
>
> contained in acme-api.jar
>
> then, we do have a PayPal implementation:
>
> package org.acme.paypal;
> public class PayPalCreditCardProcessor
> implements CreditCardProcessor
> {
> public void doSomething()
> {...}
> }
>
> defined in acme-paypal.jar, and then a MasterCard implementation:
>
> package org.acme.mastercard;
> public class MasterCardCreditCardProcessor
> implements CreditCardProcessor
> {
> public void doSomething()
> {...}
> }
>
> defined in acme-mastercard.jar.
>
> Now, the idea is binding all these implementation automagically,
> without scanning the classpath (which is something covered by
> onami-autobind), but using the ServiceLoader approach. So, let's
> immagine acme-paypal.jar content as:
>
> acme-paypal.jar
> -------------------------------------------------------------------------------
> org/acme/paypal/PayPalCreditCardProcessor.class
> META-INF/services/org.acme.api.CreditCardProcessor
>
> where org.acme.api.CreditCardProcessor contains
>
> META-INF/services/org.acme.api.CreditCardProcessor
> -------------------------------------------------------------------------------
> org.acme.paypal.PayPalCreditCardProcessor
>
> it is now easy to immagine the same scenario for the acme-mastercard.jar file.
>
> Let's suppose that our classpath is in the form of
>
> acme-api.jar:acme-paypal.jar:acme-mastercard.jar
>
> what I would like to obtain, for next version od SPI, is
>
> bind(CreditCardProcessor.class)
> .annotatedWith(?!?!??!)
> .to(PayPalCreditCardProcessor.class);
> bind(CreditCardProcessor.class)
> .annotatedWith(?!?!??!)
> .to(MasterCardCreditCardProcessor.class);
>
> The missing part are, as you can notice, the binding annotations,
> because I am looking for a way to specify qualifiers...
>
> Component configuration is out of scope for that extension.
>
> Do you have any suggestion on how to discover binding annotations as well?
>
> TIA, have a nice weekend!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
Re: [spi] smarter services binding
Posted by Eric Charles <er...@apache.org>.
On 13/01/2013 13:18, Simone Tripodi wrote:
> Salut Eric!
>
> On Sun, Jan 13, 2013 at 1:45 PM, Eric Charles <er...@apache.org> wrote:
>> My only 2-cent is that the release process would be much easier if all the
>> trunk was released as one at the same time. Yes, modules would be upgraded
>> to a newer version even if no change has been committed, but that's a
>> non-issue to me.
>>
>
> what I suggested at the time of beginning, is to avoid to bump a new
> component release with no new features/bugfix/... i.e. if 1.0.0 ==
> 1.0.1 so there's no reason to have a new release.
>
I'm just lazy and likes to let the framework do the job for me, even if
it does more it should...
Release often and early, yes, but release process are heavy and I've got
limited slots.
>>> Thanks a lot!
>>
>>
>> Thx to You for all you work, vision, great ideas and didactic explanations!
>
> I feel honoured, tr�s gentil!!! :)
> Merci et � tr�s bient�t!
A+ :)
Eric
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Salut Eric!
On Sun, Jan 13, 2013 at 1:45 PM, Eric Charles <er...@apache.org> wrote:
> My only 2-cent is that the release process would be much easier if all the
> trunk was released as one at the same time. Yes, modules would be upgraded
> to a newer version even if no change has been committed, but that's a
> non-issue to me.
>
what I suggested at the time of beginning, is to avoid to bump a new
component release with no new features/bugfix/... i.e. if 1.0.0 ==
1.0.1 so there's no reason to have a new release.
>> Thanks a lot!
>
>
> Thx to You for all you work, vision, great ideas and didactic explanations!
I feel honoured, trés gentil!!! :)
Merci et á trés bientôt!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Eric Charles <er...@apache.org>.
On 13/01/2013 12:24, Simone Tripodi wrote:
> Salut Eric!
>
>> Well, we are talking here about configurating the injection.
>> It can be injecting the expiration time for a memory cache entries, about
>> choosing Visa vs MasterCard...
>>
>> So I still like to think about injection configuration.
>>
>> Does it make sense?
>
> sure that it does! we created indeed a separated module for that
> purpose, see the Onami Configuration module
> <http://onami.incubator.apache.org/configuration/>
> What Onami Configuration misses is the configuration
> watchdog/reload/update injections, that I would discuss in a separate
> thread - every suggestion is more than welcome! :)
>
+1 to discuss watchdog/reloading/updating injections. I really need this.
> The approach we followed, while creating Onami extensions, is
> splitting functionalities in small reusable modules, rather than build
> a big monolithe, in order that our users can include just the
> feature(s) they are interested and not a complete framework.
> Another concept we kept in mind, is being strict as much as possible
> to Guice SPIs, in oder to make extensions collaborate even if they are
> not aware each other, I mean you can still discover&bind services via
> Onami SPI and inject configuration properties via Onami Configuration.
>
+1 for modularity. Each one should be able to pick any subset he likes.
But all those modules have to collaborate to provide to a user a
first-class coherent platform. That's why Onami has been created and
that's great.
My only 2-cent is that the release process would be much easier if all
the trunk was released as one at the same time. Yes, modules would be
upgraded to a newer version even if no change has been committed, but
that's a non-issue to me.
> Thanks a lot!
Thx to You for all you work, vision, great ideas and didactic explanations!
Eric
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Hi Noctarius!
>> What Onami Configuration misses is the configuration
>> watchdog/reload/update injections, that I would discuss in a separate
>> thread - every suggestion is more than welcome! :)
> But wouldn't update / reload needs some tricks like childinjectors?
I still haven't thought about that - better IMHO if we discuss it in a
new thread with the [configuration] prefix, in order to get involved
people more focused on that component.
Ideas, feedbacks, suggestions, proposals, ... everything is more than welcome :)
All the best!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Christoph Engelbert <no...@apache.org>.
Am 13.01.2013 13:24, schrieb Simone Tripodi:
> Salut Eric!
>
>> Well, we are talking here about configurating the injection.
>> It can be injecting the expiration time for a memory cache entries, about
>> choosing Visa vs MasterCard...
>>
>> So I still like to think about injection configuration.
>>
>> Does it make sense?
> sure that it does! we created indeed a separated module for that
> purpose, see the Onami Configuration module
> <http://onami.incubator.apache.org/configuration/>
> What Onami Configuration misses is the configuration
> watchdog/reload/update injections, that I would discuss in a separate
> thread - every suggestion is more than welcome! :)
But wouldn't update / reload needs some tricks like childinjectors?
> The approach we followed, while creating Onami extensions, is
> splitting functionalities in small reusable modules, rather than build
> a big monolithe, in order that our users can include just the
> feature(s) they are interested and not a complete framework.
> Another concept we kept in mind, is being strict as much as possible
> to Guice SPIs, in oder to make extensions collaborate even if they are
> not aware each other, I mean you can still discover&bind services via
> Onami SPI and inject configuration properties via Onami Configuration.
>
> Thanks a lot!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Salut Eric!
> Well, we are talking here about configurating the injection.
> It can be injecting the expiration time for a memory cache entries, about
> choosing Visa vs MasterCard...
>
> So I still like to think about injection configuration.
>
> Does it make sense?
sure that it does! we created indeed a separated module for that
purpose, see the Onami Configuration module
<http://onami.incubator.apache.org/configuration/>
What Onami Configuration misses is the configuration
watchdog/reload/update injections, that I would discuss in a separate
thread - every suggestion is more than welcome! :)
The approach we followed, while creating Onami extensions, is
splitting functionalities in small reusable modules, rather than build
a big monolithe, in order that our users can include just the
feature(s) they are interested and not a complete framework.
Another concept we kept in mind, is being strict as much as possible
to Guice SPIs, in oder to make extensions collaborate even if they are
not aware each other, I mean you can still discover&bind services via
Onami SPI and inject configuration properties via Onami Configuration.
Thanks a lot!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Eric Charles <er...@apache.org>.
On 13/01/2013 09:55, Simone Tripodi wrote:
(snip)
> The missing part are, as you can notice, the binding annotations,
> because I am looking for a way to specify qualifiers...
>
> Component configuration is out of scope for that extension.
>
Well, we are talking here about configurating the injection.
It can be injecting the expiration time for a memory cache entries,
about choosing Visa vs MasterCard...
So I still like to think about injection configuration.
Does it make sense?
Thx, Eric
> Do you have any suggestion on how to discover binding annotations as well?
>
> TIA, have a nice weekend!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Hi Noctarius!
thanks for keeping participating in the discussion - they do exactly
what onami-spi does:
>From Mycila doc:
+---------------------+
binder.bind(AgentPlugin[].class)
.toProvider(ServiceLoaderProvider.of(AgentPlugin.class).withClassLoader(ClassLoader.class))
.in(Cached20Seconds.class);
This binding creates in a cached scope for 20 seconds a list of
AgentPlugin instances on the classpath, loaded by the JDK
ServiceLoader (META-INF/services/...). When loaded, each service will
be injected with its dependencies.
+---------------------+
that is equivalent of what the Onami-SPI ServiceLoaderModule does:
+---------------------+
Injector injector = createInjector( new ServiceLoaderModule()
{
@Override
protected void configure()
{
bindService( FooService.class ).loadingAllService();
}
} );
+---------------------+
(Onami supports ClassLoader specification as well)
Nice, but that has a huge limitation, since bound service
implementation are not qualified.
Thanks!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
On Sun, Jan 13, 2013 at 11:21 AM, Christoph Engelbert
<no...@apache.org> wrote:
> Hey Simone
> here's a nice article about that:
> http://blog.mycila.com/2009/10/jdk-serviceloader-as-google-guice.html
> or: https://code.google.com/p/mycila/wiki/MycilaGuice#Service_Loader
>
> Chris
>
> Am 13.01.2013 10:55, schrieb Simone Tripodi:
>> Salut Eric,
>>
>> thanks a lot for your thoughts, much more than appreciated! This
>> helped me understanding that adding some extra metadata in
>> META-INF/services files is not the right direction to address that
>> problem :)
>>
>> Let's recap: what I wanted to add to guice, in the SPI module, is the
>> ability to binding services implementation by discovering them via the
>> "ServiceLoader".
>> So, let's suppose we have the following service:
>>
>> package org.acme.api;
>> public interface CreditCardProcessor {
>> void doSomething();
>> }
>>
>> contained in acme-api.jar
>>
>> then, we do have a PayPal implementation:
>>
>> package org.acme.paypal;
>> public class PayPalCreditCardProcessor
>> implements CreditCardProcessor
>> {
>> public void doSomething()
>> {...}
>> }
>>
>> defined in acme-paypal.jar, and then a MasterCard implementation:
>>
>> package org.acme.mastercard;
>> public class MasterCardCreditCardProcessor
>> implements CreditCardProcessor
>> {
>> public void doSomething()
>> {...}
>> }
>>
>> defined in acme-mastercard.jar.
>>
>> Now, the idea is binding all these implementation automagically,
>> without scanning the classpath (which is something covered by
>> onami-autobind), but using the ServiceLoader approach. So, let's
>> immagine acme-paypal.jar content as:
>>
>> acme-paypal.jar
>> -------------------------------------------------------------------------------
>> org/acme/paypal/PayPalCreditCardProcessor.class
>> META-INF/services/org.acme.api.CreditCardProcessor
>>
>> where org.acme.api.CreditCardProcessor contains
>>
>> META-INF/services/org.acme.api.CreditCardProcessor
>> -------------------------------------------------------------------------------
>> org.acme.paypal.PayPalCreditCardProcessor
>>
>> it is now easy to immagine the same scenario for the acme-mastercard.jar file.
>>
>> Let's suppose that our classpath is in the form of
>>
>> acme-api.jar:acme-paypal.jar:acme-mastercard.jar
>>
>> what I would like to obtain, for next version od SPI, is
>>
>> bind(CreditCardProcessor.class)
>> .annotatedWith(?!?!??!)
>> .to(PayPalCreditCardProcessor.class);
>> bind(CreditCardProcessor.class)
>> .annotatedWith(?!?!??!)
>> .to(MasterCardCreditCardProcessor.class);
>>
>> The missing part are, as you can notice, the binding annotations,
>> because I am looking for a way to specify qualifiers...
>>
>> Component configuration is out of scope for that extension.
>>
>> Do you have any suggestion on how to discover binding annotations as well?
>>
>> TIA, have a nice weekend!
>> -Simo
>>
>> http://people.apache.org/~simonetripodi/
>> http://simonetripodi.livejournal.com/
>> http://twitter.com/simonetripodi
>> http://www.99soft.org/
>
Re: [spi] smarter services binding
Posted by Christoph Engelbert <no...@apache.org>.
Hey Simone
here's a nice article about that:
http://blog.mycila.com/2009/10/jdk-serviceloader-as-google-guice.html
or: https://code.google.com/p/mycila/wiki/MycilaGuice#Service_Loader
Chris
Am 13.01.2013 10:55, schrieb Simone Tripodi:
> Salut Eric,
>
> thanks a lot for your thoughts, much more than appreciated! This
> helped me understanding that adding some extra metadata in
> META-INF/services files is not the right direction to address that
> problem :)
>
> Let's recap: what I wanted to add to guice, in the SPI module, is the
> ability to binding services implementation by discovering them via the
> "ServiceLoader".
> So, let's suppose we have the following service:
>
> package org.acme.api;
> public interface CreditCardProcessor {
> void doSomething();
> }
>
> contained in acme-api.jar
>
> then, we do have a PayPal implementation:
>
> package org.acme.paypal;
> public class PayPalCreditCardProcessor
> implements CreditCardProcessor
> {
> public void doSomething()
> {...}
> }
>
> defined in acme-paypal.jar, and then a MasterCard implementation:
>
> package org.acme.mastercard;
> public class MasterCardCreditCardProcessor
> implements CreditCardProcessor
> {
> public void doSomething()
> {...}
> }
>
> defined in acme-mastercard.jar.
>
> Now, the idea is binding all these implementation automagically,
> without scanning the classpath (which is something covered by
> onami-autobind), but using the ServiceLoader approach. So, let's
> immagine acme-paypal.jar content as:
>
> acme-paypal.jar
> -------------------------------------------------------------------------------
> org/acme/paypal/PayPalCreditCardProcessor.class
> META-INF/services/org.acme.api.CreditCardProcessor
>
> where org.acme.api.CreditCardProcessor contains
>
> META-INF/services/org.acme.api.CreditCardProcessor
> -------------------------------------------------------------------------------
> org.acme.paypal.PayPalCreditCardProcessor
>
> it is now easy to immagine the same scenario for the acme-mastercard.jar file.
>
> Let's suppose that our classpath is in the form of
>
> acme-api.jar:acme-paypal.jar:acme-mastercard.jar
>
> what I would like to obtain, for next version od SPI, is
>
> bind(CreditCardProcessor.class)
> .annotatedWith(?!?!??!)
> .to(PayPalCreditCardProcessor.class);
> bind(CreditCardProcessor.class)
> .annotatedWith(?!?!??!)
> .to(MasterCardCreditCardProcessor.class);
>
> The missing part are, as you can notice, the binding annotations,
> because I am looking for a way to specify qualifiers...
>
> Component configuration is out of scope for that extension.
>
> Do you have any suggestion on how to discover binding annotations as well?
>
> TIA, have a nice weekend!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Salut Eric,
thanks a lot for your thoughts, much more than appreciated! This
helped me understanding that adding some extra metadata in
META-INF/services files is not the right direction to address that
problem :)
Let's recap: what I wanted to add to guice, in the SPI module, is the
ability to binding services implementation by discovering them via the
"ServiceLoader".
So, let's suppose we have the following service:
package org.acme.api;
public interface CreditCardProcessor {
void doSomething();
}
contained in acme-api.jar
then, we do have a PayPal implementation:
package org.acme.paypal;
public class PayPalCreditCardProcessor
implements CreditCardProcessor
{
public void doSomething()
{...}
}
defined in acme-paypal.jar, and then a MasterCard implementation:
package org.acme.mastercard;
public class MasterCardCreditCardProcessor
implements CreditCardProcessor
{
public void doSomething()
{...}
}
defined in acme-mastercard.jar.
Now, the idea is binding all these implementation automagically,
without scanning the classpath (which is something covered by
onami-autobind), but using the ServiceLoader approach. So, let's
immagine acme-paypal.jar content as:
acme-paypal.jar
-------------------------------------------------------------------------------
org/acme/paypal/PayPalCreditCardProcessor.class
META-INF/services/org.acme.api.CreditCardProcessor
where org.acme.api.CreditCardProcessor contains
META-INF/services/org.acme.api.CreditCardProcessor
-------------------------------------------------------------------------------
org.acme.paypal.PayPalCreditCardProcessor
it is now easy to immagine the same scenario for the acme-mastercard.jar file.
Let's suppose that our classpath is in the form of
acme-api.jar:acme-paypal.jar:acme-mastercard.jar
what I would like to obtain, for next version od SPI, is
bind(CreditCardProcessor.class)
.annotatedWith(?!?!??!)
.to(PayPalCreditCardProcessor.class);
bind(CreditCardProcessor.class)
.annotatedWith(?!?!??!)
.to(MasterCardCreditCardProcessor.class);
The missing part are, as you can notice, the binding annotations,
because I am looking for a way to specify qualifiers...
Component configuration is out of scope for that extension.
Do you have any suggestion on how to discover binding annotations as well?
TIA, have a nice weekend!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Eric Charles <er...@apache.org>.
On 12/01/2013 10:30, Simone Tripodi wrote:
> Salut Eric!
>
> please forget the *version* field for a moment, as I wrote before it
> was just fake metadata that I accidentally chose just because it was
> the first it came in my mind, the purpose is only qualifying the
> discovered services implementation
>
>> You mean the version attribute of your example can be statically loaded from a properties file for example?
>
> It could work as well, my initial proposal was specifying the
> qualifiers directly in the META-INF/services files, i.e.
>
> file META-INF/services/org.acme.CreditCardProcessor
> -----------------------------------------------------------------
> org.acme.VisaCreditCardProcessor; type=Visa; somethingElse=value1
> org.acme.MastercardCreditCardProcessor; type=Mastercard; somethingElse=value2
>
> but at after a second thought I realized that this format would make
> that files useless with traditional ServiceLoader API... any other
> idea?
>
Hi Simo,
Although quite easy and understandable, this solution implies:
- Reuse/extend and already existing file, which can introduce some
confusion and lower adpation in existing SPI project (people don't like
changing something that works, and they are right).
- Format limitation (no hierarchy, bloated line...).
- Often, you want to specify the implementation, and not falling on the
first one found present in the classpath.
I've got a use case where the implementation has to be chosen via
configuration. For Apache James, we define the type of mailbox
implementation in a mailbox.conf file (can be maildir, jpa, hbase...).
All those different implementation can further be configured (the
qualifiers : e.g. (non)caching,...).
For now, we use custom spring BeanFactoryPostProcessor... but I would
love to delegate all that work to an injecting framework.
We are also using commons-configuration and one point we miss is to able
to reload the configuration (meaning to reinject I guess).
commons-configuration allows us to read the "qualifiers" from files in
an arbitrary format (so not only from the META-INF/service files).
For completeness, we are OSGIing the modules, but this will not bring
anything regarding the configuration/injection/reload.
Just thinking loud.
Thx,
Eric
>> I guess the example you gave with the version is not about loading different
>> version of a same implementation, but just defining which concrete
>> implementation to choose.
>
> You got it! :)
>
> Any other idea is welcome!
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
Salut Eric!
please forget the *version* field for a moment, as I wrote before it
was just fake metadata that I accidentally chose just because it was
the first it came in my mind, the purpose is only qualifying the
discovered services implementation
> You mean the version attribute of your example can be statically loaded from a properties file for example?
It could work as well, my initial proposal was specifying the
qualifiers directly in the META-INF/services files, i.e.
file META-INF/services/org.acme.CreditCardProcessor
-----------------------------------------------------------------
org.acme.VisaCreditCardProcessor; type=Visa; somethingElse=value1
org.acme.MastercardCreditCardProcessor; type=Mastercard; somethingElse=value2
but at after a second thought I realized that this format would make
that files useless with traditional ServiceLoader API... any other
idea?
> I guess the example you gave with the version is not about loading different
> version of a same implementation, but just defining which concrete
> implementation to choose.
You got it! :)
Any other idea is welcome!
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
Re: [spi] smarter services binding
Posted by Eric Charles <er...@apache.org>.
Hi Simon, Hi All,
See comments inline.
Thx, Eric
On 11/01/2013 08:24, Simone Tripodi wrote:
> The topic here is not binding multiple version of the same service -
> that Guice would already allow out of the box anyway, via binding
> annotations
>
Well, not really versions of the same implementation, but different
implementations.
OSGI can a bit further and defines different version of the same
implementation.
> The main issue is enabling the SPI module - services automatically
> discovered via the "ServiceLoader" pattern - to qualify discovered
> bindings.
>
> @(com.google.inject.name|javax.inject).Named is just *one* way to
> qualify bindings, this is why IMHO supporting a more complete set of
> metadata (Properties versus @Named) would help users specify more
> accurate qualifications.
>
> The "version" in my sample was just fake data - "version" is indeed a
> string value, not an hardcoded key in the annotations - to show how to
> express multiple properties.
>
You mean the version attribute of your example can be statically loaded
from a properties file for example?
@Property.List({
@Property( name="type", value="Visa" ),
@Property( name="version", value=VisaVersion.VERSION )
})
I guess the example you gave with the version is not about loading
different version of a same implementation, but just defining which
concrete implementation to choose.
> So, my question is: would a single @Named binding annotation enough
> for users to qualify their bindings?
>
> TIA,
> -Simo
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/
>
>
> On Thu, Jan 10, 2013 at 10:16 PM, Christoph Engelbert
> <no...@apache.org> wrote:
>> I would use OSGi when I need multiple version of the same service. I
>> don't think that I would use a DI framework with explicitly declared
>> version information.
>>
>> Chris
>>
>> Am 10.01.2013 21:51, schrieb Simone Tripodi:
>>> Hi all guys,
>>>
>>> I think the main idea of services binding[1] in SPI is good but still
>>> a little far to be complete, because what they miss are *qualifiers*,
>>> I mean, Guice allows binding the same interface/service to multiple
>>> instances by qualifying them via annotations, i.e.
>>>
>>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
>>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Mastercard")).to(MastercardCreditCardProcessor.class);
>>>
>>> So users can require service injection depending on bound metadata,
>>> rather than requiring and explicit class implementation:
>>>
>>> @Inject
>>> @Named("Visa")
>>> CreditCardProcessor creditCardProcessor;
>>>
>>> Now, coming back to the current SPI implementation, it just allows
>>> doing silly bindings, such as bind the service to the first discovered
>>> implementation or getting all the discovered implementations, mainly
>>> because META-INF/services files just enlist service implementation,
>>> i.e.
>>>
>>> file META-INF/services/org.acme.CreditCardProcessor
>>> -----------------------------------------------------------------
>>> org.acme.VisaCreditCardProcessor
>>> org.acme.MastercardCreditCardProcessor
>>>
>>> There are not qualifiers :( While at the time of coding the first
>>> version of SPI it made me happy, now I am not longer satisfied.
>>>
>>> We can do something better, my proposal is:
>>>
>>> * allows specifying a set of metadata - please remind that qualifiers,
>>> binding annotations, can be more complex rather than just @Named - in
>>> META-INF/services files for each service, something like
>>>
>>> file META-INF/services/org.acme.CreditCardProcessor
>>> -----------------------------------------------------------------
>>> org.acme.VisaCreditCardProcessor; type=Visa; version=1.0.0;
>>> org.acme.MastercardCreditCardProcessor; type=Mastercard; version=1.5.0;
>>>
>>> * defining a new binding annotation, something like:
>>>
>>> @Documented
>>> @Retention( RetentionPolicy.RUNTIME )
>>> public @interface Property
>>> {
>>>
>>> String name();
>>>
>>> String value();
>>>
>>> @Documented
>>> @BindingAnnotation
>>> @Retention( RetentionPolicy.RUNTIME )
>>> @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
>>> @interface List
>>> {
>>> Property[] value();
>>> }
>>>
>>> }
>>>
>>> in order users can request injections specifying injections like:
>>>
>>> @Inject
>>> @Property.List({
>>> @Property( name="type", value="Visa" ),
>>> @Property( name="version", value="1.0.0" )
>>> })
>>> CreditCardProcessor creditCardProcessor;
>>>
>>> WDYT? Do you have any idea?
>>> Many thanks in advance!
>>> -Simo
>>>
>>> [1] http://onami.incubator.apache.org/spi/services.html
>>>
>>> http://people.apache.org/~simonetripodi/
>>> http://simonetripodi.livejournal.com/
>>> http://twitter.com/simonetripodi
>>> http://www.99soft.org/
>>
Re: [spi] smarter services binding
Posted by Simone Tripodi <si...@apache.org>.
The topic here is not binding multiple version of the same service -
that Guice would already allow out of the box anyway, via binding
annotations
The main issue is enabling the SPI module - services automatically
discovered via the "ServiceLoader" pattern - to qualify discovered
bindings.
@(com.google.inject.name|javax.inject).Named is just *one* way to
qualify bindings, this is why IMHO supporting a more complete set of
metadata (Properties versus @Named) would help users specify more
accurate qualifications.
The "version" in my sample was just fake data - "version" is indeed a
string value, not an hardcoded key in the annotations - to show how to
express multiple properties.
So, my question is: would a single @Named binding annotation enough
for users to qualify their bindings?
TIA,
-Simo
http://people.apache.org/~simonetripodi/
http://simonetripodi.livejournal.com/
http://twitter.com/simonetripodi
http://www.99soft.org/
On Thu, Jan 10, 2013 at 10:16 PM, Christoph Engelbert
<no...@apache.org> wrote:
> I would use OSGi when I need multiple version of the same service. I
> don't think that I would use a DI framework with explicitly declared
> version information.
>
> Chris
>
> Am 10.01.2013 21:51, schrieb Simone Tripodi:
>> Hi all guys,
>>
>> I think the main idea of services binding[1] in SPI is good but still
>> a little far to be complete, because what they miss are *qualifiers*,
>> I mean, Guice allows binding the same interface/service to multiple
>> instances by qualifying them via annotations, i.e.
>>
>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
>> bind(CreditCardProcessor.class).annotatedWith(Names.named("Mastercard")).to(MastercardCreditCardProcessor.class);
>>
>> So users can require service injection depending on bound metadata,
>> rather than requiring and explicit class implementation:
>>
>> @Inject
>> @Named("Visa")
>> CreditCardProcessor creditCardProcessor;
>>
>> Now, coming back to the current SPI implementation, it just allows
>> doing silly bindings, such as bind the service to the first discovered
>> implementation or getting all the discovered implementations, mainly
>> because META-INF/services files just enlist service implementation,
>> i.e.
>>
>> file META-INF/services/org.acme.CreditCardProcessor
>> -----------------------------------------------------------------
>> org.acme.VisaCreditCardProcessor
>> org.acme.MastercardCreditCardProcessor
>>
>> There are not qualifiers :( While at the time of coding the first
>> version of SPI it made me happy, now I am not longer satisfied.
>>
>> We can do something better, my proposal is:
>>
>> * allows specifying a set of metadata - please remind that qualifiers,
>> binding annotations, can be more complex rather than just @Named - in
>> META-INF/services files for each service, something like
>>
>> file META-INF/services/org.acme.CreditCardProcessor
>> -----------------------------------------------------------------
>> org.acme.VisaCreditCardProcessor; type=Visa; version=1.0.0;
>> org.acme.MastercardCreditCardProcessor; type=Mastercard; version=1.5.0;
>>
>> * defining a new binding annotation, something like:
>>
>> @Documented
>> @Retention( RetentionPolicy.RUNTIME )
>> public @interface Property
>> {
>>
>> String name();
>>
>> String value();
>>
>> @Documented
>> @BindingAnnotation
>> @Retention( RetentionPolicy.RUNTIME )
>> @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
>> @interface List
>> {
>> Property[] value();
>> }
>>
>> }
>>
>> in order users can request injections specifying injections like:
>>
>> @Inject
>> @Property.List({
>> @Property( name="type", value="Visa" ),
>> @Property( name="version", value="1.0.0" )
>> })
>> CreditCardProcessor creditCardProcessor;
>>
>> WDYT? Do you have any idea?
>> Many thanks in advance!
>> -Simo
>>
>> [1] http://onami.incubator.apache.org/spi/services.html
>>
>> http://people.apache.org/~simonetripodi/
>> http://simonetripodi.livejournal.com/
>> http://twitter.com/simonetripodi
>> http://www.99soft.org/
>
Re: [spi] smarter services binding
Posted by Christoph Engelbert <no...@apache.org>.
I would use OSGi when I need multiple version of the same service. I
don't think that I would use a DI framework with explicitly declared
version information.
Chris
Am 10.01.2013 21:51, schrieb Simone Tripodi:
> Hi all guys,
>
> I think the main idea of services binding[1] in SPI is good but still
> a little far to be complete, because what they miss are *qualifiers*,
> I mean, Guice allows binding the same interface/service to multiple
> instances by qualifying them via annotations, i.e.
>
> bind(CreditCardProcessor.class).annotatedWith(Names.named("Visa")).to(VisaCreditCardProcessor.class);
> bind(CreditCardProcessor.class).annotatedWith(Names.named("Mastercard")).to(MastercardCreditCardProcessor.class);
>
> So users can require service injection depending on bound metadata,
> rather than requiring and explicit class implementation:
>
> @Inject
> @Named("Visa")
> CreditCardProcessor creditCardProcessor;
>
> Now, coming back to the current SPI implementation, it just allows
> doing silly bindings, such as bind the service to the first discovered
> implementation or getting all the discovered implementations, mainly
> because META-INF/services files just enlist service implementation,
> i.e.
>
> file META-INF/services/org.acme.CreditCardProcessor
> -----------------------------------------------------------------
> org.acme.VisaCreditCardProcessor
> org.acme.MastercardCreditCardProcessor
>
> There are not qualifiers :( While at the time of coding the first
> version of SPI it made me happy, now I am not longer satisfied.
>
> We can do something better, my proposal is:
>
> * allows specifying a set of metadata - please remind that qualifiers,
> binding annotations, can be more complex rather than just @Named - in
> META-INF/services files for each service, something like
>
> file META-INF/services/org.acme.CreditCardProcessor
> -----------------------------------------------------------------
> org.acme.VisaCreditCardProcessor; type=Visa; version=1.0.0;
> org.acme.MastercardCreditCardProcessor; type=Mastercard; version=1.5.0;
>
> * defining a new binding annotation, something like:
>
> @Documented
> @Retention( RetentionPolicy.RUNTIME )
> public @interface Property
> {
>
> String name();
>
> String value();
>
> @Documented
> @BindingAnnotation
> @Retention( RetentionPolicy.RUNTIME )
> @Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
> @interface List
> {
> Property[] value();
> }
>
> }
>
> in order users can request injections specifying injections like:
>
> @Inject
> @Property.List({
> @Property( name="type", value="Visa" ),
> @Property( name="version", value="1.0.0" )
> })
> CreditCardProcessor creditCardProcessor;
>
> WDYT? Do you have any idea?
> Many thanks in advance!
> -Simo
>
> [1] http://onami.incubator.apache.org/spi/services.html
>
> http://people.apache.org/~simonetripodi/
> http://simonetripodi.livejournal.com/
> http://twitter.com/simonetripodi
> http://www.99soft.org/