Error Creating Bean Error (Spring Cloud Config Client)



I am trying to learn Spring Cloud Config. So first I setup a Server, where I can fetch the properties using http://localhost:9090/config/default/master/app.static.properties on the browser. It has about 5 or 6 properties. I am trying to get just one for now.

I wrote my classes like:

package com.gcp.logicalprovisioning.config.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class DemoClientApplication {

    private static final Logger LOGGER = LoggerFactory.getLogger(DemoClientApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DemoClientApplication.class, args);
    }


    /**
     * Output property from cloud-config-server on startup of app,
     *
     * also can be seen at:
     * http://localhost:9090/env/APP.aaf.env
     */
    @Bean
    public CommandLineRunner printProperties(@Value("${APP.aaf.env}") final String appProperty)  {
        return args -> LOGGER.info("APP.aaf.env is: [{}]", appProperty);
    }
}

and

package com.gcp.logicalprovisioning.config.server;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
// This will allow us to reinitialize this controller to get any new config
// values when the /refresh endpoint is POSTed to.
@RefreshScope

public class DemoClientController {

    @Value("${APP.aaf.env}")
    private String appProperty;

    @RequestMapping("/")
    public String hello() {
        return "Using [" + appProperty + "] from config server";
    }
}

My bootstrap.properties look like:

spring.application.name=client
spring.cloud.config.label=master
spring.cloud.config.uri=http://localhost:9090/config/default/master/
spring.cloud.config.enabled=true
spring.security.user.name=admin
spring.security.user.password=admin
logging.level.web=DEBUG
debug=false
spring.output.ansi.enabled=ALWAYS
spring.devtools.restart.enabled=true
spring.config.import=optional:configserver:http://localhost:9090/
spring.cloud.config.import-check.enabled=false

But I get this error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'printProperties' defined in com.gcp.logicalprovisioning.config.server.DemoClientApplication: Unexpected exception during bean creation; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'APP.aaf.env' in value "${APP.aaf.env}"
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:537) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.9.jar:5.3.9]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) [spring-boot-2.5.3.jar:2.5.3]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) [spring-boot-2.5.3.jar:2.5.3]
    at com.att.logicalprovisioning.config.server.DemoClientApplication.main(DemoClientApplication.java:20) [classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_281]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_281]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_281]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_281]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.5.3.jar:2.5.3]
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'APP.aaf.env' in value "${APP.aaf.env}"
    at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210) ~[spring-core-5.3.9.jar:5.3.9]
    at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175) ~[spring-context-5.3.9.jar:5.3.9]

I searched for the problem on StackOverflow, found a few solutions, tried it. But nothing worked. But since I am getting my feet wet, I am not exactly sure what is going wrong. Am I missing some extra configuration? Any help would be appreciated.

I haven’t posted my server’s code, if needed let me know, I will add it.

Answer

With help for Gregor, I was able to solve it. These are the changes I did:

I added a messageConverter:

package com.gcp.logicalprovisioning.config.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class DemoClientApplication {

    private static final Logger LOGGER = LoggerFactory.getLogger(DemoClientApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(DemoClientApplication.class, args);
    }


    /**
     * Output property from cloud-config-server on startup of app,
     *
     * also can be seen at:
     * http://localhost:9090/env/APP.aaf.env
     */
    @Bean
    public CommandLineRunner printProperties(@Value("${APP.aaf.env}") final String appProperty)  {
        return args -> LOGGER.info("APP.aaf.env is: [{}]", appProperty);
    }
    
    @Bean
    public RestTemplate restTemplate() {

        final RestTemplate restTemplate = new RestTemplate();

        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();

        mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));

        messageConverters.add(mappingJackson2HttpMessageConverter);

        restTemplate.setMessageConverters(messageConverters);

        return restTemplate;
    }
}

And in the bootstrap.properties, added a few extra configs here too:

debug=false
logging.level.web=DEBUG
server.port=1010
spring.application.name=app.static
spring.cloud.config.uri=http://localhost:9090/
spring.cloud.config.username=admin
spring.cloud.config.password=admin
spring.cloud.config.enabled=true
spring.cloud.config.import-check.enabled=false
spring.devtools.restart.enabled=true
spring.output.ansi.enabled=ALWAYS
spring.security.user.name=admin
spring.security.user.password=admin

Now I can fetch the configs from the config server by using the URL http://localhost:9090/app.static/default

So in short:

  1. I had to add messageConverter.
  2. Change the git.config.uri.
  3. And add username/password to the bootstrap.properties because the config server is tied with a username/password.
  4. Remove the spring.config.import properties.


Source: stackoverflow