Adobe CQ (AEM) 6.3 未加载 Servlet
Adobe CQ (AEM) 6.3 Did Not Load Servlet
我有一个来自 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 解析器和错误处理程序 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.SlingRepository
由 com.day.crx.sling.server
提供,而在 CQ 6.3 中由 com.day.crx.sling.server
提供com.adobe.granite.repository
。不知道是不是这个原因。
Servlet 本质上是 OSGI 组件,因此您应该能够在 OSGI 组件 Web 控制台中看到您的 servlet:/system/console/components
您的 servlet 可能已注册但由于某种原因被禁用,或者由于您的编写方式存在问题而未注册。
请提供您的 servlet 代码,以便我们进一步提供帮助
稍微弄乱并检查了日志。显然,问题出在没有生成必要绑定(在 @Reference
中绑定和取消绑定)方法的 maven scr 插件上。基本上,我需要严格定义方法,例如:
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;
}
}
}
有几项我们需要检查服务是否卡在 满意 状态:
- Configuration,是不是每个配置字段都配置了?
- 它依赖的其他服务,它们是否已经激活或者也处于满意状态?
- 您是否已将服务列入白名单? -- 如果您使用
slingRepository.loginAdministrative(null)
.
- 任何异常在激活时发生(用
@Activate
表示)?
我知道清单不完整,我也在学习这个 OSGi 东西。这很有趣,虽然有点不清楚(没有傻瓜文档)。
我有一个来自 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 解析器和错误处理程序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.SlingRepository
由 com.day.crx.sling.server
提供,而在 CQ 6.3 中由 com.day.crx.sling.server
提供com.adobe.granite.repository
。不知道是不是这个原因。
Servlet 本质上是 OSGI 组件,因此您应该能够在 OSGI 组件 Web 控制台中看到您的 servlet:/system/console/components
您的 servlet 可能已注册但由于某种原因被禁用,或者由于您的编写方式存在问题而未注册。
请提供您的 servlet 代码,以便我们进一步提供帮助
稍微弄乱并检查了日志。显然,问题出在没有生成必要绑定(在 @Reference
中绑定和取消绑定)方法的 maven scr 插件上。基本上,我需要严格定义方法,例如:
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;
}
}
}
有几项我们需要检查服务是否卡在 满意 状态:
- Configuration,是不是每个配置字段都配置了?
- 它依赖的其他服务,它们是否已经激活或者也处于满意状态?
- 您是否已将服务列入白名单? -- 如果您使用
slingRepository.loginAdministrative(null)
. - 任何异常在激活时发生(用
@Activate
表示)?
我知道清单不完整,我也在学习这个 OSGi 东西。这很有趣,虽然有点不清楚(没有傻瓜文档)。