Expand my Community achievements bar.

SOLVED

Issues with SCR References

Avatar

Level 5

I'm trying to utilize a reference to the QueryBuilder within a maven bundle, but I'm getting a Null Pointer Exception when I execute any methods on the Object that is injected. My maven install doesn't seem to throw any relevant errors or warnings, in fact within the web console, the entry for my bundle is listed under the  "using bundles" section of the com.day.cq.Search service.

Trying the same method calls with other services (ResourceResolverFactory for example) generates the same null pointer exception. The line referenced in the stack trace is on the method call within the method of my class im working in, not on the @reference in my class.

com.uc.news.Author.(Author.java:64) 

I'm not sure if this is an issue with binding/unbinding, but I believe those methods are being set automatically--I've double checked that I have the latest version f all the decencies set up n my POM.xml (from the adobe  repos). Any guidance is appreciated.

Here's the top part of my Author Class (I'm developing a system for news publishing for our org) up until the line that throws the exception. (not that I'm passing the session to the constructor, which is how I got around the issue earlier before I fully understood what was occurring).

package com.uc.news; import org.apache.felix.scr.annotations.*; import javax.jcr.Value; import javax.jcr.ValueFactory; import javax.jcr.Session; //for querying import com.day.cq.search.*; import com.day.cq.search.result.Hit; import com.day.cq.search.result.SearchResult; import java.util.HashMap; import java.util.Map; //Sling Imports import org.apache.sling.api.resource.ResourceResolverFactory; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.Resource; //Jackrabbit User APIs import org.apache.jackrabbit.api.JackrabbitSession ; import org.apache.jackrabbit.api.security.user.Group; import org.apache.jackrabbit.api.security.user.UserManager; import org.apache.jackrabbit.api.security.user.User; import org.apache.jackrabbit.api.security.user.Authorizable; @Component public class Author { @Reference private QueryBuilder queryBuilder; //Inject a Sling ResourceResolverFactory public String name = ""; public String id = ""; public String email = ""; public String phone = ""; public String title = ""; public String aboutMe = ""; public String headshot = ""; public String reassign = ""; public String approvers = ""; public String approvees = ""; public boolean newContact = false; public Author() { } public Author(String u, UserManager um, Session sess) { id = u; try{ //query for approvees Map<String,String> map = new HashMap<String, String>(); map.put("path","/home"); map.put("type", "rep:User"); map.put("fulltext.relPath","profile/approvers"); map.put("fulltext",id); Query approveeQuery = queryBuilder.createQuery(PredicateGroup.create(map),sess); SearchResult result = approveeQuery.getResult(); for (Hit hit : result.getHits()) { approvees += hit.getPath(); }

...

1 Accepted Solution

Avatar

Correct answer by
Level 9

Are you running this code as an OSGI service, or as stand-alone class? You may not be able to use @Reference without being in an OSGi container, it is  Felix that's providing the service. There is an example on how to use Querybuilder with OSGI

https://helpx.adobe.com/experience-manager/using/using-query-builder-api1.html

Please check and compare your service with the above link

View solution in original post

4 Replies

Avatar

Correct answer by
Level 9

Are you running this code as an OSGI service, or as stand-alone class? You may not be able to use @Reference without being in an OSGi container, it is  Felix that's providing the service. There is an example on how to use Querybuilder with OSGI

https://helpx.adobe.com/experience-manager/using/using-query-builder-api1.html

Please check and compare your service with the above link

Avatar

Level 5

Thanks, I did follow that tutorial while i was first learning maven, and it executes successfully.

I've followed this tutorial in order to set my maven bundle up https://helpx.adobe.com/experience-manager/using/first-osgi.html

The only difference I can spot is that I'm not using the @Service annotation, which the felix doc seems to indicate isn't required, though I can't find any other examples online where @Reference is used and @Service isn't present, so I wonder if that's my issue.

Avatar

Employee Advisor

Hi,

the @Reference only works within OSGI components and OSGI services; it does not work with simple POJOs.

kind regards,
Jörg

Avatar

Level 10

I would follow the QUeryBuilder article that is mentioned above. It shows you how to successfully inject a QueryBuilder instance into your Service:

//This is a component so it can provide or consume services
@Component
  
@Service
public class SearchServiceImpl implements SearchService {
 
/** Default log. */
protected final Logger log = LoggerFactory.getLogger(this.getClass());
          
private Session session;
              
//Inject a Sling ResourceResolverFactory
@Reference
private ResourceResolverFactory resolverFactory;
          
@Reference
private QueryBuilder builder;
     
@Override
public String SearchCQForContent() {
try { 
              
 //Invoke the adaptTo method to create a Session 
    ResourceResolver resourceResolver = resolverFactory.getAdministrativeResourceResolver(null);
    session = resourceResolver.adaptTo(Session.class);
             
    String fulltextSearchTerm = "Geometrixx";
                  
    // create query description as hash map (simplest way, same as form post)
    Map<String, String> map = new HashMap<String, String>();
 
 // create query description as hash map (simplest way, same as form post)
               
    map.put("path", "/content");
    map.put("type", "cq:Page");
    map.put("group.p.or", "true"); // combine this group with OR
    map.put("group.1_fulltext", fulltextSearchTerm);
    map.put("group.1_fulltext.relPath", "jcr:content");
    map.put("group.2_fulltext", fulltextSearchTerm);
    map.put("group.2_fulltext.relPath", "jcr:content/@cq:tags");
    // can be done in map or with Query methods
    map.put("p.offset", "0"); // same as query.setStart(0) below
    map.put("p.limit", "20"); // same as query.setHitsPerPage(20) below
                    
    Query query = builder.createQuery(PredicateGroup.create(map), session);

                      

Yeah - always use the @Service annotation.