Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring 5 - No ServletContext set exception

When I try to run my app based on Spring 5 using AnnotationConfigApplicationContext class, getting the exception No ServletContext set.

Here is my main method:

public class Run {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

        context.register(AppConfig.class);
        context.register(WebConfig.class);
        context.register(WebAppInitializer.class);
        context.refresh();

        MainService mainService = (MainService ) context.getBean("mainService ");
        mainService.loadData();
    }

}

AppConfig defines the transactionManager and sessionFactory beans:

@PropertySource("classpath:hibernate.properties")
@EnableTransactionManagement
@Configuration
@ComponentScan(basePackages = {"com.tk"})
@ComponentScans(value = { @ComponentScan("com.tk.spring4App.service"),
                          @ComponentScan("com.tk.spring4App.dao") })
public class AppConfig {

    @Autowired
    private Environment env;

    @Bean
    public LocalSessionFactoryBean getSessionFactory() {
        LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();

        Properties props = new Properties();
        // Setting JDBC and hibernate properties

        factoryBean.setHibernateProperties(props);
        factoryBean.setAnnotatedClasses(SampleObject.class);
        return factoryBean;
    }

    @Bean
    public HibernateTransactionManager getTransactionManager() {
        HibernateTransactionManager transactionManager = new HibernateTransactionManager();
        transactionManager.setSessionFactory(getSessionFactory().getObject());
        return transactionManager;
    }

}

Here is my WebConfig class:

@PropertySource({
        "classpath:mail.properties",
        "classpath:ldap.properties"
})
@EnableScheduling
@EnableAspectJAutoProxy
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = {"com.tk"})
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private Environment env;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/resources/")
                .setCachePeriod(3600)
                .resourceChain(true)
                .addResolver(new PathResourceResolver());
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public InternalResourceViewResolver jspViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/view/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Bean(name = "multipartResolver")
    public CommonsMultipartResolver getMultipartResolver() {
        return new CommonsMultipartResolver();
    }

    @Bean(name = "messageSource")
    public ReloadableResourceBundleMessageSource getMessageSource() {
        ReloadableResourceBundleMessageSource resource = new ReloadableResourceBundleMessageSource();
        resource.setBasename("classpath:messages");
        resource.setDefaultEncoding("UTF-8");
        return resource;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new ControllerInterceptor()).addPathPatterns("/*");
    }

    @Bean
    public TaskScheduler taskExecutor() {
        return new ConcurrentTaskScheduler(Executors.newScheduledThreadPool(3));
    }

    @Bean(name = "mailSender")
    public JavaMailSender getJavaMailSender() {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

        mailSender.setHost(env.getRequiredProperty("mail.host"));
        mailSender.setPort(Integer.parseInt(env.getRequiredProperty("mail.port")));
        mailSender.setUsername(env.getRequiredProperty("mail.username"));
        mailSender.setPassword(env.getRequiredProperty("mail.password"));

        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", env.getRequiredProperty("mail.transport.protocol"));
        props.put("mail.smtp.auth", env.getRequiredProperty("mail.smtp.auth"));
        props.put("mail.smtp.starttls.enable", env.getRequiredProperty("mail.smtp.starttls.enable"));
        props.put("mail.debug", env.getRequiredProperty("mail.debug"));

        return mailSender;
    }

    @Bean
    public LdapContextSource contextSource() {
        LdapContextSource contextSource = new LdapContextSource();
        contextSource.setUrl(env.getRequiredProperty("ldap.url"));
        contextSource.setBase(env.getRequiredProperty("ldap.base"));
        contextSource.setUserDn(env.getRequiredProperty("ldap.user"));
        contextSource.setPassword(env.getRequiredProperty("ldap.password"));
        return contextSource;
    }

    @Bean
    public LdapTemplate ldapTemplate() {
        return new LdapTemplate(contextSource());
    }

}

The WebAppInitializer class simply initialize the app:

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) {
        WebApplicationContext context = getContext();
        servletContext.addListener(new ContextLoaderListener(context));
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);
        servletContext.addFilter("characterEncodingFilter", characterEncodingFilter).addMappingForUrlPatterns(null, false, "/*");
    }

    private AnnotationConfigWebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation("com.tk.spring4App.config");
        return context;
    }

}
like image 565
talha06 Avatar asked Feb 16 '18 07:02

talha06


1 Answers

I managed to find a reason why this was happening. My config was split into several files and I was creating a MVC related bean in the Security Config (which was created earlier) forcing to use the MVC config before its time.

The solution was to move the @Bean instance from the security config to the MVC config. I hope it helps other people!

like image 89
Esteban Avatar answered Oct 12 '22 11:10

Esteban