I had a jar from CQ 5.6 that expose several servlets. I moved the jar to new CQ 6.3 only to find out that the servlets are not ran (tested on Servlet Resolver and it answer with com.day.cq.commons.servlets.NonExistingDispatcherServlet
-- equals to 404).
I have do several checklist to narrow down this issue:
apps
directory where it is included in Apache Sling Servlet/Script Resolver and Error Handler Execution Paths
.Is there any missing checklist to let the servlet handle the specific path defined in sling.servlet.paths
property?
Sorry for the noob question. Thank you in advance.
EDIT
Added the rough code -- i don't think you will be interested on what happens in doPost
. As it is unrelated with registering servlet to AEM 6.3.
package com.test.something;
import java.util.Iterator;
import java.io.*;
import javax.jcr.*;
import javax.servlet.ServletException;
import java.util.*;
import java.util.Date;
import java.text.*;
import org.apache.jackrabbit.api.security.user.Group;
import org.apache.jackrabbit.api.security.user.User;
import org.apache.jackrabbit.api.security.user.UserManager;
import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.jackrabbit.api.*;
import java.rmi.ServerException;
import java.security.Principal;
import org.apache.jackrabbit.api.security.principal.PrincipalManager;
import org.apache.jackrabbit.api.security.user.AuthorizableExistsException;
import java.security.*;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
import org.apache.commons.codec.binary.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.jcr.api.SlingRepository;
@Component(immediate = true)
@Service
@Properties({
@Property(name = "sling.servlet.methods", value = "POST"),
@Property(name = "sling.servlet.paths", value = { "/content/test" }),
@Property(name = "service.description", value = "Test Servlet")
})
public class TestServlet extends SlingAllMethodsServlet {
@Reference
private SlingRepository repository;
protected final Logger log = LoggerFactory.getLogger("SSOLogger");
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
throws ServerException, IOException {
try {
this.doPost(request, response);
} catch (ServletException e) {
//do some logging
}
}
@Override
protected void doPost(SlingHttpServletRequest request,
SlingHttpServletResponse response)
throws ServletException, IOException {
try {
//do something
} catch (RepositoryException ex) {
//do some logging
}
}
}
And yes, this servlet is registered in OSGi Components. It states the properties correctly.
EDIT: Narrowing down the culprit it seems
@Reference
private SlingRepository repository;
does not seems to be loaded properly.. weird. It caused the component to be in Satisfied state instead of Active.
EDIT: Checking the OSGi Services in CQ, noticed that org.apache.sling.jcr.api.SlingRepository
in CQ 5.6 was provided by com.day.crx.sling.server
while in CQ 6.3 it is provided by com.adobe.granite.repository
. Not sure if it is the cause or not.
After messing a bit and checking the logs. Apparently the issue lies on the maven scr plugin that did not generate the necessary binding (bind and unbind in @Reference
) methods. Basically, i need to strictly define the method such as:
public class TestServlet extends SlingAllMethodsServlet {
@Reference(bind = "bindRepository", unbind = "unbindRepository")
private SlingRepository repository;
protected void bindRepository(SlingRepository repository){
this.repository = repository;
}
protected void unbindRepository(SlingRepository repository){
if(this.repository == repository){
this.repository = null;
}
}
}
There are several item we need to check if the Service is stuck in Satisfied state:
slingRepository.loginAdministrative(null)
.@Activate
)?I know the checklist are incomplete, i am also still learning this OSGi thingy. It is interesting though a bit unclear (no documentation for dummies).