Search code examples
javaspringspring-bean

Invalid bean definition: Could not resolve placeholder


I'm using springframework first time. So wrote a small program and to test value of Instance variable generated in IoC. But I am getting below error:

Feb 24, 2019 10:40:13 PM org.springframework.context.support.AbstractApplicationContext refresh
WARNING: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'loadingObject' defined in class path resource [Spring-Config.xml]: Could not resolve placeholder 'log4j.configuration' in value "${log4j.configuration}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'log4j.configuration' in value "${log4j.configuration}"
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean definition with name 'loadingObject' defined in class path resource [Spring-Config.xml]: Could not resolve placeholder 'log4j.configuration' in value "${log4j.configuration}"; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'log4j.configuration' in value "${log4j.configuration}"
    at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:228)
    at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.processProperties(PropertyPlaceholderConfigurer.java:213)
    at org.springframework.beans.factory.config.PropertyResourceConfigurer.postProcessBeanFactory(PropertyResourceConfigurer.java:86)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:286)
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:166)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:691)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:528)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
    at com.jcg.spring.log4j.Mainclass.main(Mainclass.java:12)
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'log4j.configuration' in value "${log4j.configuration}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:172)
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124)
    at org.springframework.beans.factory.config.PropertyPlaceholderConfigurer$PlaceholderResolvingStringValueResolver.resolveStringValue(PropertyPlaceholderConfigurer.java:232)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveStringValue(BeanDefinitionVisitor.java:296)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveValue(BeanDefinitionVisitor.java:217)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitPropertyValues(BeanDefinitionVisitor.java:147)
    at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitBeanDefinition(BeanDefinitionVisitor.java:85)
    at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:225)
    ... 9 more

I've placed my application.properties file and Spring-Config.xml metadata file to this location ...\src\main\resources

application.properties

log4j.configuration=C:\Softwares\ConfigFiles\log4j.properties

Spring-Config.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="propertiesToBeTaken" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath*:application.properties</value>
                <value>classpath*:*keys.properties</value>
            </list>
        </property>
    </bean>

    <bean id = "loadingObject" class = "com.jcg.spring.log4j.TestController">
        <property name="log4jConfig" value="${log4j.configuration}" />
    </bean> 

</beans>

Code Snippet

public class TestController  {

    public String log4jConfig;

    public void setlog4j(String log4jConfig){

        this.log4jConfig = log4jConfig;

    }

    public  String getlog4j(){

        return this.log4jConfig;
    }

}

public class Mainclass {

    public static void main(String[] args){


        ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Config.xml");
        TestController obj = (TestController) context.getBean("TestController");
        System.out.println(obj.log4jCongif);



    }

}

Everything seems to be okay, But not sure why this error is coming. Stuck in this for a while. Can anyone please have a look? What I am missing?

Thanks


Solution

  • It seems Spring container is trying to instantiate TestController bean before the PropertyPlaceholderConfigurer so property is not getting resolved, hence the error.

    You can try putting <property name="ignoreUnresolvablePlaceholders" value="true"/> into Spring-Config.xml to tell spring to ignore unresolved properties. Once PropertyPlaceholderConfigurer will be instantiated possibly property will get resolved.

    Try this

    <bean id="propertiesToBeTaken" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:application.properties</value>
                <value>classpath:keys.properties</value>
            </list>
        </property>
        <property name="ignoreUnresolvablePlaceholders" value="true"/>
    </bean>
    

    Plus few more changes:

    • TestController obj = (TestController) context.getBean("loadingObject");
    • setter method name: setLog4jConfig
    • getter method name: getLog4jConfig