【问题标题】:ResourceResolverFactory and SlingRepository null in Service class服务类中的 ResourceResolverFactory 和 SlingRepository null
【发布时间】:2015-09-18 05:23:21
【问题描述】:

我有一个服务类,如下所示,我使用 Maven 部署并在 Sling Web 控制台上处于活动状态。当我从此包访问方法 getSearchAssetNames() 时,它会根据 AEM 6.0 登录创作实例被调用。

但是,存储库、资源解析器工厂、查询构建器等隐式对象都通过我使用@Reference 注释派生它们的方式获得空指针异常。

这是课程的代码。我已经尝试删除激活、停用方法、添加启动/停止方法等所有内容,但这仍然不起作用。

错误日志显示:

*01.07.2015 12:05:24.014 INFO [127.0.0.1 [1435732523998] GET /content/test/en/headerfooter/jcr:content/footerpar/testassetfinder..html HTTP/1.1 ] com.test.example.assetfinder.AssetFinderImpl 查询生成器:null 01.07.2015 12:05:24.014 INFO [127.0.0.1 [1435732523998] GET /content/test/en/fordheaderfooter/jcr:content/footerpar/testassetfinder..html HTTP/1.1] com.test .example.assetfinder.AssetFinderImpl JCR 存储库:空 引起:java.lang.NullPointerException:null 在 com.test.example.assetfinder.AssetFinderImpl.getSearchAssetNames(AssetFinderImpl.java:61)*

谁能帮我解决这个问题?

            package com.test.example.assetfinder;

            import java.util.ArrayList;
            import java.util.HashMap;
            import java.util.List;
            import java.util.Map;

            import javax.jcr.RepositoryException;
            import javax.jcr.Session;

            import org.apache.felix.scr.annotations.Activate;
            import org.apache.felix.scr.annotations.Component;
            import org.apache.felix.scr.annotations.Deactivate;
            import org.apache.felix.scr.annotations.Reference;
            import org.apache.felix.scr.annotations.Service;
            import org.apache.sling.jcr.api.SlingRepository;
            import org.osgi.service.component.ComponentContext;
            import org.slf4j.Logger;
            import org.slf4j.LoggerFactory;

            import com.day.cq.search.PredicateGroup;
            import com.day.cq.search.Query;
            import com.day.cq.search.QueryBuilder;
            import com.day.cq.search.result.Hit;
            import com.day.cq.search.result.SearchResult;


            /**
             * Example Asset Finder in AEM DAM.
             */
            @Service(value=com.test.example.assetfinder.AssetFinderService.class)
            @Component
            public class AssetFinderImpl implements AssetFinderService {

                @Reference
                private QueryBuilder builder;

                @Reference
                private ResourceResolverFactory resolverFactory;

                @Reference
                private SlingRepository repository;

                private static final Logger LOGGER = LoggerFactory.getLogger(AssetFinderImpl.class);

                @Activate
                protected void activate(final ComponentContext pCtx) throws RepositoryException {
                }
                @Deactivate
                protected void deactivate(ComponentContext pCtx) throws RepositoryException {
                }

                public List<String> getSearchAssetNames() {
                    List<String> assetList = new ArrayList<String>();
                    Session session = null;
                    try {
                        LOGGER.info("Query Builder: "  +builder);
                        LOGGER.info("Resolver Factory: "  +resolverFactory);
                        LOGGER.info("JCR Repository: " +repository);

                        session = repository.loginAdministrative(null);           
                        Map<String, String> map = new HashMap<String, String>();
                        map.put("path",         "/content/dam");
                        map.put("type",         "dam:Asset");
                        map.put("nodename",     "*example*.*");
                        map.put("orderby.sort", "asc");           
                        Query query = builder.createQuery(PredicateGroup.create(map), session);
                        SearchResult result = query.getResult();

                        // Iterating over the results
                        for (Hit hit : result.getHits()) {
                            assetList.add(hit.getTitle());
                        }
                    } catch(RepositoryException re) {
                        re.printStackTrace();       
                    } finally {
                        if(null != session) {
                            session.logout();
                        }
                    }       
                    return assetList;
                }
            }

【问题讨论】:

  • 他们用 AEM 6 改变了一些东西。看看这篇博文:wemblog.com/2014/08/how-to-use-sessions-and-resource.html
  • 您好 Thomas,感谢您的宝贵时间和建议!我尝试像这样更新对捆绑 pom xml 的依赖项:` com.adobe.aemaem-api6.0.0.1provided ` 然后尝试清理构建。但它没有采用在类路径中有 aem-api-6.0.0.1 jar 的 Eclipse 上看起来没有错误的更新方法。有什么线索吗?
  • 我通过依赖修复解决了 Maven 构建问题。但是,当我构建捆绑包时,resolverFactory 仍然为空 - 严酷的现实,无法逃避那个!总的来说:@Reference private ResourceResolverFactory resolverFactory; 不适合我。
  • 这确实很奇怪。您的 OSGi 控制台中是否有一些不满意的捆绑包?如果他引用的服务不可用,您的服务甚至不应该启动。也许尝试添加以下注释属性:@Reference(policy = ReferencePolicy.STATIC)
  • 问题已解决。以下是我的经验教训: 1. 从组件 JSP 对 OSGi 服务的调用必须使用 Serive-class-name service-object = sling.getService("service-class-name.class");并且不使用正常的实例化 new 运算符。 2. impl类中不需要@Activate注解。因为它是实现一个接口,@Override 很好。 3. 在声明 maven 依赖项时,我在包含 aem 6.0.0.1 时遇到了构建错误。我删除了以前版本对导入 ResourceResolverFactory 类的依赖,并且 maven 构建错误消失了。

标签: osgi aem bundles


【解决方案1】:

这里的关键是,当您使用@Reference 时,它会将服务引用注入到由服务组件运行时 (SCR) 管理的类的实例中,并且 注入到该托管实例中。如果您创建类的新(即不同)实例,则不会注入该字段。这就是为什么您需要使用sling.getService() 方法来获取托管实例的原因。

最佳做法是避免将实现类放在导出的包中。这样,您就不能直接从 JSP 中引用实现类;您只能引用服务接口,因此您永远无法从 JSP 创建新实例,因此不会遇到使用类的非托管实例的问题。

关于@Activate@Deactivate,只有在您的激活/停用方法执行任何操作时才需要它们。在这种情况下,它们不会(至少在您的代码示例中)。如果您将方法命名为 activatedeactivate,您也可以避免使用它们,但出于安全考虑,我个人始终建议使用它们,例如如果您将名称输入错误为activte 或类似的名称。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    • 2018-07-03
    • 2014-12-22
    • 2016-07-05
    相关资源
    最近更新 更多