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
Solved! Go to Solution.
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
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
Total Likes
Class C should implement A. Then it will work.
Views
Replies
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
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
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
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
Total Likes
Looks like a much better design pattern!
Views
Replies
Total Likes
You probably know the rule "composition over inheritance" :-)
Views
Replies
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
Total Likes
Views
Likes
Replies