ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events
Asked Answered
T

2

13

I am trying to implement ehcache for my application but when try invoking the server, getting the following error -

java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: WebApplicationContext for namespace 'dispatcher-servlet': startup date [Thu Apr 16 14:37:53 IST 2015]; root of context hierarchy
    at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:344)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:331)
    at org.springframework.web.servlet.FrameworkServlet.publishRequestHandledEvent(FrameworkServlet.java:1061)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:996)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    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.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    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.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

Steps that I did follow -

STEP1 - Created ehcache.xml file under /src/main/resources as can be seen below -

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="ehcache.xsd" 
    updateCheck="true"
    monitoring="autodetect" 
    dynamicConfig="true">

    <diskStore path="java.io.tmpdir" />

    <cache name="movieFindCache" 
        maxEntriesLocalHeap="10000"
        maxEntriesLocalDisk="1000" 
        eternal="false" 
        diskSpoolBufferSizeMB="20"
        timeToIdleSeconds="300" timeToLiveSeconds="600"
        memoryStoreEvictionPolicy="LFU" 
        transactionalMode="off">
        <persistence strategy="localTempSwap" />
    </cache>

</ehcache>

STEP2 - Added following to appconfig.java

@Bean
    public CacheManager getEhCacheManager(){
            return  new EhCacheCacheManager(getEhCacheFactory().getObject());
    }
    @Bean
    public EhCacheManagerFactoryBean getEhCacheFactory(){
        EhCacheManagerFactoryBean factoryBean = new EhCacheManagerFactoryBean();
        factoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        factoryBean.setShared(true);
        return factoryBean;
    }

STEP3 - Added following to webappinitializer.java which is called on startup

AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();  
        ctx.register(AppConfig.class);  
        ctx.register(HibernateConfiguration.class); 
        ctx.setServletContext(servletContext);    
        Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));  
        dynamic.setLoadOnStartup(1); 

STEP4 - pom.xml contains -

<dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.3.8.Final</version>
    </dependency>




    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.9.0</version>
    </dependency>

        <!-- Optional, to log stuff -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.0.13</version>
    </dependency>

    <!-- Spring caching framework inside this -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>

    <!-- Support for Ehcache and others -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>4.1.4.RELEASE</version>
    </dependency>





    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-osgi</artifactId>
        <version>4.3.8.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-envers</artifactId>
        <version>4.3.8.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
        <version>4.3.8.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-proxool</artifactId>
        <version>4.3.8.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-infinispan</artifactId>
        <version>4.3.8.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>4.3.8.Final</version>
    </dependency>

I am unable to understand the root cause of the above error. Any help is appreciated.

Topaz answered 16/4, 2015 at 9:23 Comment(4)
For starters don't mix versions of spring, secondly use the starters and use spring boot for the configuration.Dig
use the starters means? Also, if you could please elaborate a bit on using spring boot for configuration. I thought I am using the same.Topaz
You are using spring boot but are trying very hard not to use spring boot. By specifying all the configuration, not using the auto configuration features and by not using the spring boot starters.Dig
Thank you Deinum. I am gonna give it a try the way you said.Topaz
S
6

This is kinda stupid but my problem was that I had placed the @SpringBootApplication class (namely App, Application, WebApplication in most projects) inside the default package. Hence, everything was in total disarray.

I'm not sure why this exact error showed up, but moving the application class to a package sure fixed it.

Sensor answered 15/6, 2017 at 15:2 Comment(1)
Indeed, strangely moving the starter application class to a different package solves the problem.Gallfly
T
2

The idea behind spring-boot is that all the configurations are done automatically by spring.

In you case use the following POM.

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.3.RELEASE</version>
    </parent>

     <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.9.0</version>
    </dependency>
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
  </dependencies>

Add the following application.properties in your src/main/resources.

spring.datasource.url=jdbc:mysql://localhost:3306/soschema
spring.datasource.username=root
spring.datasource.password=root123
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# Specify the DBMS
spring.jpa.database = MYSQL

# Show or not log for each sql query
spring.jpa.show-sql = true

# Hibernate settings are prefixed with spring.jpa.hibernate.*
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.jpa.hibernate.naming_strategy = org.hibernate.cfg.ImprovedNamingStrategy

Add the Appconfig file,

package org.arunm.ehcacheconfig;


import org.springframework.cache.CacheManager;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;


@Configuration
public class AppConfig {

    @Bean
    public CacheManager getEhCacheManager(){
            return  new EhCacheCacheManager(getEhCacheFactory().getObject());
    }
    @Bean
    public EhCacheManagerFactoryBean getEhCacheFactory(){
        EhCacheManagerFactoryBean factoryBean = new EhCacheManagerFactoryBean();
        factoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        factoryBean.setShared(true);
        return factoryBean;
    }

}

Add a top level class with the following code,

package org.ehcachetest;

import java.util.Arrays;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ComponentScan;

/**
 * Hello world!
 *
 */

@EnableAutoConfiguration
@ComponentScan
public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext ctx = SpringApplication.run(App.class, args);

        String[] beanNames = ctx.getBeanDefinitionNames();
        Arrays.sort(beanNames);
        for (String beanName : beanNames) {
            System.out.println(beanName);
        }
    }
}

If you run App the main method you will find that spring has automatically created the sessionFactory, TransactionManager etc for you. There is no need for any manual configuration which means there is no need to add the dispatcherservlet, your hibernate config etc. Everything is managed by spring.

Tisbe answered 16/4, 2015 at 12:29 Comment(2)
Thank you ArunM for being that articulate. Trying it as you suggested. But there is no top level class it seems but webinitializer.java that has a onstartup method. Any sugesstions?Topaz
The point is you dont need a webinitializer.jav. Spring has already created that for you. Run the code and check the output if the App class .. You can see the list of beans .. Check out vids on youtube as well from springdeveloper ..Tisbe

© 2022 - 2024 — McMap. All rights reserved.