Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

OSGi service and component

Avatar

Employee Advisor

Hi All,

I have created 1 interface called - Interface A and I have one implementation class called: Class B

So, Class B is implementing Interface A . After deployment of OSGI bundle I could see in /system/console/bundles -

Service ID 10437 Types: Interface A

Component Name: Class B

Component ID: 3665 (Class B)

Now, I have created 1 more service called: Class C which is extending Class B , but after deployment I am not getting similar information for Class C.

Here, Component B and component C both are in active state. To understand the relation in between Service and component I have done one small changes -

Remove - Class C extends Class B

Use - Class C implements interface A and now I can see -

Service ID 10437 Types: Interface A

Component Name: Class C

Component ID: 3663 (Class C)

Is It not good idea if I follow below approach?

Class B implements Interface

Class C extends Class B

Here, I am thinking from the service design point of view.

I am using AEM 6.3 with archtype 11 and I have used  org.osgi.service.component.annotations.Component and org.apache.felix.scr.annotations.Service.

Please correct my understanding.

Thanks

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

Hi,

the problem lies in the fact, that SCR is not designed in that way. Inheriting from a class (which is also a component) does not inherit SCR annotations / definitions.

If you want to use inheritance to have a lot of similar services implementing the same interface, you could have an AbstractComponent  B (look the SCR documentation for this) implementing the interface A, and then making Component C and D extending B. In that case the annotations (including the references) for all references in B should be usable in C and D as well.

On the other hand I have rarely seen this case actually implemented. I think that many very similar services implementing the same interface show a problematic software design.

Jörg

View solution in original post

11 Replies

Avatar

Employee Advisor

Hi Scott,

Thanks for your suggestion.

Let me explain you the issue in details -

1.

@Component

@Service(value = { A.class })

Class B implements Interface A

{

@Refereence

Service D

}

2. @Component

   @Service

   Class C extends Class B

   {

   getting null for Service D

   }

  

   I have only one bundle.

Thanks

Avatar

Level 10

Class C should implement A. Then it will work.

Avatar

Employee Advisor

Hi Scott,

As you have suggested I have used the same and it's working.

But, I don't want that Class C should implements A.

So, I have referred http://www.computepatterns.com/76/osgi-component-vs-service-in-aem/ and

tried to refer/call other service from component Class C

@Component

Class C

{

@Reference

Service D d;

}

But still is getting "d" as null.

Thanks,

Debal

Avatar

Level 10

I have never tried this - always Class B implements Interface A. Never any issues,

However - have you tried this:

public class C extends B implements A

try that

Avatar

Correct answer by
Employee Advisor

Hi,

the problem lies in the fact, that SCR is not designed in that way. Inheriting from a class (which is also a component) does not inherit SCR annotations / definitions.

If you want to use inheritance to have a lot of similar services implementing the same interface, you could have an AbstractComponent  B (look the SCR documentation for this) implementing the interface A, and then making Component C and D extending B. In that case the annotations (including the references) for all references in B should be usable in C and D as well.

On the other hand I have rarely seen this case actually implemented. I think that many very similar services implementing the same interface show a problematic software design.

Jörg

Avatar

Employee Advisor

Hi,

Thanks for your suggestion.

I have referred following links: Apache Felix - SCR Annotations and https://searchcode.com/codesearch/view/17572101/ to get understanding of componentAbstract attribute.

As I am using maven archtype 11 so, I have used org.osgi.service.component.annotations.Component. But, I am not getting attribute called:componentAbstract.

I could see attribute called:componentAbstract for org.apache.felix.scr.annotations.Component.

Have reffered:https://stackoverflow.com/questions/41280061/abstract-components-via-org-osgi-service-component-anno... to get Abstract components via org.osgi.service.component annotations.

Do you have any other suggestion.

Thanks,

Debal

Avatar

Employee Advisor

Hi,

Thanks for your suggestion.

I would like to say sorry that I couldn't reveal the requirement completely. But, to achieve the requirement I have created separate interface.

So, now my design is looking as below -

1.

@Component

@Service(value = { A.class })

Class B implements Interface A

{

@Refereence

Service D

}

2.

@Component

@Service(value = { D.class })

Class C implements Interface E

{

@Refereence

Service D

}

3.

ClassF extends SlingAllMethodsServlet

{

@Refereence

Service A

@Refereence

Service E

}

Thanks,

Debal

Avatar

Level 10

Looks like a much better design pattern!

Avatar

Employee Advisor

You probably know the rule "composition over inheritance" :-)

Avatar

Level 2

my understanding is you want to get the service in another service ( which is like a dependency injection). please use this links to get an idea of injecting the osgi services  AEM Quick & Easy Solutions :): How to get OSGI Service reference in AEM?