Service类中的ResourceResolverFactory和SlingRepository为空 [英] ResourceResolverFactory and SlingRepository null in Service class
问题描述
我有一个下面的服务类,我使用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方法执行任何操作时,才需要使用它们.在这种情况下,它们不会(至少在您的代码示例中).如果您将方法命名为activate
和deactivate
,也可以避免使用它们,但就我个人而言,我总是建议您使用它们只是为了安全起见,例如如果您将名称错误输入为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屋!