Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session
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

Level 7

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.