Search code examples
aemjcrsling

CQ5 QueryBuilder Reference in Sling Servlet


I am declaring a sling servlet like so

@Component(metatype = false)
@Service(Servlet.class)
@Properties({
        @Property(name = "sling.servlet.paths", value = "/bin/foo/bar"),
        @Property(name = "sling.servlet.methods", value = "POST") })
public class FooBarServlet extends SlingAllMethodsServlet {
    ...
}

I override doPost like so

@Override
    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
    ...
}

And I am able to post from a client. Great!

I throw in the following

@Reference
private QueryBuilder queryBuilder;

as per the documentation, a reference to query builder should be injected. But it does not seem to. In the log I see this error

bindQueryBuilder cannot be found (java.lang.VerifyError: ...

And when I try to post to the servlet I get this

javax.jcr.RepositoryException: org.apache.sling.api.resource.PersistenceException: Resource at '/bin/foo/bar' is not modifiable.

And in the OSGi console I see my bundle is installed, and this is what it has to say about my servlet

Service ID 3075 Types: javax.servlet.Servlet
Service PID: com.myproject.FooBarServlet
Component Name: com.myproject.FooBarServlet
Component ID: 5526
Vendor: Adobe

Any suggestions as to what I am doing wrong?


Solution

  • I had been using this tutorial as a reference. I came across this about the Felix Service Component Runtime (SCR)

    and so I implemented the following

    protected void activate(ComponentContext context) {
        LOGGER.info("activating {}", this.getClass().getName());
    }
    
    protected void unbindQueryBuilder(QueryBuilder queryBuilder) {
        this.queryBuilder = null;
    }
    
    protected void bindQueryBuilder(QueryBuilder queryBuilder) {
        this.queryBuilder = queryBuilder;
    }
    

    and it worked! So upon closer investigation I learned that these bind/unbind methods are actually supposed to be generated by the maven-scr-plugin, of which I have version 1.6.0

                <plugin>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>maven-scr-plugin</artifactId>
                    <version>1.6.0</version>
                    <executions>
                        <execution>
                            <id>generate-scr-scrdescriptor</id>
                            <goals>
                                <goal>scr</goal>
                            </goals>
                            <configuration>
                                <!-- Private service properties for all services. -->
                                <properties>
                                    <service.vendor>Adobe</service.vendor>
                                </properties>
                            </configuration>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>org.slf4j</groupId>
                            <artifactId>slf4j-simple</artifactId>
                            <version>1.5.2</version>
                        </dependency>
                    </dependencies>
                </plugin>
    

    and for the annotations I have 1.4.0

                <dependency>
                    <groupId>org.apache.felix</groupId>
                    <artifactId>org.apache.felix.scr.annotations</artifactId>
                    <version>1.4.0</version>
                    <scope>provided</scope>
                </dependency>
    

    so although I am not sure why the bind/unbind methods are not getting generated, I know that they should be, so I generate them manually.

    Update I tried to update the maven-scr-plugin to version 1.20.0, which yielded the following error during mvn build

    [ERROR] Project depends on org.apache.felix:org.apache.felix.scr.annotations:jar:1.4.0:provided
    [ERROR] Minimum required version is 1.9.0
    

    so... I updated the org.apache.felix.scr.annotations to 1.9.0. And it works! My bind/unbind accessors are generated and all is great. However, I am concerned and do not know if I should use version 1.9.0 of org.apache.felix.scr.annotations because I am marking it as provided in the maven dependency and when I look at the OSGi bundles installed on the cq instance I see the following

    Apache Felix Declarative Services (org.apache.felix.scr) : Version 1.6.3.R1409029