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

Avatar

Avatar

mpalme1

Avatar

mpalme1

mpalme1

29-12-2020

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?

Accepted Solutions (1)

Accepted Solutions (1)

Avatar

Avatar

Vijayalakshmi_S

MVP

Avatar

Vijayalakshmi_S

MVP

Vijayalakshmi_S
MVP

04-01-2021

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"
           })

 

Answers (2)

Answers (2)

Avatar

Avatar

KiranVedantam1992

Avatar

KiranVedantam1992

KiranVedantam1992

04-01-2021

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

Avatar

shelly-goel

MVP

Avatar

shelly-goel

MVP

shelly-goel
MVP

29-12-2020

@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.

mpalme1
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.
shelly-goel
@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/))
mpalme1
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.
shelly-goel
@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.