AEM6.4 @Reference not working in SlingServlet

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

01-04-2019

Hi  All,

My sling servlet is not working as soon as i add

@Reference in it, otherwise it works fine

Below is the servlet code, i have create custom configuration as per the AEM6.4 standards(one @Interface class, one Interface class, one Impl class with proper annotations(org.osgi.service.component.annotations))

@Component(service = Servlet.class,

property = { Constants.SERVICE_DESCRIPTION + "=Simple Demo Servlet",

"sling.servlet.methods=" + HttpConstants.METHOD_GET,

"sling.servlet.paths=" + "/bin/testservlet" }

)

public class TestServlet extends SlingAllMethodsServlet {

  private static final long serialVersionUID = 1L;

 

  @Reference

  MySimpleService mySimpleService;

 

  private static final Logger logger =

  LoggerFactory.getLogger(TestServlet.class);

 

  @Override

  protected void doGet(final SlingHttpServletRequest req, final

  SlingHttpServletResponse resp) throws ServletException, IOException {

  logger.info("Inside doGet!!!");

  try {

  logger.info("Name ::: "+mySimpleService.getMyName());

  resp.getWriter().write(mySimpleService.getMyName()); }

  catch(Exception ex) {

  logger.error("Error in  doGet ::: ", ex);

  }

  }

}

 

Please advise, any help is highly appreciated.

Thanks,

Pradeep

Accepted Solutions (1)

Accepted Solutions (1)

Avatar

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K
smacdonald2008

02-04-2019

Look at our SOLR Article. This one closely matches your requirement. We have a class named MySimpleService that reads OSGi config values.

In the Servlet in this article - we use a @Refence to get config values:

@Reference

    SolrServerConfiguration solrConfigurationService;

This shows the proper way of getting OSGI configuration information within an AEM Servlet. Never try and read OSGI config information directly from a servlet. Write a separate class - as shown in this development article.

Adobe Experience Manager Help | Integrating SOLR with Adobe Experience Manager 6.4

Hope this clear this issue up. Notice the Java code in this Servlet. We use the CONFIG values to perform SOLR actions - such as getting the URL to the SOLR server.

            final String protocol = solrConfigurationService.getSolrProtocol();

        final String serverName = solrConfigurationService.getSolrServerName();

        final String serverPort = solrConfigurationService.getSolrServerPort();

        final String coreName = solrConfigurationService.getSolrCoreName();

        final String pagesResourcePath = solrConfigurationService

I would go through this entire article so you understand.

Hope this helps you.

Answers (22)

Answers (22)

Avatar

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831
Arun_Patidar
MVP

01-04-2019

Hi,

Could you please check if your bundle is active or not? If yes the check if you using osgi reference annotation. e.g.

import org.osgi.service.component.annotations.Reference;

e.g.

aem63app-repo/GetFeaturesServlet.java at master · arunpatidar02/aem63app-repo · GitHub

Avatar

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831
Arun_Patidar
MVP

03-04-2019

Hi,

you were using below which was returning null

@AttributeDefinition(name = "Test Namel", defaultValue="Pradeep", description = "Read my name")

    String name();

But I changed your config class like below, I was getting results

@AttributeDefinition(

        name = "Test Name",

        description = "Read my Name",

       type = AttributeType.STRING

    )

String getName() default "Pradeep";

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

03-04-2019

I had set default value(i have  shared all my code in post), still i have to open the configuration and save once to bring servlet in satisfied state.

Avatar

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831
Arun_Patidar
MVP

03-04-2019

The reason is your not setting default value of configuration and service returning null.

You can use the configuration like I mentioned to set default value of property and servlet will work without saving osgi value.

example code I posted in last comment.

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

03-04-2019

I finally solved this, though it was very weird, first we have to save the configuration then servlet will become in  'satisfied' state.

Once servlet is in satisfied state we can call the same in url.

Thanks everyone for helping me on this.

Regards,

Pradeep

Avatar

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831

Avatar

Arun_Patidar

MVP

Total Posts

2.9K

Likes

1.0K

Correct Answer

831
Arun_Patidar
MVP

02-04-2019

Hi,

Can you try with below code, I tried changing with your config , other code is almost same except method name.

------------------------------------- CustomConfigIntf

import org.osgi.service.metatype.annotations.AttributeDefinition;

import org.osgi.service.metatype.annotations.AttributeType;

import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "My Service Configuration", description = "Service Configuration")

public @interface CustomConfigIntf {

@AttributeDefinition(

        name = "TestName",

        description = "Read my Name",

        type = AttributeType.STRING

    )

String getName() default "Pradeep";

}

---------------------- MyCustomeService

public interface MyCustomeService {

public String getMyName();

}

-------------------------- MyCustomeServiceImpl

import org.osgi.service.component.annotations.Activate;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.ConfigurationPolicy;

import org.osgi.service.metatype.annotations.Designate;

import com.acc.arch17.core.services.CustomConfigIntf;

import com.acc.arch17.core.services.MyCustomeService;

@Component(service = MyCustomeService.class, configurationPolicy = ConfigurationPolicy.REQUIRE)

@Designate(ocd = CustomConfigIntf.class)

public class MyCustomeServiceImpl implements MyCustomeService {

private CustomConfigIntf config;

private String name;

@Activate

public void activate(CustomConfigIntf config) {

this.config = config;

this.name = config.getName();

}

public String getMyName() {

return this.name;

}

}

--------------------------------------- TestServlet

import java.io.IOException;

import javax.servlet.Servlet;

import javax.servlet.ServletException;

import org.apache.sling.api.SlingHttpServletRequest;

import org.apache.sling.api.SlingHttpServletResponse;

import org.apache.sling.api.servlets.HttpConstants;

import org.apache.sling.api.servlets.SlingAllMethodsServlet;

import org.osgi.framework.Constants;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.Reference;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.acc.arch17.core.services.MyCustomeService;

@Component(service = Servlet.class, property = { Constants.SERVICE_DESCRIPTION + "=Simple Demo Servlet",

"sling.servlet.methods=" + HttpConstants.METHOD_GET, "sling.servlet.paths=" + "/bin/testservlet" })

public class TestServlet extends SlingAllMethodsServlet {

private static final long serialVersionUID = 1L;

@Reference

MyCustomeService myCustomService;

private static final Logger logger = LoggerFactory.getLogger(TestServlet.class);

@Override

protected void doGet(final SlingHttpServletRequest req, final SlingHttpServletResponse resp)

throws ServletException, IOException {

logger.info("Inside doGet!!!");

try {

logger.info("Name ::: " + myCustomService.getMyName());

resp.getWriter().write(myCustomService.getMyName());

} catch (Exception ex) {

logger.error("Error in  doGet ::: ", ex);

} finally {

resp.getWriter().close();

}

}

}

output

1724053_pastedImage_10.png

Avatar

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K
smacdonald2008

02-04-2019

Go through this article -- follow it step by step - it works. Then once you get it working - you can compare it with yours to see the difference.

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

02-04-2019

Hi Donald,

No luck,  same error,  servlet is in unsatisfied state.

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

02-04-2019

Hi  Donald,

In AEM 6.4 There is a entirely different approach to read config values. That i am trying to understand how to implement it.

Avatar

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K
smacdonald2008

02-04-2019

Like I said - create the logic to read OSGI config values in a separate class. Then create an instance of that class in the servlet and call a getter method. That will return config values in the servlet.

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

02-04-2019

I followed the same link, not working in  sling servlet.

Avatar

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K
smacdonald2008

02-04-2019

Following article shows how to read OSGi config values - notice this class is not a Sling Servlet:

Reading OSGi Configuration Values for Adobe Experience Manager 6.3

Avatar

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K
smacdonald2008

02-04-2019

That may be where your issue is. I would not try to mix that up.

I would create a separate class that reads those OSGi conig values. Then from your Sling Servlet - you can create an instance of that class and invoke a method to get the config values.

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

02-04-2019

Hi Hemant arora tried your way also, didn't work.

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

02-04-2019

Hi Donald,

My requirement is to read custom configuration properties from osgi console in sling servlet using AEM6.4 SP2.

The example you shared is just to define and use the class in @Reference. I didn't find any custom configuration.

Thanks,

Pradeep

Avatar

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K
smacdonald2008

02-04-2019

Avatar

Avatar

Hemant_arora

Avatar

Hemant_arora

Hemant_arora

02-04-2019

This should work.

____________________________________________________________________________________________________

import org.osgi.service.metatype.annotations.AttributeDefinition;

import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "My Service Configuration", description = "Service Configuration")

public @interface CustomConfigIntf {

@AttributeDefinition(name = "Test Namel", defaultValue="Pradeep", description = "Read my name")

    String name();

}

______________________________________________________________________________________________________

public interface MySimpleService {

public String getName();

}

______________________________________________________________________________________________________

import org.osgi.service.component.annotations.Activate;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.metatype.annotations.Designate;

import com.aem.test.core.CustomConfigIntf;

import com.aem.test.core.service.MySimpleService;

@Component(service=MySimpleService.class, configurationPolicy=ConfigurationPolicy.REQUIRE)

@Designate(ocd = CustomConfigIntf.class)

public class MySimpleServiceImpl implements MySimpleService {

private CustomConfigIntf configs;

@Activate

public void activate(CustomConfigIntf config) {

this.configs = config;

}

public String getName() {

return configs.name();

}

}

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

01-04-2019

Hi Donald,

Below is my entire code

import org.osgi.service.metatype.annotations.AttributeDefinition;

import org.osgi.service.metatype.annotations.ObjectClassDefinition;

@ObjectClassDefinition(name = "My Service Configuration", description = "Service Configuration")

public @interface CustomConfigIntf {

@AttributeDefinition(name = "Test Namel", defaultValue="Pradeep", description = "Read my name")

    String name();

}

public interface MySimpleService {

public String getName();

}

import org.osgi.service.component.annotations.Activate;

import org.osgi.service.component.annotations.Component;

import org.osgi.service.component.annotations.ConfigurationPolicy;

import org.osgi.service.metatype.annotations.Designate;

@Component(service=MySimpleService.class, configurationPolicy=ConfigurationPolicy.REQUIRE)

@Designate(ocd = CustomConfigIntf.class)

public class MySimpleServiceImpl implements MySimpleService {

private CustomConfigIntf config;

   

    private String name;

    @Activate

    public void activate(CustomConfigIntf config) {

        this.config = config;

        this.name = config.name();

    }

    public String getName() {

        return this.name;

    }

    

}

Let me know where i am doing wrong?

@Referencce is not working in servlet.

Thanks,

Pradeep

Avatar

Avatar

Hemant_arora

Avatar

Hemant_arora

Hemant_arora

01-04-2019

In your service class MySimpleService  check the @component annotation:

@Component(service = MySimpleService.class, immediate = true)

Go to http://localhost:4502/system/console/components and search for MySimpleService . Check the status of the service.

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

01-04-2019

Yes, My bundle is in active state, and servlet is unsatisfied state due to @Reference

Avatar

Avatar

pradeepdubey82

Avatar

pradeepdubey82

pradeepdubey82

01-04-2019

Yes, If I add @Reference sling servlet stopped working. It is in unsatisfied state due to the reference.

Avatar

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K

Avatar

smacdonald2008

Total Posts

12.7K

Likes

1.4K

Correct Answer

2.3K
smacdonald2008

01-04-2019

Do you mean when you have this line of code:

@Reference

  MySimpleService mySimpleService;

Its not working?