ResourceResolverFactory и SlingRepository null в классе обслуживания
У меня есть класс Service, как показано ниже, который я развернул с помощью Maven и активен в Sling Web Console. Когда я получаю доступ к методу getSearchAssetNames()
из этого комплекта он вызывается согласно журналам AEM 6.0 на экземпляре Authoring.
Но неявные объекты, такие как репозиторий, фабрика распознавателя ресурсов, построитель запросов, получают исключения нулевого указателя через то, как я их вывел, используя @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 Построитель запросов: ноль 01.07.2015 12:05:24.014 ИНФОРМАЦИЯ [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 Вызывается: 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 ответ
Ключевым моментом здесь является то, что когда вы используете @Reference
это вставляет ссылку на службу в экземпляр вашего класса, управляемый средой выполнения компонентов службы (SCR), и только в этот управляемый экземпляр. Если вы создадите новый (т. Е. Другой) экземпляр вашего класса, тогда в него не будет вставлено поле. Вот почему вам нужно использовать sling.getService()
метод для получения управляемого экземпляра.
Рекомендуется избегать того, чтобы класс реализации находился в экспортированном пакете. Таким образом, вы не можете ссылаться на класс реализации напрямую из JSP; вы можете ссылаться только на интерфейс сервиса, чтобы вы никогда не могли создать новый экземпляр из JSP и, таким образом, не столкнуться с проблемой использования неуправляемого экземпляра класса.
относительно @Activate
а также @Deactivate
, они понадобятся вам, только если ваши методы активации / деактивации что-то сделали. В этом случае они не (по крайней мере, в вашем примере кода). Вы также можете отказаться от их использования, если назовете свои методы activate
а также deactivate
, но лично я всегда рекомендовал бы использовать их, чтобы быть в безопасности, например, если вы неправильно набрали имя как activte
или что-то типа того.