Service类中的ResourceResolverFactory和SlingRepository为空 [英] ResourceResolverFactory and SlingRepository null in Service class

查看:117
本文介绍了Service类中的ResourceResolverFactory和SlingRepository为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个下面的服务类,我使用Maven进行了部署,并且在Sling Web Console上处于活动状态.当我从此捆绑包访问方法getSearchAssetNames()时,它会按照Authoring实例上的AEM 6.0日志被调用.

I have a Service class as below which I deployed using Maven and is Active on Sling Web Console. When I am accessing the method getSearchAssetNames() from this bundle it is getting called as per the AEM 6.0 logs on Authoring instance.

但是,隐式对象(例如存储库,资源解析器工厂,查询生成器)都通过我使用@Reference注释派生它们的方式而获得了空指针异常.

But, implicit objects such as repository, resource resolver factory, query builder are all getting null pointer exceptions through how I have derived them using @Reference annotation.

这是该课程的代码.我尝试删除激活,停用方法,添加开始/停止方法等所有方法,但这仍然行不通.

Here is the code for the class. I have tried removing activate, deactivate methods, adding start/stop methods, everything, but still this does not work.

错误日志显示:

* 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存储库:null 引起原因:java.lang.NullPointerException:null 在com.test.example.assetfinder.AssetFinderImpl.getSearchAssetNames(AssetFinderImpl.java:61)*

*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 Query Builder: 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 Repository: null Caused by: java.lang.NullPointerException: null at com.test.example.assetfinder.AssetFinderImpl.getSearchAssetNames(AssetFinderImpl.java:61)*

任何人都可以帮助我解决该问题吗?

Can anyone please help me regarding how to solve this ?

            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;
                }
            }

推荐答案

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

The key thing here is that when you use @Reference, that injects a service reference into an instance of your class managed by the Service Component Runtime (SCR) and only into that managed instance. If you create a new (i.e. different) instance of your class, then it won't have the field injected. Which is why you need to use the sling.getService() method to get the managed instance.

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

A best practice is to avoid having the implementation class be in an exported package. That way, you can't reference the implementation class directly from a JSP; you can only reference the service interface so you could never create a new instance from the JSP and thus not hit the problem of using a non-managed instance of the class.

关于@Activate@Deactivate,仅当您的activate/deactivate方法执行任何操作时,才需要使用它们.在这种情况下,它们不会(至少在您的代码示例中).如果您将方法命名为activatedeactivate,也可以避免使用它们,但就我个人而言,我总是建议您使用它们只是为了安全起见,例如如果您将名称错误输入为activte或类似名称.

Regarding @Activate and @Deactivate, you would need those only if your activate/deactivate methods did anything. In this case, they don't (at least in your code example). You can also get away from using them if you name your methods activate and deactivate, but personally I would always recommend using them just to be on the safe side, e.g. if you mistype the name as activte or something like that.

这篇关于Service类中的ResourceResolverFactory和SlingRepository为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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