Is it possible to inject a @reference object in a service with normal initialization? | Community
Skip to main content
Level 3
July 17, 2017
Solved

Is it possible to inject a @reference object in a service with normal initialization?

  • July 17, 2017
  • 7 replies
  • 11675 views

Hi all,

Is it possible to initialize the object in class with @reference in a service with normal java initialization?

Example:

This is the class

public class AEMUtilImpl implements AEMUtil {  

    @Reference

    private ResourceResolverFactory resourceFactory;

    @Reference

    private SlingRepository slingRepository;

}

If I'm initializing this class in another class (like a servlet) like this:

AEMUtil aem = new AEMUtilImpl();

resourceFactory and slingRepository is always null.

If I initialize like this in a servlet

@Reference

AEMUtil aem;

resourceFactory and slingRepository do get initialized and works properly.

What is the reason behind this? Is there anyway we can initialize by using the first method?

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by VeenaVikraman

Hi

   As per Apache Felix documentation Apache Felix - SCR Annotations @Reference annotation is defined as below

     @reference is used to refer any service registered in your osgi console. So until you declare your class as a service , if you try to refer it using @reference annotation it is going to return you null.

I would try to explain you in a plain language . One service can be referred only in another service.

That means, if AEMUtilImpl is a service, then all the below objects will return you a valid object.


So your code snippet should be something like below

public interface AEMUtil {

}

@Service

@Component(metatype = false)

public class AEMUtilImpl implements AEMUtil {

@Reference

    private ResourceResolverFactory resourceFactory;

    @Reference

    private SlingRepository slingRepository;

}

And in this case you should not initialize or cannot do the below

This service should be initialized in any other service as below

@Reference

AEMUtil aemUtil;

or in any Java class , you can use bundle context to get the object of the class as below

servlets - Getting OSGi services from a bundle in Sling/CQ - Stack Overflow

Hope this helps !! . Let me know if this is not what you are looking for .

Thanks

Veena

7 replies

smacdonald2008
Level 10
July 17, 2017

To use @Reference in a backend Java class - make sure you are using @Component and @Service annotations - see this article as an example --

Adobe Experience Manager Help | Injecting a DataSourcePool Service into an Adobe Experience Manager OSGi bundle

Hope this helps....

viveksachdeva
Community Advisor
Community Advisor
July 18, 2017

Your normal class is not registered in OSGi.. So you cannot use any of service in it... Even if you just use @Component annotation you can use other OSGi components in your class..

vitis90Author
Level 3
July 18, 2017

No the servlet is registered. so is the service impl but when i do

AEMService a = new AEMServiceImpl();

all the instance variables inside the impl class is null.

but when I do

@Reference

AEMService a

the instance variables inside it like

@Reference

private ResourceResolverFactory resourceFactory;

do get initalised. I was thinking if there was any work around to make first approach work

zeeshanKhan0786
Level 5
July 18, 2017

Hi Vitis,

If  i am not wrong you are calling the class from Sling servlet if it is than you can do one thing.

In the servlet you write

public class Servlet extends SlingSafeMethodsServlet {   

@Reference

private ResourceResolverFactory resourceFactory;

@Reference

    private SlingRepository slingRepository;

//your code and call your class in doGet or doPost like yourClass y = new yourClass(resourceFactory,slingRepository);

And these value in your normal class as constructur and assign these values in constructor.

VeenaVikraman
Community Advisor
VeenaVikramanCommunity AdvisorAccepted solution
Community Advisor
July 18, 2017

Hi

   As per Apache Felix documentation Apache Felix - SCR Annotations @Reference annotation is defined as below

     @reference is used to refer any service registered in your osgi console. So until you declare your class as a service , if you try to refer it using @reference annotation it is going to return you null.

I would try to explain you in a plain language . One service can be referred only in another service.

That means, if AEMUtilImpl is a service, then all the below objects will return you a valid object.


So your code snippet should be something like below

public interface AEMUtil {

}

@Service

@Component(metatype = false)

public class AEMUtilImpl implements AEMUtil {

@Reference

    private ResourceResolverFactory resourceFactory;

    @Reference

    private SlingRepository slingRepository;

}

And in this case you should not initialize or cannot do the below

This service should be initialized in any other service as below

@Reference

AEMUtil aemUtil;

or in any Java class , you can use bundle context to get the object of the class as below

servlets - Getting OSGi services from a bundle in Sling/CQ - Stack Overflow

Hope this helps !! . Let me know if this is not what you are looking for .

Thanks

Veena

Ratna_Kumar
Level 10
July 18, 2017

Awesome answer Veena_07

~Ratna

vitis90Author
Level 3
August 7, 2017

Thank you! This was very helpful.