Question

I am trying to use servletcontext.getRealPath in my Util class to load a file resource (Not part of unit testing) but it does not work.

I tried both to use "implements ServletContextAware":

@Component
public class Utils implements ServletContextAware{
    private ServletContext servletContext;

    @Override
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;

        System.out.println("**** "+servletContext);
    }
}

Which throws NPE since servletcontext is not assigned by spring.

And the @Autowired route:

@Component
public class Utils{

    @Autowired
    private ServletContext servletContext;

Which throws NoSuchBeanDefinitionException when tomcat is being starting:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.servlet.ServletContext] found for dependency: expected at le
ast 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

I am adding the my initialization code in case I am doing something wrong which prevents Spring to inject the right bean.

public class WebAppInitializer implements WebApplicationInitializer {

    private static Logger LOG = LoggerFactory.getLogger(WebAppInitializer.class);

    @Override
    public void onStartup(ServletContext servletContext) {
        WebApplicationContext rootContext = createRootContext(servletContext);

        configureSpringMvc(servletContext, rootContext);

        FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", CORSFilter.class);
        corsFilter.addMappingForUrlPatterns(null, false, "/*");

//        configureSpringSecurity(servletContext, rootContext);
    }

    private WebApplicationContext createRootContext(ServletContext servletContext) {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

//        rootContext.register(CoreConfig.class, SecurityConfig.class);
        rootContext.register(CoreConfig.class);
        rootContext.refresh();

        servletContext.addListener(new ContextLoaderListener(rootContext));
        servletContext.setInitParameter("defaultHtmlEscape", "true");

        return rootContext;
    }

CoreConfig.class:

@Configuration
public class CoreConfig {

    @Bean
    public CaptionFixture createCaptionFixture() {
        return new CaptionFixture();
    }

    @Bean
    public Utils createUtils () {
        return new Utils();
    }
}

Utils is the class with the servlet context.

I have looked at the suggested answers: here and here and it didnt work.

Was it helpful?

Solution

The issue is that you are calling refresh() without a ServletContext being registered, so none is available when the beans are initialized.

Get rid of this call

rootContext.refresh();

The ContextLoaderListener will take care of calling refresh(). The constructor javadoc explains what happens when the ApplicationContext passed as an argument isn't refreshed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top