


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
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
See this Stack-over flow thread for more information on OSGi and inheritance.
java - OSGI: bundles, class inheritance and maven scope - Stack Overflow
Views
Replies
Sign in to like this content
Total Likes
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
Views
Replies
Sign in to like this content
Total Likes
Class C should implement A. Then it will work.
Views
Replies
Sign in to like this content
Total Likes
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
Views
Replies
Sign in to like this content
Total Likes
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
Views
Replies
Sign in to like this content
Total Likes
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
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
Views
Replies
Sign in to like this content
Total Likes
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
Views
Replies
Sign in to like this content
Total Likes
Looks like a much better design pattern!
Views
Replies
Sign in to like this content
Total Likes
You probably know the rule "composition over inheritance" 🙂
Views
Replies
Sign in to like this content
Total Likes
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?
Views
Replies
Sign in to like this content
Total Likes