Expand my Community achievements bar.

Guidelines for the Responsible Use of Generative AI in the Experience Cloud Community.
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?