10

I am facing strange issue with spring property mapper. I have yml contains list of values. I want convert that to list of object why building application. So, i used @ConfigurationProperties. With this i am able to map simple types. when i use this to complex type(list of objects) it failed. No exception, but values list is zero when i debug. please find below yml and java files. I tried with spring 2.0.0,2.0.1,2.0.2,2.0.3 No success. Can any one have idea to fix it?

application.yml

acme:
  list:
    - name: my name
      description: my description
    - name: another name
      description: another description

AcmeProperties.java

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
@ConfigurationProperties("acme")
@PropertySource("classpath:configuration/yml/application.yml")
public class AcmeProperties {

    private final List<MyPojo> list = new ArrayList<>();

    public List<MyPojo> getList() {
        return this.list;
    }

    static class MyPojo {
        private String name;
        private String description;

        public String getName() {
            return name;
        }

        public String getDescription() {
            return description;
        }
    }
}

With setter and getter methods:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@ConfigurationProperties(prefix = "acme")
@PropertySource("classpath:configuration/yml/application.yml")
public class AcmeProperties {

    private List<MyPojo> list;

    public List<MyPojo> getList() {
        return list;
    }

    public void setList(List<MyPojo> list) {
        this.list = list;
    }

    public static class MyPojo {
        private String name;
        private String description;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }
    }
}

Usage of this class:

@Autowired
public HomeController(AppProperties appProperties, AcmeProperties acmeProperties) {
    this.appProperties = appProperties;
    this.acmeProperties = acmeProperties;
}
7
  • 1
    could try public static class MyPojo, and put set methods on it. And same with list: make that non final, don't inialise it, and have a setter for it Commented Jul 17, 2018 at 10:16
  • 1
    @MrSpoon, No success Commented Jul 17, 2018 at 10:24
  • I tried your code with setter and getter at a spring boot application and it worked... so i doupt it is in these classes the problem. You do not create and AcmeProperties bean manually or via new, right? spring boot version? one extra info. i ommited @PropertySource("classpath:configuration/yml/application.yml") i have put it in my application.yml in resources folder. Can you try that for debuging reasons? just in case.. Commented Jul 17, 2018 at 10:32
  • 1
    @Alexandros, I am not creating AcmeProperties bean manually. I autowired that in my controller. I updated my question with usage please check. Commented Jul 17, 2018 at 10:36
  • 1
    @Alexandros, I am using spring-boot 2.0.3. Can you post your changes in answer. or update question with your changes? Commented Jul 17, 2018 at 10:39

4 Answers 4

15

The problem is PropertySource only support the properties file, you cannot read the value from yml file. you can update it like:

@Component
@ConfigurationProperties("acme")
@PropertySource("classpath:/configuration/yml/test.properties")
class AcmeProperties {

configuration/yml/test.properties

acme.list[0].name=my name
acme.list[0].description=my description
acme.list[1].name=another name
acme.list[1].description=another description

and the code should work.

Sign up to request clarification or add additional context in comments.

Comments

2

According to the Spring Boot documentation (emphasis is mine) :

24.6.4 YAML Shortcomings

YAML files cannot be loaded by using the @PropertySource annotation. So, in the case that you need to load values that way, you need to use a properties file.

But you provided a yml file to @PropertySource :

@Component
@ConfigurationProperties(prefix = "acme")
@PropertySource("classpath:configuration/yml/application.yml")
public class AcmeProperties { ...}  

So you have two possibilities :

  • this yml file is a Spring Boot profile properties file : enable this profile before executing the application and so remove @PropertySource
  • this yml file is not a Spring Boot profile properties file : use a properties file instead of a yml file.

Comments

0

Try with @ConfigurationProperties(prefix = "acme")

Based on: https://aykutakin.wordpress.com/2016/02/26/injecting-list-with-spring-from-yaml/

5 Comments

It is the same thing. The value() of the enum is an alias for prefix
@James, No success
Oh ok, so maybe formatting in .yml is wrong. This little boy is sensitive for this things
No formatting is good, when i give simple type it is accepting.
I followed this link
0

I think problem is that resource is not found as specified at @PropertySource("classpath:configuration/yml/application.yml"). -made the same mistake when tried to debug your code..- Could you please put a break point in org.springframework.context.annotation.ConfigurationClassParser#processPropertySource with watch check path returned from this.resourceLoader.getResource(resolvedLocation).getFile().

In my case i have: C:\Users\user12\Desktop\hibernate\out\production\classes\configuration\application.yml

there there is not application.yml...

I think you do not see exception because spring has if (ignoreResourceNotFound) {..} else {throw ex} in this method

2 Comments

If resource not found spring application wont run. In my local i am able run application and fetch simple types from the yml file
@Component @ConfigurationProperties("acme") public class AcmeProperties { ... } and add one application.yml under resources folder.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.