You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Steve Runion <St...@myfuelmaster.com> on 2021/06/16 20:57:10 UTC

@Component and @AspectService not playing nice

My company has used activators for quite some time, instead of annotations, due to a perceived inability for the annotations to fit our needs.

I have cornered the use case that is reported to be the challenge. We have services that are both aspects on services by their interfaces and also implement another (common) interface which are whiteboarded in elsewhere. The plumbing to get that to work would look like…

@AspectService(ranking = 10, service = AimEncryptionKeyService.class)
@Component(provides = EntitySynchronizer.class)

… however it seems as if these two annotations are not intended to be used as the same time. Whichever one is first is applied and the second is ignored. Is anyone aware of a workaround, or an idiomatic way, to get this scenario to work?




Re: @Component and @AspectService not playing nice

Posted by Steve Runion <St...@myfuelmaster.com>.
Pierre,
  Thanks for the solution. My goal is remove boilerplate in our system by ditching activators where possible, using the annotations. This solution, while slightly manual, is a major step in the right direction and might be automatable using inheritance.
________________________________
From: Pierre De Rop <pi...@gmail.com>
Sent: Thursday, June 17, 2021 9:49 AM
To: users@felix.apache.org <us...@felix.apache.org>
Subject: Re: @Component and @AspectService not playing nice

CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.


Hi Steve,

You are correct. I just checked, and indeed, what you are describing can be
done using the DM api, but it's not supported when using annotations.
As a work around, you can do the following: in your SomeDomainSpecificClass
aspect implementation, you can manually register the aspect service using
a  bundle context, like this:

(I assume the "SomeDomainSpecificClassAspect" is the implementation of your
SomeDomainSpecificClass aspect:

import org.apache.felix.dm.annotation.api.AspectService;
import org.apache.felix.dm.annotation.api.Inject;
import org.apache.felix.dm.annotation.api.Start;
import org.osgi.framework.BundleContext;

@AspectService(ranking = 10, service=SomeDomainSpecificClass.class)
public class SomeDomainSpecificClassAspect implements
SomeDomainSpecificClass, EntitySynchronizer {

    @Inject
    BundleContext bc;

    @Start
    void start() {
        bc.registerService(EntitySynchronizer.class, this, null);
    }

}

Doing so will register the aspect implementation also as an
EntitySynchronizer service.
Would this work around be fine for you ? let me know.

thanks
/pierre


On Thu, Jun 17, 2021 at 2:23 PM Steve Runion <St...@myfuelmaster.com>
wrote:

> ....
> AspectComponent =
> getDependencyManager().createAspectComponent().setAspect(SomeDomainSpecificClass.class,
> null, 10)
> component.setInterface(EntitySynchronizer.class, properties);
> component
>       .add(getDependencyManager()
>             .createServiceDependency()
>             .setService(EventMediator.class)
>             .setRequired(true))
>       .add(getDependencyManager()
>             .createServiceDependency()
>             .setService(LogService.class)
>             .setRequired(false));
> return component;
>
> For example this is what one of our Activators look like. Our component
> aspects <aspectedInterface> and also implements EntitySynchronizer. There
> are other services (only a handful AFAIK) that whiteboard in
> EntitySynchronizers and monitor the health of them by that interface.
>
>
> ________________________________
> From: Steve Runion <St...@myfuelmaster.com>
> Sent: Thursday, June 17, 2021 5:18 AM
> To: users@felix.apache.org <us...@felix.apache.org>
> Subject: Re: @Component and @AspectService not playing nice
>
> CAUTION: This email originated from outside of the organization. Do not
> click links or open attachments unless you recognize the sender and know
> the content is safe.
>
>
> Thanks for the responses.
>
> From what I am reading out usage where we have services that are both
> interceptors (aspects) and services (in their own right) that are white
> boarded in is atypical. I could probably work around this by adding service
> properties (or use one of the ones we are already adding to the aspect) to
> get around the need for these to both be aspects and components.
>
> Get Outlook for iOS<
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Faka.ms%2Fo0ukef&amp;data=04%7C01%7CSteve.Runion%40myfuelmaster.com%7C7ef40ae69c2840022a9b08d93196cbc6%7Cdd4cdb5b3a504947bce6dd41ce3544d6%7C1%7C0%7C637595346044797827%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=ipcNj4lU%2F1IFntbrRHHnQEOTvsZugAReUtIb8ijXpC0%3D&amp;reserved=0
> >
> ________________________________
> From: Pierre De Rop <pi...@gmail.com>
> Sent: Thursday, June 17, 2021 2:16:43 AM
> To: users@felix.apache.org <us...@felix.apache.org>
> Subject: Re: @Component and @AspectService not playing nice
>
> CAUTION: This email originated from outside of the organization. Do not
> click links or open attachments unless you recognize the sender and know
> the content is safe.
>
>
> Hello Steve,
>
> These annotations are part of the Felix DependencyManager (DM) annotaitons.
>
> So, the two annotations can't be mixed.  @AspectService are specialized
> DependencyManager components (like @AdapterService,
> or @BundleAdapterService), and can be used to dynamically define an
> interceptor (or a chain of interceptors) between a service consumer and a
> service provider.
>
> You will define the service consumer and the service provider using
> DM @Components annotations, but you will define the interceptors using
> the @AspectService annotation.
>
> Example: let's say you have a Database service provider interface.
> Something like:
>
> public interface Database {
>     String getObject(String key);
> }
>
> The implementation will be defined using @Component annotation:
>
> @Component
> public class DatabaseImpl implements Database {
>     public String getObject(String key) { /* implementation */ }
> }
>
> Then if you want to define an aspect that provides a caching for your
> Database service, you will define it like this with only the
> @AspectService:
> (AspectService are like Components, and can use @ServiceDependency
> annotations, if they need to depend on something).
>
> @AspectService
> public class DatabaseCache implements Database {
>
>      // The service we are intercepting (injected by reflection)
>      volatile Database database;
>
>     public String getObject(String key) {
>         // returns keys from our cache, else return
> database.getObject(key);
>     }
> }
>
> You can chain multiple aspects that will be ordered using the ranking
> annotation attribute, like @AspectService(ranking=10). Once the Database
> original service is registered, then the DatabaseCache interceptor will be
> instantiated, and registered.
>
> The above example corresponds to the following that is using the original
> DM API:
>
> public class Activator extends DependencyActivatorBase {
>      &Override
>      public void init(BundleContext context, DependencyManager dm) throws
> Exception {
>          Component aspectComponent = createAspectComponent()
>              .setAspect(Database.class, null, 10)
>              .setImplementation(DatabaseCache.class):
>          dm.add(aspectComponent);
>      }
> }
>
> or  if you are using the DM lambda API:
>
> public class Activator extends DependencyManagerActivator {
>     public void init(BundleContext ctx, DependencyManager dm) throws
> Exception {
>         aspect(Database.class, aspect ->
> aspect.impl(DatabaseCache.class).rank(10));
>     }
> }
>
> Hope this helps.
>
> kind regards
> /pierre
>
> On Thu, Jun 17, 2021 at 2:25 AM David Jencks <da...@gmail.com>
> wrote:
>
> > I’m used to the DS OSGI spec @Component annotation but I guess you are
> > using the DM annotations and not DS?
> >
> > David Jencks
> >
> > > On Jun 16, 2021, at 1:57 PM, Steve Runion <
> Steve.Runion@myfuelmaster.com>
> > wrote:
> > >
> > > My company has used activators for quite some time, instead of
> > annotations, due to a perceived inability for the annotations to fit our
> > needs.
> > >
> > > I have cornered the use case that is reported to be the challenge. We
> > have services that are both aspects on services by their interfaces and
> > also implement another (common) interface which are whiteboarded in
> > elsewhere. The plumbing to get that to work would look like…
> > >
> > > @AspectService(ranking = 10, service = AimEncryptionKeyService.class)
> > > @Component(provides = EntitySynchronizer.class)
> > >
> > > … however it seems as if these two annotations are not intended to be
> > used as the same time. Whichever one is first is applied and the second
> is
> > ignored. Is anyone aware of a workaround, or an idiomatic way, to get
> this
> > scenario to work?
> > >
> > >
> > >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> > For additional commands, e-mail: users-help@felix.apache.org
> >
> >
>

Re: @Component and @AspectService not playing nice

Posted by Pierre De Rop <pi...@gmail.com>.
Hi Steve,

You are correct. I just checked, and indeed, what you are describing can be
done using the DM api, but it's not supported when using annotations.
As a work around, you can do the following: in your SomeDomainSpecificClass
aspect implementation, you can manually register the aspect service using
a  bundle context, like this:

(I assume the "SomeDomainSpecificClassAspect" is the implementation of your
SomeDomainSpecificClass aspect:

import org.apache.felix.dm.annotation.api.AspectService;
import org.apache.felix.dm.annotation.api.Inject;
import org.apache.felix.dm.annotation.api.Start;
import org.osgi.framework.BundleContext;

@AspectService(ranking = 10, service=SomeDomainSpecificClass.class)
public class SomeDomainSpecificClassAspect implements
SomeDomainSpecificClass, EntitySynchronizer {

    @Inject
    BundleContext bc;

    @Start
    void start() {
        bc.registerService(EntitySynchronizer.class, this, null);
    }

}

Doing so will register the aspect implementation also as an
EntitySynchronizer service.
Would this work around be fine for you ? let me know.

thanks
/pierre


On Thu, Jun 17, 2021 at 2:23 PM Steve Runion <St...@myfuelmaster.com>
wrote:

> ....
> AspectComponent =
> getDependencyManager().createAspectComponent().setAspect(SomeDomainSpecificClass.class,
> null, 10)
> component.setInterface(EntitySynchronizer.class, properties);
> component
>       .add(getDependencyManager()
>             .createServiceDependency()
>             .setService(EventMediator.class)
>             .setRequired(true))
>       .add(getDependencyManager()
>             .createServiceDependency()
>             .setService(LogService.class)
>             .setRequired(false));
> return component;
>
> For example this is what one of our Activators look like. Our component
> aspects <aspectedInterface> and also implements EntitySynchronizer. There
> are other services (only a handful AFAIK) that whiteboard in
> EntitySynchronizers and monitor the health of them by that interface.
>
>
> ________________________________
> From: Steve Runion <St...@myfuelmaster.com>
> Sent: Thursday, June 17, 2021 5:18 AM
> To: users@felix.apache.org <us...@felix.apache.org>
> Subject: Re: @Component and @AspectService not playing nice
>
> CAUTION: This email originated from outside of the organization. Do not
> click links or open attachments unless you recognize the sender and know
> the content is safe.
>
>
> Thanks for the responses.
>
> From what I am reading out usage where we have services that are both
> interceptors (aspects) and services (in their own right) that are white
> boarded in is atypical. I could probably work around this by adding service
> properties (or use one of the ones we are already adding to the aspect) to
> get around the need for these to both be aspects and components.
>
> Get Outlook for iOS<
> https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Faka.ms%2Fo0ukef&amp;data=04%7C01%7CSteve.Runion%40myfuelmaster.com%7C6d55595d4a504b74faab08d93170d9f4%7Cdd4cdb5b3a504947bce6dd41ce3544d6%7C1%7C0%7C637595183055109113%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=tLgoMcg04W6f6jcTM5GxoOw3uoWPB5ub%2Fm1etBr0AW0%3D&amp;reserved=0
> >
> ________________________________
> From: Pierre De Rop <pi...@gmail.com>
> Sent: Thursday, June 17, 2021 2:16:43 AM
> To: users@felix.apache.org <us...@felix.apache.org>
> Subject: Re: @Component and @AspectService not playing nice
>
> CAUTION: This email originated from outside of the organization. Do not
> click links or open attachments unless you recognize the sender and know
> the content is safe.
>
>
> Hello Steve,
>
> These annotations are part of the Felix DependencyManager (DM) annotaitons.
>
> So, the two annotations can't be mixed.  @AspectService are specialized
> DependencyManager components (like @AdapterService,
> or @BundleAdapterService), and can be used to dynamically define an
> interceptor (or a chain of interceptors) between a service consumer and a
> service provider.
>
> You will define the service consumer and the service provider using
> DM @Components annotations, but you will define the interceptors using
> the @AspectService annotation.
>
> Example: let's say you have a Database service provider interface.
> Something like:
>
> public interface Database {
>     String getObject(String key);
> }
>
> The implementation will be defined using @Component annotation:
>
> @Component
> public class DatabaseImpl implements Database {
>     public String getObject(String key) { /* implementation */ }
> }
>
> Then if you want to define an aspect that provides a caching for your
> Database service, you will define it like this with only the
> @AspectService:
> (AspectService are like Components, and can use @ServiceDependency
> annotations, if they need to depend on something).
>
> @AspectService
> public class DatabaseCache implements Database {
>
>      // The service we are intercepting (injected by reflection)
>      volatile Database database;
>
>     public String getObject(String key) {
>         // returns keys from our cache, else return
> database.getObject(key);
>     }
> }
>
> You can chain multiple aspects that will be ordered using the ranking
> annotation attribute, like @AspectService(ranking=10). Once the Database
> original service is registered, then the DatabaseCache interceptor will be
> instantiated, and registered.
>
> The above example corresponds to the following that is using the original
> DM API:
>
> public class Activator extends DependencyActivatorBase {
>      &Override
>      public void init(BundleContext context, DependencyManager dm) throws
> Exception {
>          Component aspectComponent = createAspectComponent()
>              .setAspect(Database.class, null, 10)
>              .setImplementation(DatabaseCache.class):
>          dm.add(aspectComponent);
>      }
> }
>
> or  if you are using the DM lambda API:
>
> public class Activator extends DependencyManagerActivator {
>     public void init(BundleContext ctx, DependencyManager dm) throws
> Exception {
>         aspect(Database.class, aspect ->
> aspect.impl(DatabaseCache.class).rank(10));
>     }
> }
>
> Hope this helps.
>
> kind regards
> /pierre
>
> On Thu, Jun 17, 2021 at 2:25 AM David Jencks <da...@gmail.com>
> wrote:
>
> > I’m used to the DS OSGI spec @Component annotation but I guess you are
> > using the DM annotations and not DS?
> >
> > David Jencks
> >
> > > On Jun 16, 2021, at 1:57 PM, Steve Runion <
> Steve.Runion@myfuelmaster.com>
> > wrote:
> > >
> > > My company has used activators for quite some time, instead of
> > annotations, due to a perceived inability for the annotations to fit our
> > needs.
> > >
> > > I have cornered the use case that is reported to be the challenge. We
> > have services that are both aspects on services by their interfaces and
> > also implement another (common) interface which are whiteboarded in
> > elsewhere. The plumbing to get that to work would look like…
> > >
> > > @AspectService(ranking = 10, service = AimEncryptionKeyService.class)
> > > @Component(provides = EntitySynchronizer.class)
> > >
> > > … however it seems as if these two annotations are not intended to be
> > used as the same time. Whichever one is first is applied and the second
> is
> > ignored. Is anyone aware of a workaround, or an idiomatic way, to get
> this
> > scenario to work?
> > >
> > >
> > >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> > For additional commands, e-mail: users-help@felix.apache.org
> >
> >
>

Re: @Component and @AspectService not playing nice

Posted by Steve Runion <St...@myfuelmaster.com>.
....
AspectComponent = getDependencyManager().createAspectComponent().setAspect(SomeDomainSpecificClass.class, null, 10)
component.setInterface(EntitySynchronizer.class, properties);
component
      .add(getDependencyManager()
            .createServiceDependency()
            .setService(EventMediator.class)
            .setRequired(true))
      .add(getDependencyManager()
            .createServiceDependency()
            .setService(LogService.class)
            .setRequired(false));
return component;

For example this is what one of our Activators look like. Our component aspects <aspectedInterface> and also implements EntitySynchronizer. There are other services (only a handful AFAIK) that whiteboard in EntitySynchronizers and monitor the health of them by that interface.


________________________________
From: Steve Runion <St...@myfuelmaster.com>
Sent: Thursday, June 17, 2021 5:18 AM
To: users@felix.apache.org <us...@felix.apache.org>
Subject: Re: @Component and @AspectService not playing nice

CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.


Thanks for the responses.

From what I am reading out usage where we have services that are both interceptors (aspects) and services (in their own right) that are white boarded in is atypical. I could probably work around this by adding service properties (or use one of the ones we are already adding to the aspect) to get around the need for these to both be aspects and components.

Get Outlook for iOS<https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Faka.ms%2Fo0ukef&amp;data=04%7C01%7CSteve.Runion%40myfuelmaster.com%7C6d55595d4a504b74faab08d93170d9f4%7Cdd4cdb5b3a504947bce6dd41ce3544d6%7C1%7C0%7C637595183055109113%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&amp;sdata=tLgoMcg04W6f6jcTM5GxoOw3uoWPB5ub%2Fm1etBr0AW0%3D&amp;reserved=0>
________________________________
From: Pierre De Rop <pi...@gmail.com>
Sent: Thursday, June 17, 2021 2:16:43 AM
To: users@felix.apache.org <us...@felix.apache.org>
Subject: Re: @Component and @AspectService not playing nice

CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.


Hello Steve,

These annotations are part of the Felix DependencyManager (DM) annotaitons.

So, the two annotations can't be mixed.  @AspectService are specialized
DependencyManager components (like @AdapterService,
or @BundleAdapterService), and can be used to dynamically define an
interceptor (or a chain of interceptors) between a service consumer and a
service provider.

You will define the service consumer and the service provider using
DM @Components annotations, but you will define the interceptors using
the @AspectService annotation.

Example: let's say you have a Database service provider interface.
Something like:

public interface Database {
    String getObject(String key);
}

The implementation will be defined using @Component annotation:

@Component
public class DatabaseImpl implements Database {
    public String getObject(String key) { /* implementation */ }
}

Then if you want to define an aspect that provides a caching for your
Database service, you will define it like this with only the @AspectService:
(AspectService are like Components, and can use @ServiceDependency
annotations, if they need to depend on something).

@AspectService
public class DatabaseCache implements Database {

     // The service we are intercepting (injected by reflection)
     volatile Database database;

    public String getObject(String key) {
        // returns keys from our cache, else return database.getObject(key);
    }
}

You can chain multiple aspects that will be ordered using the ranking
annotation attribute, like @AspectService(ranking=10). Once the Database
original service is registered, then the DatabaseCache interceptor will be
instantiated, and registered.

The above example corresponds to the following that is using the original
DM API:

public class Activator extends DependencyActivatorBase {
     &Override
     public void init(BundleContext context, DependencyManager dm) throws
Exception {
         Component aspectComponent = createAspectComponent()
             .setAspect(Database.class, null, 10)
             .setImplementation(DatabaseCache.class):
         dm.add(aspectComponent);
     }
}

or  if you are using the DM lambda API:

public class Activator extends DependencyManagerActivator {
    public void init(BundleContext ctx, DependencyManager dm) throws
Exception {
        aspect(Database.class, aspect ->
aspect.impl(DatabaseCache.class).rank(10));
    }
}

Hope this helps.

kind regards
/pierre

On Thu, Jun 17, 2021 at 2:25 AM David Jencks <da...@gmail.com>
wrote:

> I’m used to the DS OSGI spec @Component annotation but I guess you are
> using the DM annotations and not DS?
>
> David Jencks
>
> > On Jun 16, 2021, at 1:57 PM, Steve Runion <St...@myfuelmaster.com>
> wrote:
> >
> > My company has used activators for quite some time, instead of
> annotations, due to a perceived inability for the annotations to fit our
> needs.
> >
> > I have cornered the use case that is reported to be the challenge. We
> have services that are both aspects on services by their interfaces and
> also implement another (common) interface which are whiteboarded in
> elsewhere. The plumbing to get that to work would look like…
> >
> > @AspectService(ranking = 10, service = AimEncryptionKeyService.class)
> > @Component(provides = EntitySynchronizer.class)
> >
> > … however it seems as if these two annotations are not intended to be
> used as the same time. Whichever one is first is applied and the second is
> ignored. Is anyone aware of a workaround, or an idiomatic way, to get this
> scenario to work?
> >
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: @Component and @AspectService not playing nice

Posted by Steve Runion <St...@myfuelmaster.com>.
Thanks for the responses.

From what I am reading out usage where we have services that are both interceptors (aspects) and services (in their own right) that are white boarded in is atypical. I could probably work around this by adding service properties (or use one of the ones we are already adding to the aspect) to get around the need for these to both be aspects and components.

Get Outlook for iOS<https://aka.ms/o0ukef>
________________________________
From: Pierre De Rop <pi...@gmail.com>
Sent: Thursday, June 17, 2021 2:16:43 AM
To: users@felix.apache.org <us...@felix.apache.org>
Subject: Re: @Component and @AspectService not playing nice

CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe.


Hello Steve,

These annotations are part of the Felix DependencyManager (DM) annotaitons.

So, the two annotations can't be mixed.  @AspectService are specialized
DependencyManager components (like @AdapterService,
or @BundleAdapterService), and can be used to dynamically define an
interceptor (or a chain of interceptors) between a service consumer and a
service provider.

You will define the service consumer and the service provider using
DM @Components annotations, but you will define the interceptors using
the @AspectService annotation.

Example: let's say you have a Database service provider interface.
Something like:

public interface Database {
    String getObject(String key);
}

The implementation will be defined using @Component annotation:

@Component
public class DatabaseImpl implements Database {
    public String getObject(String key) { /* implementation */ }
}

Then if you want to define an aspect that provides a caching for your
Database service, you will define it like this with only the @AspectService:
(AspectService are like Components, and can use @ServiceDependency
annotations, if they need to depend on something).

@AspectService
public class DatabaseCache implements Database {

     // The service we are intercepting (injected by reflection)
     volatile Database database;

    public String getObject(String key) {
        // returns keys from our cache, else return database.getObject(key);
    }
}

You can chain multiple aspects that will be ordered using the ranking
annotation attribute, like @AspectService(ranking=10). Once the Database
original service is registered, then the DatabaseCache interceptor will be
instantiated, and registered.

The above example corresponds to the following that is using the original
DM API:

public class Activator extends DependencyActivatorBase {
     &Override
     public void init(BundleContext context, DependencyManager dm) throws
Exception {
         Component aspectComponent = createAspectComponent()
             .setAspect(Database.class, null, 10)
             .setImplementation(DatabaseCache.class):
         dm.add(aspectComponent);
     }
}

or  if you are using the DM lambda API:

public class Activator extends DependencyManagerActivator {
    public void init(BundleContext ctx, DependencyManager dm) throws
Exception {
        aspect(Database.class, aspect ->
aspect.impl(DatabaseCache.class).rank(10));
    }
}

Hope this helps.

kind regards
/pierre

On Thu, Jun 17, 2021 at 2:25 AM David Jencks <da...@gmail.com>
wrote:

> I’m used to the DS OSGI spec @Component annotation but I guess you are
> using the DM annotations and not DS?
>
> David Jencks
>
> > On Jun 16, 2021, at 1:57 PM, Steve Runion <St...@myfuelmaster.com>
> wrote:
> >
> > My company has used activators for quite some time, instead of
> annotations, due to a perceived inability for the annotations to fit our
> needs.
> >
> > I have cornered the use case that is reported to be the challenge. We
> have services that are both aspects on services by their interfaces and
> also implement another (common) interface which are whiteboarded in
> elsewhere. The plumbing to get that to work would look like…
> >
> > @AspectService(ranking = 10, service = AimEncryptionKeyService.class)
> > @Component(provides = EntitySynchronizer.class)
> >
> > … however it seems as if these two annotations are not intended to be
> used as the same time. Whichever one is first is applied and the second is
> ignored. Is anyone aware of a workaround, or an idiomatic way, to get this
> scenario to work?
> >
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: @Component and @AspectService not playing nice

Posted by Pierre De Rop <pi...@gmail.com>.
Hello Steve,

These annotations are part of the Felix DependencyManager (DM) annotaitons.

So, the two annotations can't be mixed.  @AspectService are specialized
DependencyManager components (like @AdapterService,
or @BundleAdapterService), and can be used to dynamically define an
interceptor (or a chain of interceptors) between a service consumer and a
service provider.

You will define the service consumer and the service provider using
DM @Components annotations, but you will define the interceptors using
the @AspectService annotation.

Example: let's say you have a Database service provider interface.
Something like:

public interface Database {
    String getObject(String key);
}

The implementation will be defined using @Component annotation:

@Component
public class DatabaseImpl implements Database {
    public String getObject(String key) { /* implementation */ }
}

Then if you want to define an aspect that provides a caching for your
Database service, you will define it like this with only the @AspectService:
(AspectService are like Components, and can use @ServiceDependency
annotations, if they need to depend on something).

@AspectService
public class DatabaseCache implements Database {

     // The service we are intercepting (injected by reflection)
     volatile Database database;

    public String getObject(String key) {
        // returns keys from our cache, else return database.getObject(key);
    }
}

You can chain multiple aspects that will be ordered using the ranking
annotation attribute, like @AspectService(ranking=10). Once the Database
original service is registered, then the DatabaseCache interceptor will be
instantiated, and registered.

The above example corresponds to the following that is using the original
DM API:

public class Activator extends DependencyActivatorBase {
     &Override
     public void init(BundleContext context, DependencyManager dm) throws
Exception {
         Component aspectComponent = createAspectComponent()
             .setAspect(Database.class, null, 10)
             .setImplementation(DatabaseCache.class):
         dm.add(aspectComponent);
     }
}

or  if you are using the DM lambda API:

public class Activator extends DependencyManagerActivator {
    public void init(BundleContext ctx, DependencyManager dm) throws
Exception {
        aspect(Database.class, aspect ->
aspect.impl(DatabaseCache.class).rank(10));
    }
}

Hope this helps.

kind regards
/pierre

On Thu, Jun 17, 2021 at 2:25 AM David Jencks <da...@gmail.com>
wrote:

> I’m used to the DS OSGI spec @Component annotation but I guess you are
> using the DM annotations and not DS?
>
> David Jencks
>
> > On Jun 16, 2021, at 1:57 PM, Steve Runion <St...@myfuelmaster.com>
> wrote:
> >
> > My company has used activators for quite some time, instead of
> annotations, due to a perceived inability for the annotations to fit our
> needs.
> >
> > I have cornered the use case that is reported to be the challenge. We
> have services that are both aspects on services by their interfaces and
> also implement another (common) interface which are whiteboarded in
> elsewhere. The plumbing to get that to work would look like…
> >
> > @AspectService(ranking = 10, service = AimEncryptionKeyService.class)
> > @Component(provides = EntitySynchronizer.class)
> >
> > … however it seems as if these two annotations are not intended to be
> used as the same time. Whichever one is first is applied and the second is
> ignored. Is anyone aware of a workaround, or an idiomatic way, to get this
> scenario to work?
> >
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
> For additional commands, e-mail: users-help@felix.apache.org
>
>

Re: @Component and @AspectService not playing nice

Posted by David Jencks <da...@gmail.com>.
I’m used to the DS OSGI spec @Component annotation but I guess you are using the DM annotations and not DS?

David Jencks

> On Jun 16, 2021, at 1:57 PM, Steve Runion <St...@myfuelmaster.com> wrote:
> 
> My company has used activators for quite some time, instead of annotations, due to a perceived inability for the annotations to fit our needs.
> 
> I have cornered the use case that is reported to be the challenge. We have services that are both aspects on services by their interfaces and also implement another (common) interface which are whiteboarded in elsewhere. The plumbing to get that to work would look like…
> 
> @AspectService(ranking = 10, service = AimEncryptionKeyService.class)
> @Component(provides = EntitySynchronizer.class)
> 
> … however it seems as if these two annotations are not intended to be used as the same time. Whichever one is first is applied and the second is ignored. Is anyone aware of a workaround, or an idiomatic way, to get this scenario to work?
> 
> 
> 


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