We encountered a strange injection behaviour of service into our servlets. First serlvet looks as follows:
@Service(Servlet.class)
@Component(
label = "Some Label",
description = "Some description",
metatype = true,
immediate = true
)
@Properties({
@Property(name = "service.description", value = "some val"),
@Property(name = "service.vendor", value = "some val"),
@Property(name = "sling.servlet.paths",
value = { "/some/path" },
propertyPrivate = false)
})
public class RequestPasswordServlet extends SlingAllMethodsServlet {
...
@Reference
private ValidateService validateService;
...
}
and the validation service:
@Component
@Service
public class ValidateServiceImpl implements ValidateService {
...
@Reference
private Service1 service1;
@Reference
private Service2 service2;
...
}
When request comes to this servlet, validateService is not null, but references inside this service are null, so I get NPE at some point. In OSGi console I see, that both components are active and their references are Satisfied.
There is even more strange thing - we also have second servlet (with just the same annotations, like RegitrationServlet), with reference to the same ValidateService. When request comes to second servlet, I can see, that references inside ValidateService are NOT null.
So I took heap dumps, where I see that there are two objects of class ValidateServiceImpl, which usually is ok, because second can wait for GC to remove it. But in this dump I can see, that servlets has references to different instances, what is really strange.
In both servlets, I wrote constructors and bind/unbind methods for this service. The output during deployment of package is:
2015-11-02 15:57:15.127 ERROR [com.package.registration.RegistrationServlet] Unbinding ValidateService
2015-11-02 16:01:47.159 ERROR [com.package.registration.RegistrationServlet] Creating RegistrationServlet()
2015-11-02 16:01:47.159 ERROR [com.package.registration.RegistrationServlet] Binding ValidateService
and
2015-11-02 15:57:15.106 ERROR [com.package.security.RequestPasswordServlet] Unbinding ValidateService
2015-11-02 16:01:47.104 ERROR [com.package.security.RequestPasswordServlet] Creating RequestPasswordServlet
2015-11-02 16:01:47.104 ERROR [com.package.security.RequestPasswordServlet] Binding ValidateService
2015-11-02 16:02:06.861 ERROR [com.package.security.RequestPasswordServlet] Unbinding ValidateService
2015-11-02 16:02:07.348 ERROR [com.package.security.RequestPasswordServlet] Creating RequestPasswordServlet
2015-11-02 16:02:07.348 ERROR [com.package.security.RequestPasswordServlet] Binding ValidateService
So RequestPasswordServlet (the one which has reference to correct service) getting created twice during bundle deployment, what I can not understand as well.
Whole this story can be related to next facts:
- our project runs on AEM 5.6.1 with SP 2
- version of org.apache.felix.framework is 4.2.0
- we moved to JAVA 8 and updated some versions of deps/plugins in our pom file:
- org.apache.felix.scr.annotations from 1.6.0 to 1.9.0
- maven-scr-plugin from 1.7.4 to 1.20.0
- maven-bundle-plugin from 2.3.7 to 2.5.4
- maven-compiler-plugin from 2.3.2 to 3.1
According to this link versions of org.apache.felix.scr.annotations and maven-scr-plugi, we use in our project, are not compatible, so I tried to change them to 1.9.8 and 1.21.0 respectively, but with no luck.
Also my steps to reproduce:
- clear install folder (to remove all our bundles)
- restart AEM instance
- install package1 (with version, when we first encountered this issue)
- install package2 any newer package
- check if issue is there
Restarting bundle/component helps to solve, but we would like to find reason for this weird behaviour and fix it.
Any ideas what is going on there, or where to look next?
Upd1: we also have this problem with other servlets/jsp pages as well. Also, it seems, that setting immediate=true for ValidateServiceImpl solves the problem (but not 100% sure about this), but this behaviour is not clear for me.