Service class

时间:2015-07-01 07:13:34

标签: osgi cq5 aem bundles

我有一个Service Class,如下所示,我使用Maven部署,并且在Sling Web Console上处于Active状态。当我从此捆绑包中访问方法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 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存储库:null   引起:java.lang.NullPointerException:null       at 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;
                }
            }

1 个答案:

答案 0 :(得分:1)

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

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

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