Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.
SOLVED

Two similar servlets. One works. The other errors "invalid recursion selector value"

Avatar

Level 3

I have the following servlet that works great

@component(
		service=Servlet.class,
		property= {					
			"sling.servlet.resourceTypes="+"mysite/components/structure/page",
			"sling.servlet.selectors="+"testselector",
			"sling.servlet.extensions="+"json",
			ServletResolverConstants.SLING_SERVLET_METHODS + "=GET"
		}	
	)
public class TestServlet extends SlingSafeMethodsServlet

 

I can call it using jquery ajax on a page like this 

$.ajax({
	type:"GET",
	url: "/_jcr_content.testselector.json",				
	success: function(data){
		console.log("success!")									
	}
});

 

I can also put the full address to the servlet in my browser (if i'm logged into my local aem instance) and get a valid response.

 

But if I create a second servlet that is almost identical like this:

@component(
		service=Servlet.class,
		property= {					
			"sling.servlet.resourceTypes="+"mysite/components/structure/page",
			"sling.servlet.selectors="+"testselectortwo",
			"sling.servlet.extensions="+"json",
			ServletResolverConstants.SLING_SERVLET_METHODS + "=GET"
		}	
	)
public class TestServletTwo extends SlingSafeMethodsServlet

then any calls to TestServletTwo return 400 Bad Request and in the browser, shows the error "Invalid recursion selector value testselectortwo". 

 

Why isn't the second one working?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @mpalme1,

I tried to reproduce your scenario in my local and it works fine with two selectors. Given the trials/observations you have shared so far, could see that the issue is not specific to any selector value in particular.

Instead it is either

  • Servlet status issue or 
  • The way we call the servlet

Servlet OSGI component Status :

Can you navigate to OSGI components section -> look for servlet and confirm if it is in active state(not in satisfied or unsatisfied reference)

If it is active, click on that component and check if all the properties are intact (per the Servlet file - In particular, resourceTypes, extension and selector)

The way we call the servlet :

Can you share the exact path you are using to test the servlet resolution in Sling -> Sling Servlet Resolver. 

 

Outside this issue, if you are looking to associate multiple selectors to a single servlet, use the respective property as many times needed. (for any multiple value property for that matter)

Example:

@Component(service=Servlet.class,
           property={
        		   ServletResolverConstants.SLING_SERVLET_METHODS+"=GET",                   
           		   ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES+"=weretail/components/structure/page",
           		   ServletResolverConstants.SLING_SERVLET_SELECTORS+"=testselector",
           		   ServletResolverConstants.SLING_SERVLET_SELECTORS+"=testselectortwo",
           		   ServletResolverConstants.SLING_SERVLET_EXTENSIONS+"=json"
           })

 

View solution in original post

11 Replies

Avatar

Employee Advisor

@mpalme1 

Please confirm if you're trying the second servlet on the same resource as first servlet and it also returns a valid json response? (may be you can just try second servlet with exact same logic as first one).

Also check if the servlet component (TestServletTwo) & the bundle are in active state and servlet is registered Sling-> Sling Servlet Resolver.

Avatar

Level 3
Hey @shelly-goel. Thank you so much for responding. The two servlets are part of the same bundle, and it is active. I have been testing from the same page and javascript, just changing the selector in the path for the ajax call between tests. I don't know what registering Sling > Sling Servlet Resolver looks like. Not sure if I've done that or how I would if I haven't.

Avatar

Employee Advisor
@mpalme1 - To check if the servlet is registered, go to felix console > Sling > Sling Servlet Resolver > enter the url (/_jcr_content.testselectortwo.json) and click Resolve to see which servlet is being served. If servlettwo is not returned, it's not registered. For troubleshooting purpose, try removing your first servlet from the bundle and then see if servlettwo is resolved or not. You can also try giving two selectors in a single servlet as comma separated to see if that works (example: https://taradevko.com/aem/sling-selector-best-practice/))

Avatar

Level 3
Hey, @shelly-goel. When I check the two servlets in Sling Servlet Resolver, "testselector" resolves to the TestServlet class, but "testselectortwo" does not resolve to TestServletTwo class. I removed TestServlet from the code entirely and recompiled. TestServletTwo still returns 400 Bad Request. I tried to alter TestServlet using the syntax in the article you linked for multiple selectors, but I get several depreciated warnings, and a requests to it start returning 400 Bad Request.

Avatar

Employee Advisor
@mpalme1 Looks like the servlet component itself is not available/ unsatisfied, you can look for if the TestServletTwo component is in active state here: <aem instance>/system/console/components. If it's not active, need to fix that and other option is to bring back the TestServlet and add comma - separated another selector in that.

Avatar

Community Advisor
looks correct, what is the implementation of the second servlet, is it the same as the first?

Avatar

Community Advisor

Your error says that the issue is with the selector value "testselectortwo". Try changing it and check if it works.

 

Also, In addition to the below steps mentioned by @shelly-goel, can you please share the log entries once you hit the second servlet?

 

Thanks,

Kiran Vedantam.

Avatar

Level 3
Hey @Kiran_Vedantam, thanks for trying to help me. I've tried several different selector names in TestServletTwo and they all get the same 400 Bad Request result. The error.log doesn't show anything about this error right after I hit it. Just a few *INFO* entries about missing .woff files. Those are present when invoking the first servlet successfully, too. But if I try to invoke the request on the second failing servlet directly in chrome developer tools, the response is actually an html page with "invalid recrursion selector value 'testselectortwo'" as the title.

Avatar

Level 3
yes @BrianKasingli. Same implementation. When debugging, I never get to the first line of the servlet that is returning 400 bad request.

Avatar

Correct answer by
Community Advisor

Hi @mpalme1,

I tried to reproduce your scenario in my local and it works fine with two selectors. Given the trials/observations you have shared so far, could see that the issue is not specific to any selector value in particular.

Instead it is either

  • Servlet status issue or 
  • The way we call the servlet

Servlet OSGI component Status :

Can you navigate to OSGI components section -> look for servlet and confirm if it is in active state(not in satisfied or unsatisfied reference)

If it is active, click on that component and check if all the properties are intact (per the Servlet file - In particular, resourceTypes, extension and selector)

The way we call the servlet :

Can you share the exact path you are using to test the servlet resolution in Sling -> Sling Servlet Resolver. 

 

Outside this issue, if you are looking to associate multiple selectors to a single servlet, use the respective property as many times needed. (for any multiple value property for that matter)

Example:

@Component(service=Servlet.class,
           property={
        		   ServletResolverConstants.SLING_SERVLET_METHODS+"=GET",                   
           		   ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES+"=weretail/components/structure/page",
           		   ServletResolverConstants.SLING_SERVLET_SELECTORS+"=testselector",
           		   ServletResolverConstants.SLING_SERVLET_SELECTORS+"=testselectortwo",
           		   ServletResolverConstants.SLING_SERVLET_EXTENSIONS+"=json"
           })

 

Avatar

Level 3
@Vijayalakshmi_S, the syntax you are showing above is what I ended up using, and it works. Specifying both selectors in the same working servlet and handling the different logic inside. I initially avoided this approach because of the recommendations against that approach in this article https://taradevko.com/aem/sling-selector-best-practice/, but at this point, I needed to just get it to work, and this works.