Issue
I have a spring boot application that is being deployed to an external instance of Tomcat. The main class extends SpringBootServletInitializer and overrides the methods configure and onStartup. In the method configure, a custom environment is initialized to provide an encryptor for decrypting user passwords for activemq because jasypt is not initialized until after activemq. This I got from the jasypt-spring-boot documentation.
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
try {
StandardEncryptableServletEnvironment env = StandardEncryptableServletEnvironment.builder().encryptor(encryptor).build();
return application.environment(env).sources(AxleServer.class);
} catch (FileNotFoundException e) {
logger.error("Could not load encryptable environment", e);
return application.sources(AxleServer.class);
}
}
In the method onStartup I am configuring DispatcherServlets:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(RemotingConfig.class);
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("rest-dispatcher", new DispatcherServlet(context));
restDispatcher.setLoadOnStartup(1);
restDispatcher.addMapping("/rest/*");
ServletRegistration.Dynamic remotingDispatcher = servletContext.addServlet("remoting-dispatcher", new DispatcherServlet(context));
remotingDispatcher.setLoadOnStartup(2);
remotingDispatcher.addMapping("/remoting/*");
}
The problem is that the configure method is never called because it is called from the super implementation of onStartup. I tried calling the super implementation super.onStartup(servletContext);
but then I get an error that a root context already exists when deploying the app.
What is the correct way to register the DispatcherServlets and to override the onStartup method? Is it required to call the super implementation of onStartup?
Solution
I was able to solve this issue by first calling the super.onStartup and then getting the root context from ServletContext attributes
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
Object obj = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
if(obj instanceof AnnotationConfigServletWebServerApplicationContext) {
AnnotationConfigServletWebServerApplicationContext context = (AnnotationConfigServletWebServerApplicationContext) obj;
context.register(RemotingConfig.class);
ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("rest-dispatcher", new DispatcherServlet(context));
restDispatcher.setLoadOnStartup(1);
restDispatcher.addMapping("/rest/*");
ServletRegistration.Dynamic remotingDispatcher = servletContext.addServlet("remoting-dispatcher", new DispatcherServlet(context));
remotingDispatcher.setLoadOnStartup(2);
remotingDispatcher.addMapping("/remoting/*");
}
}
Answered By - user1932673
Answer Checked By - Katrina (JavaFixing Volunteer)