Hi, I have a servlet that performs a function, I have tested it and it works, to make it execute it is necessary to write the domain name followed by bin/serviceexecution.
But now we want it to run only every so often, for that we have created a scheduler.
The problem is that the scheduler is executed but when arriving to the call of the servlet, this fails, mentioning that we do not have permissions to execute the servlet.
I think it is because to execute this servlet I need permissions, which I don't know how to set them.
How could I add them or know what is the error.
this is the code I made
Solved! Go to Solution.
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Hi @Aaron_Dempwolff ,
If you want to schedule the logic currently written inside your servlet, the better approach is to define an OSGi service that contains the actual business logic. Then, both your servlet and your scheduler can simply call this service directly instead of making an HTTP call.
The issue you're facing is happening because, when your scheduler makes an HTTP request to the servlet, it is treated as an anonymous user (no authentication), and therefore you don't have the permissions to execute the servlet.
Let me know if it works.
Thanks.
Hi @Aaron_Dempwolff ,
If you want to schedule the logic currently written inside your servlet, the better approach is to define an OSGi service that contains the actual business logic. Then, both your servlet and your scheduler can simply call this service directly instead of making an HTTP call.
The issue you're facing is happening because, when your scheduler makes an HTTP request to the servlet, it is treated as an anonymous user (no authentication), and therefore you don't have the permissions to execute the servlet.
Let me know if it works.
Thanks.
It works, thank you, even the cool part is that it work now like an scheduler and it works executing manually too.
Hi @Aaron_Dempwolff,
The exact problem in your approach is that the scheduler was making an HTTP call to the servlet endpoint (/bin/serviceexecution) internally.
Since the HTTP call originates from inside AEM without any authentication, it is treated as an anonymous user request.
Because of that, permissions are missing, and the servlet execution fails.
Instead of making an HTTP call from within the scheduler (which treats the request as anonymous and causes permission issues), IMO, the correct architectural approach is:
Extract the core business logic from the servlet into a separate OSGi service.
Inject and use this service both inside the servlet and the scheduler.
This way, the logic runs internally within the OSGi container, bypassing the need for HTTP requests and avoiding authentication or permission issues entirely.
It also improves maintainability, testability, and performance since no network overhead is involved.
This way it helps you to ensures that servlets handle HTTP communication only, while business logic is managed independently.
Hope that helps!
I second suggestions from @SantoshSai and @ShivamKumar
However, if for some reason you cannot change the code immediately, then consider using SlingRequestProcessor . Please refer the blog:
https://kiransg.com/2023/05/16/sling-servlet-helpers/
Views
Replies
Total Likes
Hi @Aaron_Dempwolff ,
You're running into a common AEM mistake: your scheduler is calling your servlet via HTTP, which executes as an anonymous user — causing permission errors when accessing restricted content or services.
Step 1: Extract Business Logic to a Service
@Component(service = MyService.class)
public class MyService {
private static final Logger log = LoggerFactory.getLogger(MyService.class);
public void executeLogic() {
// Put your servlet's logic here
log.info("MyService: Logic executed");
}
}
Step 2: Use This Service in Your Servlet
@Component(
service = Servlet.class,
property = {
"sling.servlet.paths=/bin/serviceexecution",
"sling.servlet.methods=GET"
}
)
public class MyServlet extends SlingSafeMethodsServlet {
@Reference
private MyService myService;
@Override
protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
myService.executeLogic(); // Call the shared logic
response.getWriter().write("Logic executed from servlet");
}
}
Step 3: Use Same Service in Your Scheduler Update your scheduler:
@Component(service = Runnable.class, immediate = true)
@Designate(ocd = SchedulerUseConfig.class)
public class SchedulerUse implements Runnable {
private static final Logger log = LoggerFactory.getLogger(SchedulerUse.class);
@Reference
private Scheduler scheduler;
@Reference
private MyService myService; // Inject business logic
private int schedulerId;
private SchedulerUseConfig config;
@Activate
@Modified
protected void activate(SchedulerUseConfig config) {
this.config = config;
schedulerId = config.schedulerName().hashCode();
updateScheduler();
}
@Deactivate
protected void deactivate() {
removeScheduler();
}
private void removeScheduler() {
scheduler.unschedule(String.valueOf(schedulerId));
}
private void updateScheduler() {
removeScheduler();
if (config.enabled()) {
ScheduleOptions scheduleOptions = scheduler.EXPR(config.cronExpression());
scheduleOptions.name(String.valueOf(schedulerId));
scheduleOptions.canRunConcurrently(false);
scheduler.schedule(this, scheduleOptions);
}
}
@Override
public void run() {
log.info("Scheduler: Triggering logic execution");
myService.executeLogic(); // Call shared logic (no HTTP)
}
}
Benefits of This Approach:
- No authentication issues
- No unnecessary HTTP overhead
- Centralized logic
- Cleaner separation of concerns
- Works in Cloud Service, AMS, On-Prem setups
Regards,
Amit
Views
Replies
Total Likes
@Aaron_Dempwolff Did you find the suggestions helpful? Please let us know if you require more information. Otherwise, please mark the answer as correct for posterity. If you've discovered a solution yourself, we would appreciate it if you could share it with the community. Thank you!
Views
Replies
Total Likes
Views
Likes
Replies
Views
Likes
Replies