spring boot FileNotFoundException: Could not open ServletContext resource [/WEB-INF/main-servlet.xml]

19,119

Unless you are running your application as WAR, the src/main/webapp folder won't be included in the output as stated in the documentation:

Do not use the src/main/webapp folder if your application will be packaged as a jar. Although this folder is a common standard, it will only work with war packaging and it will be silently ignored by most build tools if you generate a jar.

So that may be your problem.

To fix it try to set config location explicitly for the main servlet:

servlet.addInitParameter("contextConfigLocation", "classpath:main-servlet.xml");

and place the main-servlet.xml file in src/main/resources.

Hope this helps.

Share:
19,119
mangusbrother
Author by

mangusbrother

Updated on June 21, 2022

Comments

  • mangusbrother
    mangusbrother almost 2 years

    I am running a spring boot application with the following application class:

    @EnableAutoConfiguration
    @Configuration
    public class FakeAppBooter extends SpringBootServletInitializer{
    
        public static void main(String args[]) {
            SpringApplication.run(FakeAppBooter.class, args);
            System.out.println("Test");
        }
        @Bean
        public EmbeddedServletContainerFactory servletContainer() {
            TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
            factory.setTomcatContextCustomizers(Arrays.asList(new CustomCustomizer()));
            factory.addErrorPages(
                    new ErrorPage(HttpStatus.UNAUTHORIZED,"/WEB-INF/views/unprot/common/errors/containerError.jsp"),
                    new ErrorPage(HttpStatus.NOT_FOUND,"/WEB-INF/views/unprot/common/errors/containerError.jsp"),
                    new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR,"/WEB-INF/views/unprot/common/errors/containerError.jsp"));
            MimeMappings mappings = new MimeMappings(MimeMappings.DEFAULT);
            mappings.add("xsd", "text/xml");
            mappings.add("wsdl", "text/xml");
            factory.setMimeMappings(mappings);
            return factory;
        }
    
        static class CustomCustomizer implements TomcatContextCustomizer {
            @Override
            public void customize(Context context) {
                context.setUseHttpOnly(true);
                context.addWelcomeFile("home.html");
            }
        }
    
        @Bean
        public ServletContextInitializer initializer() {
            return new ServletContextInitializer() {
                @Override
                public void onStartup(ServletContext servletContext) throws ServletException {
                    servletContext.setInitParameter("parentContextKey", "globalContext");
                    servletContext.setInitParameter("contextConfigLocation", "classpath*:com/my/**/fakeContext.xml");
                }
            };
        }
    
        @Bean
        public ServletRegistrationBean mainServlet(){
            ServletRegistrationBean servlet = new ServletRegistrationBean();
            servlet.setName("main");
            servlet.setServlet(new DispatcherServlet());
            servlet.addUrlMappings("*.html","*.htmlf","*.json",
                    "/my/issue","/my/query","/my/adjust","/my/echo");
            return servlet;
        }
        @Bean
        public ServletRegistrationBean cxfServlet(){
            ServletRegistrationBean servlet = new ServletRegistrationBean();
            servlet.setName("CXFServlet");
            servlet.setServlet(new CXFServlet());
            servlet.setLoadOnStartup(1);
            servlet.addUrlMappings("/services/*");
            return servlet;
        }
        @Bean
        public ServletRegistrationBean axisServlet(){
            ServletRegistrationBean servlet = new ServletRegistrationBean();
            servlet.setName("AxisServlet");
            servlet.setServlet(new AxisServlet());
            servlet.addInitParameter("axis.servicesPath", "/axis/");
            servlet.addUrlMappings("/axis/*","*.jws");
            return servlet;
        }
    
        @Bean
        public FilterRegistrationBean httpMethodFilter(){
            FilterRegistrationBean filter = new FilterRegistrationBean();
            filter.setName("httpMethod");
            filter.setFilter(new HiddenHttpMethodFilter());
            filter.addUrlPatterns("*.html","*.htmlf","*.json");
            return filter;
        }
    
        @Bean
        public FilterRegistrationBean sitemeshFilter(){
            FilterRegistrationBean filter = new FilterRegistrationBean();
            filter.setName("sitemesh");
            filter.setFilter(new SiteMeshFilter());
            filter.addUrlPatterns("*.html");
            return filter;
        }
    }
    

    My layout is as follows

    • src/main/java
      • boot/FakeAppBooter.java
    • src/main/webapp
      • WEB-INF
        • main-servlet.xml
    • src/main/resources

    I have tried using above layout, as well as moving the WEB-INF folder to the resources folder

    If I package the project as war file with WEB-INF under weabpp, I get the WEB-INF folder in the root of the war file, however on startup I get:

    java.lang.reflect.InvocationTargetException
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:601)
            at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:53)
            at java.lang.Thread.run(Thread.java:722)
    Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [WEB-INF/main-servlet.xml]; nested exception is java.io.FileNotFoun
    dException: class path resource [WEB-INF/main-servlet.xml] cannot be opened because it does not exist
            at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:343)
            at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
            at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
            at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)
            at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187)
            at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromImportedResources(ConfigurationClassBeanDefinitionReader.java:313)
            at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:138)
            at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:116)
            at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:330)
            at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:243)
            at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:254)
            at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:94)
            at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:611)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
            at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
            at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
            at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
            at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
            at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
            at boot.FakeAppBooter.main(FakeAppBooter.java:73)
            ... 6 more
    Caused by: java.io.FileNotFoundException: class path resource [WEB-INF/main-servlet.xml] cannot be opened because it does not exist
            at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)
            at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:329)
            ... 25 more
    

    If I move the WEB-INF folder to the resources folder and package as a jar file, I get no error on startup, however I still get the FileNotFoundException when I try to load a webpage, as follows:

    java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/main-servlet.xml]
            at org.springframework.web.context.support.ServletContextResource.getInputStream(ServletContextResource.java:141)
            at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:329)
            at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
            at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
            at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)
            at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187)
            at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
            at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
            at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
            at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:542)
            at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:454)
            at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:658)
            at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:624)
            at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:672)
            at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:543)
            at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:484)
            at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
            at javax.servlet.GenericServlet.init(GenericServlet.java:244)
            at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
            at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:884)
            at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:134)
            at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
            at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
            at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
            at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
            at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
            at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
            at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
            at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
            at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
            at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
            at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
            at java.lang.Thread.run(Thread.java:722)