I'm having some issues with a Sling Servlet in CQ. While requesting the servlet I'm getting an exception saying
Caused by: org.apache.sling.api.resource.PersistenceException: Resource at '/bin/feedServlet' is not modifiable.
at org.apache.sling.servlets.post.impl.helper.SlingPropertyValueHandler.setProperty(SlingPropertyValueHandler.java:153)
at org.apache.sling.servlets.post.impl.operations.ModifyOperation.writeContent(ModifyOperation.java:411)
at org.apache.sling.servlets.post.impl.operations.ModifyOperation.doRun(ModifyOperation.java:101)
In the servlet, I'm trying to inject 2 services using the @Reference
annotation.
Please give me some pointers to solve this issue. Please find my Servlet code below (not complete):
@Component(immediate = true, metatype = false, label = "feedServlet")
@Service(Servlet.class)
@Properties(value = { @org.apache.felix.scr.annotations.Property(name = "sling.servlet.methods", value = "POST"),
@org.apache.felix.scr.annotations.Property(name = "sling.servlet.paths", value = "/bin/feedServlet") })
public class FeedServlet extends SlingAllMethodsServlet {
private static final long serialVersionUID = -2139716879248038562L;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.STATIC)
private ContentSearchService searchService;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY, policy = ReferencePolicy.STATIC)
private FeedGeneratorService feedService;
@Override
protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServerException,
IOException {
ResourceResolver resourceResolver = request.getResourceResolver();
List<Hit> list = null;
String feed = null;
try {
list = search(request, searchService);
feed = feedService.generateFeed(list, resourceResolver);
} catch (Throwable e) {
}
response.getWriter().write(feed);
}
Note: Without these services the servlet is working fine now(previous thread). Is this an issue with the dependency injection? The serviceComponets.xml
for this bundle defines these services as:
<scr:component enabled="true" immediate="true" name="com.acme.wcm.cq.servlet.FeedServlet">
<implementation class="com.acme.wcm.cq.servlet.FeedServlet"/>
<service servicefactory="false">
<provide interface="javax.servlet.Servlet"/>
</service>
<property name="sling.servlet.methods" type="String" value="POST"/>
<property name="sling.servlet.paths" type="String" value="/bin/feedServlet"/>
<property name="service.pid" value="com.acme.wcm.cq.servlet.FeedServlet"/>
<reference name="searchService" interface="com.acme.wcm.cq.search.ContentSearchService" cardinality="1..1" policy="static" bind="bindSearchService" unbind="unbindSearchService"/>
<reference name="feedService" interface="com.acme.wcm.cq.feed.FeedGeneratorService" cardinality="1..1" policy="static" bind="bindFeedService" unbind="unbindFeedService"/>
</scr:component>
I think the POST request you made wasn't handled by your servlet.
Look the code of SlingProprtyValueHandler: src of SlingProprtyValueHandler
CQ doesn't use your servlet, so it thinks at "/bin/feedServlet" there is a resource and it tries to modify it (because it is a POST request), but there is not any resource, that's why you got an exception.
Please create a doGet method for your serlvet and try to make a get request, I am sure that it won't work.
Check your servlet is active or not under /system/console/components.
You can also check whether the /bin path is allowed or not under /system/console/configMgr/ check "Apache Sling Servlet/Script Resolver and Error Handler".
I hope this helps!
p.s. It is better to map your servlet to a resource instead of a path. example code here how to map a servlet to a resource
So you can create a a path like /etc/myApp/services and under this path you can create a myService node with a type like etc/myApp/services/myService, and you can map your servlet to this resource type.