Sling @Inject NullPointerError, When @Reference Successful
Asked Answered
S

1

5

When trying to @Inject (javax.inject.Inject) to inject MyConfigurationService within @SlingServlet MyServlet leads to a NullPointerError anytime any operations are attempted on myConfigurationService within an AEM OSGi container using Maven org.apache.felix.maven-scr-plugin as part of the build process.

Service Implementation:

@Service({MyConfigurationService.class})
@Component(immediate = true, metatype = true, label = "My Configuration Service")
public class MyConfigurationServiceImpl implements MyConfigurationService {
    @Property(unbounded = PropertyUnbounded.DEFAULT, label = "API URL", description = "API URL")
    private static final String API_URL = "apiurl";

    private String apiUrl;

    @Activate
    protected void activate(Map<String, Object> properties) {
        this.apiUrl = PropertiesUtil.toString(properties.get(API_URL), "");
    }
}

Servlet:

@SlingServlet(paths = "/bin/myServlet", methods = "POST", metatype = true)
public class MyServlet extends org.apache.sling.api.servlets.SlingAllMethodsServlet {
    private static final long serialVersionUID = 1L;
    private static final Logger logger = LoggerFactory.getLogger(MyServlet.class);

    @Inject
    MyConfigurationService myConfigurationService;

    @Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServerException, IOException {
        // any attempts to use myConfigurationService results in NPE
    }
}

However using @Reference (org.apache.felix.scr.annotations.Reference) in place of @Inject successfully injects the service and is usable within the @SlingServlet methods such as doPost:

@Reference
MyConfigurationService myConfigurationService;

Why does @Inject fail to inject the service into the @SlingServlet when @Reference works?

Thank you for any help you can provide!

Shewchuk answered 15/2, 2018 at 21:25 Comment(0)
N
7

I think you are confusing the sling models @Inject with SCR annotations used by the maven SCR plugin.

The maven SCR plugin defines annotations to be processed at build time those are defined here: http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html All those annotations are under the package org.apache.felix.scr.annotations

The @Reference annotation can only be used with @Component, @service, @SlingServlte or any other SCR class annotation that defines an OSGI component.

The javax.inject.Inject annotation is generic and is used by many frameworks for dependency injection. In AEM or Sling's case, it only means something inside a Sling Model (a class annotated by org.apache.sling.models.annotations.Model), read more about @Inject and other annotations that can be used in a Sling Model here: https://sling.apache.org/documentation/bundles/models.html#basic-usage

Nummary answered 15/2, 2018 at 21:40 Comment(1)
So @Inject is something really only used in @Model annotated elements, while @Reference would be used within @Service, @Component or similar annotated elements to effectively accomplish dependency injection?Shewchuk

© 2022 - 2024 — McMap. All rights reserved.