Java – Could not resolve placeholder for some property

javajavabeansspring

org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'dbDataSource' defined in
cz.ita.javaee.config.DatabaseConfiguration: Unexpected exception
during bean creation; nested exception is
java.lang.IllegalArgumentException: Could not resolve placeholder
'db.jndi' in value "${db.jndi}" at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:518)
at
org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
at
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
at
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756)
at
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
at
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at
org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:409)
at
org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)
at
org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at
org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4743)
at
org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5207)
at
org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at
org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:752)
at
org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:728)
at
org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)
at
org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1739)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at
com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at
com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at
org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:482)
at
org.apache.catalina.mbeans.MBeanFactory.createStandardContext(MBeanFactory.java:431)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
at
com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
at
com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)
at
javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1468)
at
javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76)
at
javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309)
at
javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401)
at
javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:357)
at sun.rmi.transport.Transport$1.run(Transport.java:200) at
sun.rmi.transport.Transport$1.run(Transport.java:197) at
java.security.AccessController.doPrivileged(Native Method) at
sun.rmi.transport.Transport.serviceCall(Transport.java:196) at
sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568)
at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826)
at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683)
at java.security.AccessController.doPrivileged(Native Method) at
sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748) Caused by:
java.lang.IllegalArgumentException: Could not resolve placeholder
'db.jndi' in value "${db.jndi}" at
org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:172)
at
org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124)
at
org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:237)
at
org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:211)
at
org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175)
at
org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:834)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1081)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1060)
at
org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:809)
at
org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:715)
at
org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:458)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1249)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1098)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
at
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
… 55 more

My Database Configuration class:

@EnableTransactionManagement
public class DatabaseConfiguration {

    @Bean(name = "dbDataSource")
    @Profile("!development")
    public DataSource dataSource(@Value("${db.jndi}") String dbJndiName) {
        JndiDataSourceLookup lookup = new JndiDataSourceLookup();
        return lookup.getDataSource(dbJndiName);
    }

    @Profile("development")
    public DataSource dataSource(@Value("${development.db.driver}") String dbDriver,
            @Value("${development.db.url}") String dbUrl,
            @Value("${development.db.username}") String dbUsername,
            @Value("${development.db.password}") String dbPassword) {
        DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource(dbUrl);
        driverManagerDataSource.setDriverClassName(dbDriver);
        driverManagerDataSource.setUsername(dbUsername);
        driverManagerDataSource.setPassword(dbPassword);
        return driverManagerDataSource;
    }

}

And AppConfig:

@Import({DatabaseConfiguration.class, MailSenderConfiguration.class})
public class AppConfig {
@Bean
public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
    PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
    propertyPlaceholderConfigurer.setLocation(new ClassPathResource("application.properties"));
    propertyPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
    return propertyPlaceholderConfigurer;
}

}

Hi, I got error above and I don't know how to fix it, can you help me? My project working fine until I've added this bean:

@PropertySource("classpath:mail.properties")
public class MailSenderConfiguration {

@Value("${mail.smtp.host}")
private String mailHost;

@Value("${mail.smtp.port}")
private int mailPort;

@Value("${mail.username}")
private String mailUsername;

@Value("${mail.password}")
private String mailPassword;

@Value("${mail.protocol}")
private String mailProtocol;

@Value("${mail.smtp.auth}")
private boolean mailAuth;

@Value("${mail.smtp.starttls.enable}")
private String mailEnableTls;

@Value("${mail.smtp.debug}")
private boolean mailDebug;

@Bean
public JavaMailSender getMailSender() {
    JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

    mailSender.setHost(mailHost);
    mailSender.setPort(mailPort);
    mailSender.setUsername(mailUsername);
    mailSender.setPassword(mailPassword);

    Properties mailProperties = new Properties();
    mailProperties.put("mail.transport.protocol", mailProtocol);
    mailProperties.put("mail.smtp.auth", mailAuth);
    mailProperties.put("mail.smtp.starttls.enable", mailEnableTls);
    mailProperties.put("mail.smtp.debug", mailDebug);
    mailSender.setJavaMailProperties(mailProperties);

    return mailSender;
}

@Bean
public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
    PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
    propertyPlaceholderConfigurer.setLocation(new ClassPathResource("mail.properties"));
    propertyPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
    return propertyPlaceholderConfigurer;
}

}

Best Answer

Looks like your property source config in MailSenderConfiguration is overriding the one in AppConfig.

You can remove PropertyPlaceholderConfigurer bean from MailSenderConfiguration, and in AppConfig, set additional location for "mail.properties" (use setLocations() method instead of setLocation()):

@Import({DatabaseConfiguration.class, MailSenderConfiguration.class})
public class AppConfig {
@Bean
public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
    PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
    propertyPlaceholderConfigurer.setLocations(new ClassPathResource("application.properties"), new ClassPathResource("mail.properties"));
    propertyPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
    return propertyPlaceholderConfigurer;
}
Related Topic