Question

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>
Was it helpful?

Solution

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.

OTHER TIPS

I ran into a similar issue where the maven-scr-plugin was not generating the bind/unbind methods for the @Reference properties. Said so in the server side log when I deployed the bundle, hence the servlet was never registered, hence CQ doesn't know what to do about your request.

One fix is to generate the bind/unbind methods manually.

Another fix is to update the maven-scr-plugin version and the org.apache.felix.scr.annotations dependency. Refer to this post.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top