【问题标题】:Adobe CQ (AEM) 6.3 Did Not Load ServletAdobe CQ (AEM) 6.3 未加载 Servlet
【发布时间】:2018-04-18 03:09:11
【问题描述】:

我有一个来自 CQ 5.6 的 jar,它公开了几个 servlet。我将 jar 移到新的 CQ 6.3 中,却发现 servlet 没有运行(在 Servlet Resolver 上测试,它的回答是 com.day.cq.commons.servlets.NonExistingDispatcherServlet -- 等于 404)。

我已经做了几个清单来缩小这个问题的范围:

  • Jar 是一个 OSGI 包,其中包含公开其服务的 OSGI-INF 元数据 - 包括 servlet。它是在早期的 CQ 5.6 下编译的。
  • Bundle (jar) 已正确注册,CQ 将公开的 servlet 显示为服务。
  • Jar 安装在 apps 目录下,包含在 Apache Sling Servlet/Script Resolver 和错误处理程序中 Execution Paths

是否缺少任何清单让 servlet 处理sling.servlet.paths 属性中定义的特定路径?

很抱歉这个菜鸟问题。提前谢谢你。

编辑 添加了粗略的代码——我认为你不会对doPost 中发生的事情感兴趣。因为它与将 servlet 注册到 AEM 6.3 无关。

  package com.test.something;

  import java.util.Iterator;
  import java.io.*;

  import javax.jcr.*;
  import javax.servlet.ServletException;

  import java.util.*;
  import java.util.Date;
  import java.text.*;


  import org.apache.jackrabbit.api.security.user.Group;
  import org.apache.jackrabbit.api.security.user.User;
  import org.apache.jackrabbit.api.security.user.UserManager;
  import org.apache.jackrabbit.api.security.user.Authorizable;
  import org.apache.jackrabbit.api.*;

  import java.rmi.ServerException;
  import java.security.Principal;
  import org.apache.jackrabbit.api.security.principal.PrincipalManager;
  import org.apache.jackrabbit.api.security.user.AuthorizableExistsException;

  import java.security.*;
  import javax.crypto.spec.SecretKeySpec;
  import javax.crypto.Mac;
  import org.apache.commons.codec.binary.*;

  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;

  import org.apache.felix.scr.annotations.Component;
  import org.apache.felix.scr.annotations.Properties;
  import org.apache.felix.scr.annotations.Property;
  import org.apache.felix.scr.annotations.Reference;
  import org.apache.felix.scr.annotations.Service;
  import org.apache.sling.api.SlingHttpServletRequest;
  import org.apache.sling.api.SlingHttpServletResponse;
  import org.apache.sling.api.servlets.SlingAllMethodsServlet;
  import org.apache.sling.jcr.api.SlingRepository;

  @Component(immediate = true)
  @Service
  @Properties({
   @Property(name = "sling.servlet.methods", value = "POST"),
   @Property(name = "sling.servlet.paths", value = { "/content/test" }),
   @Property(name = "service.description", value = "Test Servlet")
  })
  public class TestServlet extends SlingAllMethodsServlet {

     @Reference
     private SlingRepository repository;
     protected final Logger log = LoggerFactory.getLogger("SSOLogger");

     @Override
     protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
     throws ServerException, IOException {
        try {
         this.doPost(request, response);
        } catch (ServletException e) {
         //do some logging
        }
     }

     @Override
     protected void doPost(SlingHttpServletRequest request,
      SlingHttpServletResponse response)
     throws ServletException, IOException {
        try {
         //do something
        } catch (RepositoryException ex) {
         //do some logging
        }
     }
  }

是的,这个 servlet 在OSGi Components 中注册。它正确地说明了属性。

编辑:缩小似乎是罪魁祸首

@Reference
private SlingRepository repository;

似乎没有正确加载..很奇怪。它导致组件处于 Satisfied 状态,而不是 Active

编辑:检查 CQ 中的 OSGi 服务,注意到 CQ 5.6 中的 org.apache.sling.jcr.api.SlingRepositorycom.day.crx.sling.server 提供,而在 CQ 6.3 中它由 com.adobe.granite.repository 提供。不知道是不是这个原因。

【问题讨论】:

    标签: servlets osgi aem osgi-bundle


    【解决方案1】:

    Servlet 本质上是 OSGI 组件,因此您应该能够在 OSGI 组件 Web 控制台中看到您的 servlet:/system/console/components

    您的 servlet 可能已注册但由于某种原因被禁用,或者由于您的编写方式问题而未注册。

    请提供您的 servlet 代码,以便我们进一步提供帮助

    【讨论】:

    • 抱歉,之前忘记添加了。
    【解决方案2】:

    在搞砸了一点并检查了日志之后。显然问题出在 maven scr 插件上,它没有生成必要的绑定(@Reference 中的绑定和取消绑定)方法。基本上,我需要严格定义方法,例如:

      public class TestServlet extends SlingAllMethodsServlet {
         @Reference(bind = "bindRepository", unbind = "unbindRepository")
         private SlingRepository repository;
    
         protected void bindRepository(SlingRepository repository){
            this.repository = repository;
         }
    
         protected void unbindRepository(SlingRepository repository){
            if(this.repository == repository){
               this.repository = null;
            }
         }
      }
    

    有几个项目我们需要检查服务是否卡在满意状态:

    • 配置,每个配置字段都配置好了吗?
    • 它所依赖的其他服务,它们是否已经处于活动状态或也处于满意状态?
    • 您是否将服务列入白名单? -- 如果您使用的是slingRepository.loginAdministrative(null)
    • 任何异常激活时发生(用@Activate表示)?

    我知道清单不完整,我还在学习这个 OSGi 东西。这很有趣,虽然有点不清楚(没有关于傻瓜的文档)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-22
      • 2014-07-24
      • 1970-01-01
      • 2016-09-21
      • 2018-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多