Sling Servlet中的奇怪服务注入

时间:2015-11-02 14:53:22

标签: osgi cq5 aem apache-felix sling

我们在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部署期间创建了两次,我也无法理解。

整个故事可以与下一个事实相关:

  • 我们的项目使用SP 2
  • 在AEM 5.6.1上运行
  • org.apache.felix.framework 的版本是4.2.0
  • 我们移动到JAVA 8并在我们的pom文件中更新了一些版本的deps / plugins:
    • org.apache.felix.scr.annotations from 1.6.0 to 1.9.0
    • maven-scr-plugin 1.7.4至1.20.0
    • maven-bundle-plugin 2.3.7至2.5.4
    • maven-compiler-plugin from 2.3.2 to 3.1

根据{em> org.apache.felix.scr.annotations 和 maven-scr-plugi this link版本,我们在我们的项目中使用,不是兼容,所以我试图将它们分别改为1.9.8和1.21.0,但没有运气。

我的重现步骤:

  • 清除安装文件夹(删除所有捆绑包)
  • 重启AEM实例
  • 安装package1(带版本,我们第一次遇到此问题时)
  • 安装package2任何更新的包
  • 检查问题是否存在

重新启动软件包/组件有助于解决问题,但我们希望找到这种奇怪行为的原因并进行修复。

任何想法在那里发生了什么,或者在哪里看下一步?

Upd1:我们也遇到了其他servlets / jsp页面的问题。此外,似乎为 ValidateServiceImpl 设置 immediate = true 可以解决问题(但不是100%肯定),但这种行为对我来说并不清楚。

1 个答案:

答案 0 :(得分:0)

我认为AEM 5.6.1在Java 8中不稳定:)。 AEM&g​​t; = 6.1& java 8.