0

I have a Spring boot application that requires the use of properties in files different from the standard application.properties. I wanted to map my properties files to a specific properties class and be able to use the properties class inside of a Configuration class. The code is the following:

@Configuration @EnableConfigurationProperties(AWSProperties.class) @PropertySource("kaizen-batch-common-aws.properties") public class ResourceConfigAWS { @Autowired private AWSProperties awsProperties; @Autowired private ResourceLoader resourceLoader; private static final Logger logger = LoggerFactory.getLogger(ResourceConfigAWS.class); @Bean public AmazonS3 amazonS3Client() { logger.debug("AWS Config: " + this.awsProperties); BasicAWSCredentials awsCreds = new BasicAWSCredentials("access_key_id", "secret_key_id"); AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(awsCreds)) .withRegion(awsProperties.getRegion()) .build(); return s3Client; } @Bean public SimpleStorageResourceLoader resourceLoader() { return new SimpleStorageResourceLoader(this.amazonS3Client()); } @Bean @StepScope public Resource getResourceToProcess(@Value("#{jobParameters[T(com.kaizen.batch.common.JobRunnerTemplate).INPUT_FILE_PARAM_NAME]}") String inputFile) { return this.resourceLoader.getResource(this.awsProperties.getInputLocation() + inputFile); } @PostConstruct public void postConstruct() { System.out.print("Properties values: " + this.awsProperties); } @Bean public AbstractFileValidator inputFileValidator() { InputS3Validator inputS3Validator = new InputS3Validator(); inputS3Validator.setRequiredKeys(new String[]{InputFileSystemValidator.INPUT_FILE}); return inputS3Validator; } @Bean public InputFileFinalizerDelegate inputFileFinalizerDelegate() { InputFileFinalizerDelegate inputFileFinalizerDelegate = new AWSInputFileFinalizerDelegate(); return inputFileFinalizerDelegate; } @Bean public InputFileInitializerDelegate inputFileInitializerDelegate() { InputFileInitializerDelegate inputFileInitializerDelegate = new AWSInputFileInitializerDelegate(); return inputFileInitializerDelegate; } } @ConfigurationProperties("aws") @Data public class AWSProperties { private static final String SEPARATOR = "/"; private static final String S3_PREFFIX = "s3://"; @Value("${s3.bucket.batch}") private String bucket; @Value("${s3.bucket.batch.batch-job-folder}") private String rootFolder; @Value("${s3.bucket.batch.input}") private String inputFolder; @Value("${s3.bucket.batch.processed}") private String processedFolder; @Value("${region}") private String region; public String getInputLocation() { return this.getBasePath() + this.inputFolder + SEPARATOR; } public String getProcessedLocation() { return this.getBasePath() + this.processedFolder + SEPARATOR; } private String getBasePath() { return S3_PREFFIX + this.bucket + SEPARATOR + this.rootFolder + SEPARATOR; } } 

I am struggling to manage to Get AWSProperties to get populated with the values defined in the properties files, somehow I always end up with awsProperties with a null value. Any insight on how to map properties in Spring Boot into a Properties class without using the standard property files naming conventions in Spring Boot will be very appreciated.

Here is the properties file:

aws.s3.bucket.batch=com-kaizen-batch-dev aws.s3.bucket.batch.input=input aws.s3.bucket.batch.processed=processed aws.s3.bucket.batch.batch-job-folder=merchant-file aws.region=us-east-2 

Note: I modified the Configuration class slightly and now I am getting the following exception:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.kaizen.batch.common.ResourceConfigAWS': Unsatisfied dependency expressed through field 'awsProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aws-com.kaizen.batch.common.AWSProperties': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 's3.bucket.batch' in value "${s3.bucket.batch}" at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) ~[spring-beans-4.3.7.RELEASE.jar:4.3.7.RELEASE] 
2
  • You have annotated AWSProperties class with @ConfigurationProperties("aws") and the same time all configurable fields are annotated with @Value. Can you clarify which fields you are trying to configure using @ConfigurationProperties? Also include properties (key-value pairs) that you are going to bind with AWSProperties class. Commented Mar 21, 2018 at 3:41
  • Thank sanit, I added the properties file, I also modified the code and now I am getting a specific exception indicating that it cannot bind specific properties in the AWSProperties Commented Mar 22, 2018 at 14:28

2 Answers 2

1

@ConfigurationProperties are used for binding property file keys with POJO classes. You have to do following changes for your code to work.

kaizen-batch-common-aws.properties

aws.s3.bucket.batch.bucket=com-kaizen-batch-dev aws.s3.bucket.batch.root-folder=processed aws.s3.bucket.batch.input-folder=input aws.s3.bucket.batch.processed-folder=processed aws.s3.bucket.batch.batch-job-folder=merchant-file @Component @ConfigurationProperties(prefix = "aws.s3.bucket.batch") public class AWSProperties { private String bucket; private String rootFolder; private String inputFolder; private String processedFolder; private String region; // setter require } 

Please visit doc here

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

1 Comment

Thanks a lot sanit! That fixed my issue!
0

Add the property file in classpath or keep it in resource folder and update the @PropertySource in this way:

@PropertySource("classpath:kaizen-batch-common-aws.properties") 

1 Comment

Thanks, I tried it but unfortunately it doesn't work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.