我们在servlet中遇到了奇怪的服务注入行为。第一个serlvet看起来如下:
@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;
...
}
和验证服务:
@Component
@Service
public class ValidateServiceImpl implements ValidateService {
...
@Reference
private Service1 service1;
@Reference
private Service2 service2;
...
}
当请求来到这个servlet时, validateService 不为null,但是这个服务中的引用是null,所以我在某个时候获得了NPE。在OSGi控制台中,我看到两个组件都处于活动状态,并且它们的引用都是满意的。
还有更奇怪的事情 - 我们还有第二个servlet(使用相同的注释,如RegitrationServlet),引用相同的ValidateService。当请求到达第二个servlet时,我可以看到,ValidateService中的引用是 NOT null。
所以我进行了堆转储,在那里我看到有两个类ValidateServiceImpl的对象,通常都没问题,因为第二个可以等待GC去除它。但是在这个转储中我可以看到,servlet引用了不同的实例,这真的很奇怪。
在两个servlet中,我为这个服务编写了构造函数和bind / unbind方法。程序包部署期间的输出是:
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
和
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
所以RequestPasswordServlet(引用正确服务的那个)在bundle部署期间创建了两次,我也无法理解。
整个故事可以与下一个事实相关:
根据{em> org.apache.felix.scr.annotations 和 maven-scr-plugi 的this link版本,我们在我们的项目中使用,不是兼容,所以我试图将它们分别改为1.9.8和1.21.0,但没有运气。
我的重现步骤:
重新启动软件包/组件有助于解决问题,但我们希望找到这种奇怪行为的原因并进行修复。
任何想法在那里发生了什么,或者在哪里看下一步?
Upd1:我们也遇到了其他servlets / jsp页面的问题。此外,似乎为 ValidateServiceImpl 设置 immediate = true 可以解决问题(但不是100%肯定),但这种行为对我来说并不清楚。
答案 0 :(得分:0)
我认为AEM 5.6.1在Java 8中不稳定:)。 AEM> = 6.1& java 8.