关闭 AEM 中的资源解析器对象后会话已关闭 [英] Session has been closed after closing resource resolver object in AEM

查看:93
本文介绍了关闭 AEM 中的资源解析器对象后会话已关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试关闭我打开的资源解析器,但出现此错误javax.jcr.RepositoryException:当我关闭资源解析器时,此会话已关闭.实际上,如果您将资源解析器保持打开状态,我看不出任何问题,但我不想在代码中将资源解析器保持打开状态.

I am trying to close the resource resolver that I opened but I got this error "javax.jcr.RepositoryException: This session has been closed when I close resource resolver. Actually I don’t see any problem if you leave the resource resolver as open but I don’t want to leave the resource resolver open in the code.

serviceParam.put(ResourceResolverFactory.SUBSERVICE, "serviceNew");
        ResourceResolver resourceResolver = null;

        try
        {

            resourceResolver = resourceResolverFactory.getServiceResourceResolver(serviceParam);

            final Configuration configuration = configurationManagerFactory.getConfigurationManager(resourceResolver)
                    .getConfiguration(cloudConfigurationType.getServiceName(), services);

            if (null != configuration)
            {
               return configuration.getContentResource().adaptTo(ValueMap.class);
            }

        } catch (LoginException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally
        {
            if (resourceResolver != null && resourceResolver.isLive())
            {
                resourceResolver.close();
            }
        }

错误信息:-

org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Uncaught SlingException
java.lang.IllegalArgumentException: javax.jcr.RepositoryException: This session has been closed.
    at org.apache.sling.jcr.resource.internal.JcrValueMap.read(JcrValueMap.java:337) [org.apache.sling.jcr.resource:3.0.16]
    at org.apache.sling.jcr.resource.internal.JcrValueMap.get(JcrValueMap.java:101) [org.apache.sling.jcr.resource:3.0.16]

如果我没有在代码中关闭资源解析器,会在日志中观察到许多如下所示的错误消息

Observing many error messages like below in logs If I dont close a resource resolver in code

 23.12.2020 11:56:30.481 [Apache Sling Resource Resolver Finalizer Thread] INFO o.a.s.r.i.CommonResourceResolverFactoryImpl Unclosed ResourceResolver was created here:
    java.lang.Exception: Opening Stacktrace
    at org.apache.sling.resourceresolver.impl.CommonResourceResolverFactoryImpl$ResolverReference.<init>(CommonResourceResolverFactoryImpl.java:540)

真正的问题是,一旦我们关闭资源解析器,会话就会关闭.这是 AEM 代码的问题吗?或者有什么其他方法可以处理这种情况?

The real problem is, session getting closed as soon as we close resource resolver. Is this an issue with AEM code? or Any other way to handle this case?

推荐答案

返回的问题是 ValueMap 对象尝试使用内部创建的 ResourceResolver 动态访问存储库,但是该 Resolver 在退出您的方法时已立即关闭(在 finally 块中)).

The problem is returned ValueMap object tries to dynamically access repository using internally-created ResourceResolver, but that Resolver is already closed immediately on exit from your method (in finally block).

有不同的解决方案可以克服这个问题,效率更高/更低:

There are different solutions to overcome this, more/less efficient:

解决方案 1)当您只需要对 ValueMap 属性进行只读访问时,您可以返回该映射的副本:

SOLUTION 1) When you need only read-only access to ValueMap properties, you may return the copy of that map:

  ...
  ValueMap props = configuration.getContentResource().adaptTo(ValueMap.class)
  return (props != null) ? new HashMap<>(props)     // create the copy Map of props
                         : new HashMap<String, Object>(0);

解决方案 2)不要使用内部创建的服务用户"ResourceResolver,但将当前用户的 ResourceResolver 传递到您的方法中,并确保用户具有访问配置节点的权限.

SOLUTION 2) Don't use internally-created "service-user" ResourceResolver, but pass current user's ResourceResolver into your method, and make sure user has privileges to access Configuration nodes.

解决方案 3)创建 get(propertyName)set(propertyName, value) 方法来读/写特定的配置属性,他们将创建内部 ResourceResolver 并在 get/set 后立即关闭它操作:

SOLUTION 3) Create the get(propertyName) and set(propertyName, value) methods to read/write specific Configuration property, they would create internal ResourceResolver and immediate close it after the get/set operation:

  public Object getProp(String name) {
    try(ResourceResolver resolver =  resourceResolverFactory.getServiceResourceResolver(serviceParam)) {
      Configuration configuration = configurationManagerFactory.getConfigurationManager(resolver)
                    .getConfiguration(cloudConfigurationType.getServiceName(), services);
      if (null != configuration){
         return configuration.getContentResource().adaptTo(ValueMap.class).get(name);
      }
    }
  }

解决方案 4)在某个上层方法中创建服务ResourceResolver,并通过它直到不需要ValueMap:

SOLUTION 4) Create service ResourceResolver in some upper method, and pass it through until ValueMap is not needed:

    ...
    try(ResourceResolver resolver =  resourceResolverFactory.getServiceResourceResolver(serviceParam)) {
      ...
      ValueMap confProps = getConfigProps(resolver, ...);  // call your method
      //  use confProps as you wish safely
      ...
    }  // at this place, Resolver is closed and you cannot use confProps any more
  }
    ...

解决方案 5)(解决方案 #4 的极端变体)在您的类/包启动时创建服务 ResourceResolver 一次,让它一直存在直到应用程序关闭,将其传递给您的方法.不过,Sling 文档并不完全推荐此变体..

SOLUTION 5) (extreme variant of SOLUTION #4) Create the service ResourceResolver once at your class/bundle startup, and let it lives until application shutdown, passing it to your method(s). Though, this variant is not quite recommended by Sling documentation..

我可以根据需要提供更多样品.

I can provide more samples on need.

这篇关于关闭 AEM 中的资源解析器对象后会话已关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆