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

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

Avatar

Level 4

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?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

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

View solution in original post

7 Replies

Avatar

Level 10

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 ...

Hope this helps....

Avatar

Community Advisor

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..

Avatar

Level 4

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

Avatar

Level 5

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.

Avatar

Correct answer by
Community Advisor

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

Avatar

Level 4

Thank you! This was very helpful.