当我在 AEM 6.4 中使用子服务读取模板的详细信息时,我在错误日志中收到空指针异常
map.get 给出空指针异常
错误消息为
com.adobe.cq.sightly.WCMUsePojo Failed to activate Use class java.lang.IllegalArgumentException: javax.jcr.RepositoryException: This session has been closed. at org.apache.sling.jcr.resource.internal.JcrValueMap.readFully(JcrValueMap.java:395) [org.apache.sling.jcr.resource:3.0.8] at org.apache.sling.jcr.resource.internal.JcrValueMap.entrySet(JcrValueMap.java:183) [org.apache.sling.jcr.resource:3.0.8] at com.mysite.core.helpers.AnalyticsHelper.activate(AnalyticsHelper.java:138) [mysite-core:1.0.0.SNAPSHOT] at com.adobe.cq.sightly.WCMUsePojo.init(WCMUsePojo.java:86) [com.adobe.cq.sightly.cq-wcm-sightly-extension:1.5.12]
它在 AEM 6.3 中运行良好,但在 AEM 6.4 中,它给出空指针异常
map 为空。当我删除关闭资源解析器时它工作正常
MysiteReadTemplateService mysiteReadTemplateService = getSlingScriptHelper()
.getService(MysiteReadTemplateService .class);
ValueMap map = mysiteReadTemplateService
.fetchTemplateDetails(templatePath);
if (map != null) {
templateName = map.get("jcr:title", "");
templateDescription = map.get("jcr:description", "");
}
在 fetchTemplateDetails 方法内部 -
Map<String,Object> paramMap = new HashMap<String,Object>();
//Mention the subServiceName that is configured in the User Mapping
paramMap.put(ResourceResolverFactory.SUBSERVICE, "mysitereadservice");
log.info("After the param");
ResourceResolver rr = null;
ValueMap map =null;
try{
rr = resourceFactory.getServiceResourceResolver(paramMap);
log.info("UserId : " + rr.getUserID());
Resource templateResource = rr.getResource(templatePath);
log.info("Resource : " + templateResource.getPath());
map = templateResource.getValueMap();
rr.close();
}catch(Exception e){
log.error(e.getMessage());
}
return map;
当rr.close被注释时,analyticshelper类中的map不为null。
可能的解释在
中提供com.sun.jdi.InvocationException occurred invoking method
但是,我们仍然希望关闭资源解析器,因为不关闭它会创建许多未关闭的 session 。
如果有人遇到同样的问题,请告诉我们您的想法,或者我如何重构代码以便我们能够关闭资源解析器并且 map 不为空。
最佳答案
关闭 session /资源解析器后,您将无法访问资源或属性(ValueMap)。将您的数据放入另一个数据结构(Collection、Map)中并返回它。或者在 session 打开时执行您的操作:
Map<String, Object> result = new HashMap<String, Object>;
ResourceResolver rr = null;
try{
Map<String,Object> paramMap = new HashMap<String,Object>();
//Mention the subServiceName that is configured in the User Mapping
paramMap.put(ResourceResolverFactory.SUBSERVICE, "mysitereadservice");
log.info("After the param");
rr = resourceFactory.getServiceResourceResolver(paramMap);
if (rr != null) {
log.info("UserId : " + rr.getUserID());
Resource templateResource = rr.getResource(templatePath);
if (templateResource != null) {
log.info("Resource : " + templateResource.getPath());
ValueMap map = templateResource.getValueMap();
result.put("jcr:title", map.get("jcr:title",""))
result.put(......);
result.put(......);
result.put(......);
result.put(......);
result.put(......);
}
}
}catch(LoginException e){
log.error(e.getMessage(), e);
} finally {
if (rr != null && !rr.isLive()) {
rr.close();
}
}
return result;
ResourceResulver应该在finally block 中关闭,或者使用try-with-resources:
try (ResourceResolver rr = resourceFactory.getServiceResourceResolver(paramMap)) {
//yourCode
} catch (LoginException e) {
log.errror(e.getMessage(), e);
}
关于java - 调用方法 osgi aem read 子服务时发生 com.sun.jdi.InitationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52215580/