I have a Spring Boot web application that works fine. Now I got a 3rd party lib which I must use in the project. The manual of integrating the lib is written with respect to an existing web.xml file. My project completely relies on a Java based config.
According to the Spring documentation I can reach my goal of taking over the web.xml content into my application with the help of a WebApplicationInitializer.
That's what I did (at least I think I did it correctly). Before going into more details, here is the web.xml:
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>some.package.path.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>some.package.path.LogoutServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>ResultServlet</servlet-name>
<servlet-class>some.package.path.ResultServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/saml/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/saml/logout</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ResultServlet</servlet-name>
<url-pattern>/saml/result</url-pattern>
</servlet-mapping>
<env-entry>
<env-entry-name>some.package.path.config-file</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>$HOME/.libName/libName-config.xml</env-entry-value>
</env-entry>
And here is how I refactored this in a Java config:
public class WebAppInitializer implements WebApplicationInitializer {
private static final Logger LOG = Logger.getLogger(WebAppInitializer.class.getSimpleName());
@Override
public void onStartup(ServletContext servletContext) {
final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.scan("de.davidartmann.myapp.configuration");
final ServletRegistration.Dynamic dispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(context));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
final ServletRegistration.Dynamic loginServlet =
servletContext.addServlet("LoginServlet", LoginServlet.class);
loginServlet.addMapping("/saml/login");
final ServletRegistration.Dynamic logoutServlet =
servletContext.addServlet("LogoutServlet", LogoutServlet.class);
logoutServlet.addMapping("/saml/logout");
final ServletRegistration.Dynamic resultServlet =
servletContext.addServlet("ResultServlet", ResultServlet.class);
resultServlet.addMapping("/saml/result");
try {
final InitialContext initialContext = new InitialContext();
initialContext.addToEnvironment("some.package.path.config-file",
"$HOME/.libName/libName-config.xml");
} catch (NamingException e) {
LOG.log(Level.SEVERE, "Could not initialize an InitialContext", e);
}
}
}
The problem is that the 3rd party lib throws an internal NPE with this setup. The NPE is thrown at the point where it @Inject
s (based on CDI) the runtime object of the <env-entry>
in the web.xml which I implemented as InitialContext
in my WebAppInitializer class.
My Spring Boot application uses a SpringBootServletInitializer
. The Spring documentation about Traditional Deployment mentions it with the words:
Normally, all the code from an existing WebApplicationInitializer can be moved into a SpringBootServletInitializer
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(MyApplication.class);
}
}
Now, I am a unsure what to do? Is my implementation of WebApplicationInitializer
correct or do I need to use the SpringBootServletInitializer
in my Spring Boot main class?
Thanks for your help. David