11
votes

I have below map bean definition in application context xml and used the map in controller which is causing BeanDefinitionParsingException for spring boot 2.1.3 upgrade. It works fine in 2.0.6 version.

Does anyone know how to resolve this issue?

Defining "spring.main.allow-bean-definition-overriding=true" in application properties doesn't fix the issue.

@SpringBootApplication
@PropertySource("classpath:app.properties")
public class Application extends SpringBootServletInitializer {


    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) throws Exception {// NOSONAR
        SpringApplication.run(Application.class, args);
    }

}

@Configuration
public class ApplicationConfig {

    @Configuration
    @ImportResource("classpath*:applicationContext.xml")    
    public static class XmlImportingConfiguration {
    }

}

app.properties
#Spring Boot
server.contextPath=/myapp
server.servlet.context-path=/myapp
spring.application.name=myapp
server.tomcat.max-threads=200
server.port=901
server.error.whitelabel.enabled=false

logging.level.org.springframework.web: INFO
logging.level.org.springframework: INFO
logging.level.com.wellsfargo: INFO
server.tomcat.accessLogEnabled=false
logging.config=config/log4j2.xml

spring.view.prefix: /WEB-INF/jsp/
spring.view.suffix: .jsp

applicationContext.xml 
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

        <util:map id="lookup">
            <entry key="60" value="1 hour"></entry>
            <entry key="480" value="8 hours"></entry>
            <entry key="1440" value="24 hours"></entry>
            <entry key="2880" value="2 days"></entry>
        </util:map>
</beans>

@Controller
@RequestMapping("/")
public class MyController{
    @Resource(name="lookup")
    private Map<String,String> lookup;

}

Error:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Invalid bean definition with name 'lookup' defined in null: Cannot register bean definition [Generic bean: class [org.springframework.beans.factory.config.MapFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'lookup': There is already [Generic bean: class [org.springframework.beans.factory.config.MapFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.

3
where did you define the map and is it included in the configurationSimon Martinelli
it's defined in applicationContext.xmlskumar
Can you add your application context xml?Darren Forsythe
@skumar I've added a basic example github.com/DarrenForsythe/resource-bean-override the only way I can re-create the issue is having two beans named "lookup", which makes me think there is another hiding somewhere with the name lookup - note bean definition is related to the name of the beans not their types, so if theres another called "lookup" definined anywhere else it will errorDarren Forsythe
@skumar as Darren pointed out there is another lookup defined somewhere else clean your build folders manually it may be because of IDE issue alsoManoj Ramanan

3 Answers

7
votes

I have workaround for this problem. Basically moved the map from applicationContext.xml to application properties and retrieved using @Value like below.

app.properties
lookup={'60':'Last 1 hour','480':'Last 8 hours','1440':'Last 24 hours','2880':'Last 2 days'}

ApplicationProperties.java
    @Value("#{${lookup}}")
    private Map<String,String> lookupTimeinterval;
0
votes

This might not be what are you looking for but why not to replace XML with Java Config. You should not enable bean overriding as it makes debugging Spring IoC startup problems very, very hard.

@Configuration
public class ApplicationConfig {

    @Bean
    public Map<String, String> lookup() {
      return Map.of(
            "60", "1 hour", 
            "480", "8 hour", 
            "1440", "24 hours", 
            "2880", "2 days"
      );
    }

}
0
votes

you can also if you want to instead of using a "application.properties" file you can use a "yaml" file.

Yaml has support for key values in properties.

application.yaml

myVales:
  60: "1 hour" 
  480: "8 hour" 
  1440: "24 hours" 
  2880: "2 days"

MyConfig.class

@Configuration
@ConfigurationProperties
public class MyConfig {

    private Map<String, String> myValues;

    //getters

}