How to post process Spring boot properties? - java

I have defined some external properties in my main class as follows:
#PropertySources({
#PropertySource(value = "classpath:application.properties", ignoreResourceNotFound = true),
#PropertySource(value = "file:/opt/app/conf/database.properties", ignoreResourceNotFound = true),
#PropertySource(value = "file:/opt/app/conf/overrides.properties", ignoreResourceNotFound = true)
})
For some of the properties I would like to do some post processing, for example encrypting or enrichment before they are actually used by any beans. One such property is spring.datasource.password
I have done the following:
Write an ApplicationContextInitializer<ConfigurableApplicationContext> and tried to process those properties in the initialize() method
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
String value = environment.getProperty("spring.datasource.password");
System.out.println("The value in initializer is " + value);
System.out.println("The database url in initializer is " + environment.getProperty("spring.datasource.url"));
System.out.println("The database username in initializer is " + environment.getProperty("spring.datasource.username"));
// .. other code
}
}
and included the above class in the META-INF/spring.factories as follows:
org.springframework.context.ApplicationContextInitializer=com.myapp.MyApplicationContextInitializer
I am seeing null values in all of the above properties that are printed though both database.properties and overrides.properties are present. They are the very first statements to be printed (even before the banner)
Another approach I tried is org.springframework.boot.env.EnvironmentPostProcessor and adding in META-INF/spring.factories as
org.springframework.boot.env.EnvironmentPostProcessor=com.myapp.PropertiesProcessor
But still, I get the same null value.
Interestingly, when I pass in the
-Dspring.config.location="file:/opt/app/conf/database.properties, file:/opt/app/conf/overrides.properties"
system property before executing the war, it works i.e. the values are printed.
But I do not want to manually pass in the system property at runtime. Is there a way to do it?
What is wrong with my code or approach. Are there any other ways of doing the post-processing before actually creating the beans?

I solved similar problem by adding property source with highest precedence.
Add META-INF/spring.factories with content:
org.springframework.boot.env.EnvironmentPostProcessor=
com.example.SettingsPropertiesAddingPostProcessor
SettingsPropertiesAddingPostProcessor implementation:
public class SettingsPropertiesAddingPostProcessor implements EnvironmentPostProcessor {
private static final String SETTINGS_CONFIG_PATH = "/tmp/settings.properties";
#Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
File settingsFile = new File(SETTINGS_CONFIG_PATH);
if (!settingsFile.exists()) {
log.debug("Config file not found, skipping adding custom property source");
return;
}
log.debug("Config file found, adding custom property source");
Properties props = loadProperties(settingsFile);
MutablePropertySources propertySources = environment.getPropertySources();
propertySources.addFirst(new PropertiesPropertySource("settings-source", props));
}
private Properties loadProperties(File f) {
FileSystemResource resource = new FileSystemResource(f);
try {
return PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException ex) {
throw new IllegalStateException("Failed to load local settings from " + f.getAbsolutePath(), ex);
}
}
}
That should be all.

Following the advice of #M. Deinum, regarding using "spring.config.additional-location", I have made a workaround as follows:
#SpringBootApplication
#EnableSwagger2
public class MyApp extends SpringBootServletInitializer {
public static void main(String[] args) {
System.setProperty("spring.config.additional-location", "file:/opt/app/conf/database.properties, file:/opt/app/conf/overrides.properties");
SpringApplication springApplication = new SpringApplication(MyApp.class);
springApplication.run(args);
}
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("Setting properties onStartup");
System.setProperty("spring.config.additional-location", "file:/opt/app/conf/database.properties, file:/opt/app/conf/overrides.properties");
super.onStartup(servletContext);
}
}
I have called the System.setProperty() in the onStartup() method of the SpringBootServletInitializer by overriding it as above and then invoked the super class' onStartup()
The latter part i.e. setting system property in onStartup method helps when the application is deployed in a web container like Tomcat.
Note: We can also append the properties to spring.config.additional-location instead of set so that other additional locations can also be added during runtime.

Related

unable to get value using #Value("${connection.local}")from properties file

i have properties like this
connection.local=0.0.0.0
i write it on application.properties and at application-local.properties it is correct or not ?
but when i want to get this value with annotation
i use plain java for build apps. and use spring context for get value and annotations
#Component
#Scope("singleton")
#Slf4j
#Configuration
public class SocketEngine extends Thread {
/**
* This is to make sure that the server is running and trying even when
* idxdatafeed disconnects
*/
#Value("${connection.local}")
private String connectionLocalhost;
public void run() {
while (true) {
Socket server = null;
String firstData="xvabv";
try {
log.info("Connecting to server " + connectionLocalhost+"!");
server = new Socket(connectionLocalhost, 9010);
server.setSoTimeout(10000);
PrintWriter writer= new PrintWriter(server.getOutputStream());
i got value of connectionLocal is null why like that ?
You may solve your problem by injecting the value in the constructor:
public SocketEngine(#Value("${connection.local}") String connectionLocalhost) {
this.connectionLocalhost = connectionLocalhost;
run();
}
This should resolve the problem. But really I don't why spring here acts like that (tested). Also you don't need the annotation #Compnent because #Configuration includes it.
The official approach is to define the following method in your configuration class:
#Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
But it didn't work, and that's why I'm confused!
I solved the problem , add like below code.
#PropertySource(value = "classpath:application.properties", ignoreResourceNotFound = true)

The injection point has the following annotations: - #org.springframework.beans.factory.annotation.Autowired(required=true)

I am new to Spring Boot and I'm getting the following error when writing a file upload API:
Error:Description:
Field fileStorageService in com.primesolutions.fileupload.controller.FileController required a bean of type 'com.primesolutions.fileupload.service.FileStorageService' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.primesolutions.fileupload.service.FileStorageService' in your configuration.*
Controller class:
public class FileController
{
private static final Logger logger = LoggerFactory.getLogger(FileController.class);
#Autowired
private FileStorageService fileStorageService;
#PostMapping("/uploadFile")
public UploadFileResponse uploadFile(#RequestParam("file") MultipartFile file) {
String fileName = fileStorageService.storeFile(file);
String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
.path("/downloadFile/")
.path(fileName)
.toUriString();
return new UploadFileResponse(fileName, fileDownloadUri,
file.getContentType(), file.getSize());
}
#PostMapping("/uploadMultipleFiles")
public List<UploadFileResponse> uploadMultipleFiles(#RequestParam("files") MultipartFile[] files) {
return Arrays.asList(files)
.stream()
.map(file -> uploadFile(file))
.collect(Collectors.toList());
}
}
Service class:
private final Path fileStorageLocation;
#Autowired
public FileStorageService(FileStorageProperties fileStorageProperties) {
this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
.toAbsolutePath().normalize();
try {
Files.createDirectories(this.fileStorageLocation);
} catch (Exception ex) {
throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
public String storeFile(MultipartFile file) {
// Normalize file name
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
try {
// Check if the file's name contains invalid characters
if(fileName.contains("..")) {
throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
}
// Copy file to the target location (Replacing existing file with the same name)
Path targetLocation = this.fileStorageLocation.resolve(fileName);
Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
return fileName;
} catch (IOException ex) {
throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
}
}
Configuration class:
#ConfigurationProperties(prefix = "file")
public class FileStorageProperties {
private String uploadDir;
public String getUploadDir()
{
return uploadDir;
}
public void setUploadDir(String uploadDir) {
this.uploadDir = uploadDir;
}
}
Main:
#SpringBootApplication
#EnableConfigurationProperties({
FileStorageProperties.class
})
public class FileApplication {
public static void main(String[] args) {
SpringApplication.run(FileApplication.class, args);
}
}
properties file
## MULTIPART (MultipartProperties)
# Enable multipart uploads
spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# Max file size.
spring.servlet.multipart.max-file-size=200MB
# Max Request Size
spring.servlet.multipart.max-request-size=215MB
## File Storage Properties
# All files uploaded through the REST API will be stored in this directory
file.upload-dir=C:/Projects/SpringBootProject/Primesolutions/PrimeSolutions/FileUpload
I'm trying to read the file upload property and pass it to the controller class.
The error seems to indicate that Spring does not know any bean of type com.primesolutions.fileupload.service.FileStorageService.
As said in the comment, make sure you class FileStorageServiceis annotated by #Service or #Component:
#Service
public class FileStorageService {
...
}
Make also sure that this class is located in a sub-package of your class FileApplication. For example, if your FileApplication class is located in a package com.my.package, make sure your FileStorageService is located in the package com.my.package.** (same package or any sub package).
Few notes to improve your code by the way :
When your class has only one not default constructor, the use of #Autowired on the constructor is optional.
Do not put too much code in your constructor. Use instead the #PostConstruct annotation.
#Service
public class FileStorageService {
private FileStorageProperties props;
// #Autowired is optional in this case
public FileStorageService (FileStorageProperties fileStorageProperties) {
this.props = fileStorageProperties;
this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
.toAbsolutePath().normalize();
}
#PostConstruct
public void init() {
try {
Files.createDirectories(this.fileStorageLocation);
} catch (Exception ex) {
throw new FileStorageException("Could not create the directory where the uploaded files will be stored.", ex);
}
}
}
It is better to avoid the #Autowired on a field. Use the constructor instead. It is better for your tests, and more maintainable:
public class FileController {
private FileStorageService service;
public FileController(FileStorageService service) {
this.service = service;
}
}
I solved this problem using where i use #Autowired annotation just replace with this`
#Autowired(required = false)
`
When #Autowired doesn’t work
There are several reasons #Autowired might not work.
When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection. Also when you use #Autowired in the class of which you created a new instance, the Spring context will not be known to it and thus most likely this will also fail.
Another reason can be that the class you want to use #Autowired in, is not picked up by the ComponentScan. This can basically be because of two reasons.
The package is outside the ComponentScan search path. Move the
package to a scanned location or configure the ComponentScan to
fix this.
The class in which you want to use #Autowired does not have a
Spring annotation. Add one of the following annotatons to the class:
#Component, #Repository, #Service, #Controller,
#Configuration. They have different behaviors so choose carefully!
Read more here.
I solved this problem using :
#ComponentScan({ "com.yourpkg.*" })
Make sure you #ComponentScan cover all classes contains annotatons : #Component, #Repository, #Service, #Controller, #Configuration.
Reference : https://technology.amis.nl/2018/02/22/java-how-to-fix-spring-autowired-annotation-not-working-issues/
Tried with removing the (exclude = {DataSourceAutoConfiguration.class }) parameter with #SpringBootApplication:
Before:
#SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class SpringBootMain { ...
After:
#SpringBootApplication
public class SpringBootMain { ...
Worked for me.
The class which is going to be Autowired should be marked with #Service or #Component. Also if the class is in different package then need to add the #ComponentScan annotation in the main class as follows.
#ComponentScan({"com.beta.replyservice", "com.beta.ruleService"})
#SpringBootApplication
Solution is
#Autowired(required = false)
private FileStorageService fileStorageService;
I had the same issue. It was solved for me when I added a dependency on "spring-webmvc".
When I had the same problem, I just added a default constructor in my service class and it started working.
=> Error should look like this:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field accountPresentation in june14th.account.TestSpringBoot required a bean of type 'june14th.controller.AccountPresentation' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'june14th.controller.AccountPresentation' in your configuration.
Solution to the problem:-
First and most important step is look whether your code has the needed dependencies.
Check your Folder structure (this error is mainly due to this problem, always check your package structure) i.e, check wheather the main package and its sub packages are well structured
eg:
package X.account; //consider this is my main file package
package X.controller; //consider this as my presentation file package
when you run this program this will cause our "APPLICATION FAILED TO START" error, because of our package structure..look
package X.account; //main file package [the next fie should inside this package i.e as a sub package]
package.X.account.controller // this is the right way
I think this should solve your problem.
Put #Autowired(required=true) //do only if above will not work
Make sure to have respective annotations for classes. The same issue got solved for me when I add #Service annotation for interfaces and implemented service classes.
I use #Service on the service class which has to be Autowired. It solves my error. or you can use #Autowired(required = false) to disable the auto wiring for a particular instance.

Load spring-boot properties from json file

Is it possible to load spring-boot config from a .json file as opposed to .yaml or .properties? From looking at the documentation, this isn't supported out of the box - I'm wondering if it's possible and if so how one would go about doing it?
As noted in docs and on GitHub
YAML is a superset of JSON
So you can just create the following class in your Spring Boot project:
public class JsonPropertySourceLoader extends YamlPropertySourceLoader {
#Override
public String[] getFileExtensions() {
return new String[]{"json"};
}
}
Then create a file:
/src/main/resources/META-INF/spring.factories
with the following content:
org.springframework.boot.env.PropertySourceLoader=\
io.myapp.JsonPropertySourceLoader
And your Spring application is ready to load JSON configurations from application.json. The priority will be: .properties -> .yaml -> .json
If you have multiple apps, you can create a jar with the shared PropertySourceLoader and spring.factories file in order to include it to any project you need.
The spring boot way:
#EnableAutoConfiguration
#Configuration
#PropertySource(value = { "classpath:/properties/config.default.json" }, factory=SpringBootTest.JsonLoader.class )
public class SpringBootTest extends SpringBootServletInitializer {
#Bean
public Object test(Environment e) {
System.out.println(e.getProperty("test"));
return new Object();
}
public static void main(String[] args) {
SpringApplication.run(SpringBootTest.class);
}
public static class JsonLoader implements PropertySourceFactory {
#Override
public org.springframework.core.env.PropertySource<?> createPropertySource(String name,
EncodedResource resource) throws IOException {
Map readValue = new ObjectMapper().readValue(resource.getInputStream(), Map.class);
return new MapPropertySource("json-source", readValue);
}
}
}
Define your own PropertySourceFactory and hook it in via the #PropertySource annotation. Read the resource, set the properties, use them anywhere.
Only thing is, how do you translate nested properties. The Spring way to do that (by the way you can define Json also as a variable for properties, see: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html)
is to translate nested properties as such:
{"test": { "test2" : "x" } }
Becomes:
test.test2.x
Hope that helps,
Artur
The SPRING_APPLICATION_JSON properties can be supplied on the command line with an environment variable. For example, you could use the following line in a UN*X shell:
$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar
myapp.jar
In the preceding example, you end up with acme.name=test in the Spring Environment. You can also supply the JSON as spring.application.json in a System property, as shown in the following example:
$ java -Dspring.application.json='{"name":"test"}' -jar myapp.jar
You can also supply the JSON by using a command line argument, as shown in the following example:
$ java -jar myapp.jar --spring.application.json='{"name":"test"}'
You can also supply the JSON as a JNDI variable, as follows:
java:comp/env/spring.application.json.
Reference documentation: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
2 steps
public String asYaml(String jsonString) throws JsonProcessingException, IOException {
// parse JSON
JsonNode jsonNodeTree = new ObjectMapper().readTree(jsonString);
// save it as YAML
String jsonAsYaml = new YAMLMapper().writeValueAsString(jsonNodeTree);
return jsonAsYaml;
}
Got from the post
and
public class YamlFileApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
try {
Resource resource = applicationContext.getResource("classpath:file.yml");
YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
PropertySource<?> yamlTestProperties = yamlTestProperties = sourceLoader.load("yamlTestProperties", resource, null);
applicationContext.getEnvironment().getPropertySources().addFirst(yamlTestProperties);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Got from the post
So you can combine both. Load your json as resource and convert to yaml and then add to Environment all the found properties

Spring JUnit ApplicationContextInitializer parameters

We have implemented an extended .properties format. Such a properties file can contain an optional include property. The value of this properties is the classpaths of other properties files to load recursively.
I could configure the Spring environment for my application but I have a problem to engage this mechanism with SpringJUnit4ClassRunner.
I thought I could use the initializer property of the ContextConfiguration annotation but it looks it can only be instantiated with a no-arg constructor.
I need to give it the root file of my properties files hierarchy. It could eventually be another annotation on my test class, but again, how can I access it ?
The only think I have found so far is to set this file as a system property in my test class static initializer. ugly?:
#ActiveProfiles("qacs.controller.channels=mock")
#ContextConfiguration(initializer=ContainerTestContextInitializer.class)
public class QacsControllerTest
{
static
{
System.setProperty(ContainerTestContextInitializer.SYSTEM_PROPERTY, "classpath:com/xxx/qacs/QacsControllerTest.properties");
}
#Test
void test() {}
}
}
public class ContainerTestContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{
public static final String SYSTEM_PROPERTY = "icomp.test.properties";
#Override
public void initialize(ConfigurableApplicationContext pApplicationContext)
{
String path = System.getProperty(SYSTEM_PROPERTY);
if (path == null)
{
throw new IllegalStateException("Missing system property " + SYSTEM_PROPERTY);
}
final DefaultPropertiesLoader loader;
loader = new DefaultPropertiesLoader(System.getProperties());
try
{
loader.load(path);
}
catch (IOException e)
{
throw new IllegalStateException(e.getMessage(), e);
}
MutablePropertySources sources = pApplicationContext.getEnvironment().getPropertySources();
MapPropertySource mps = new MapPropertySource(Launcher.ICOMP_PROPERTY_SOURCE, (Map) loader.getProperties());
sources.addFirst(mps);
}
}

How do I configure Spring to partially and optionally override properties?

I would like to have a properties setup which can, on certain environments, override specific properties. For example, our default JDBC properties for dev are:
db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/ourdb
db.username=root
db.password=
The problem is that some of our devs would like to have a different username/password on the db, or possibly even a non locally hosted db. The same is true for our rabbitMQ configuration, which currently uses a similar localhost, guest/guest setup. Being able to override the properties of certain elements of this configuration on a per-developer basis would allow us to move much of the infrastructure/installation requirements for building the software off the local machine and onto dedicated servers.
I have set-up a simple project to wrap my head around the configuration required to achieve what I want, and this is my first foray into the world of spring property configuration, since up till now, property loading and management is done with some custom code. Here is my setup:
class Main_PropertyTest {
public static void main(String[] args) {
String environment = System.getenv("APPLICATION_ENVIRONMENT"); // Environment, for example: "dev"
String subEnvironment = System.getenv("APPLICATION_SUB_ENVIRONMENT"); // Developer name, for example: "joe.bloggs"
System.setProperty("spring.profiles.active", environment);
System.setProperty("spring.profiles.sub", subEnvironment);
try(AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(PropertyTestConfiguration.class)) {
Main_PropertyTest main = context.getBean(Main_PropertyTest.class);
main.printProperty();
}
}
private final String property;
public Main_PropertyTest(String property) {
this.property = property;
}
public void printProperty() {
System.out.println("And the property is: '" + property + "'.");
}
}
And my configuration:
#Configuration
public class PropertyTestConfiguration {
#Bean
public static PropertySourcesPlaceholderConfigurer primaryPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setLocation(new ClassPathResource(System.getProperty("spring.profiles.active") + ".main.properties"));
return propertySourcesPlaceholderConfigurer;
}
#Bean
public static PropertySourcesPlaceholderConfigurer secondaryPlaceholderConfigurer() {
PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
propertySourcesPlaceholderConfigurer.setLocation(new ClassPathResource(System.getProperty("spring.profiles.sub") + ".main.properties"));
propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound(true);
propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound(true);
propertySourcesPlaceholderConfigurer.setOrder(-1);
return propertySourcesPlaceholderConfigurer;
}
#Bean
public Main_PropertyTest main_PropertyTest(#Value("${main.property}") String property) {
Main_PropertyTest main_PropertyTest = new Main_PropertyTest(property);
return main_PropertyTest;
}
}
And for completeness, my dev.main.properties and test.main.properties:
main.property=dev
main.property=test
The main problem is that I get an illegal argument exception. As far as I can tell, what I have written should be the javaconfig equivalent of this method: http://taidevcouk.wordpress.com/2013/07/04/overriding-a-packaged-spring-application-properties-file-via-an-external-file/
Unfortunately I get the following error: java.lang.IllegalArgumentException: Could not resolve placeholder 'main.property' in string value "${main.property}". Note that I also need to take care of the case where there is no sub-environment, and this is the case I have started with (although I get the same error even if both files exist). If I remove the bean which sets up the second propertysourcesplaceholderconfigurer, then it all works fine (by which I mean dev.main.properties is loaded and "And the property is: 'dev'." is printed out).
A secondary problem is that the code doesn't look great, and each layer of the system will need two PSPC's set-up so that they can access these properties. Furthermore, it requires a lot of manual calls to System.getProperty(), since I couldn't pass ${spring.profiles.active} to PSPC.setLocation();
Note: I have tried #PropertySources({primaryproperties, secondaryProperties}), but this fails because secondaryProperties does not exist. I have also tried #Autowired Environment environment; and getting the properties from that, but the secondary PSPC causes the environment to not be autowired...
So following this lengthy explanation, my questions are:
Is this the right way of solving this problem?
If so, what is wrong with my configuration?
How can I simplify the configuration (if at all)?
Is there an alternative mechanism available which would solve my problem?
Thank you for your time! :)
Your configuration is flawed when configuring BeanFactoryPostProcessor with java config the methods should be static. However it can be even easier, instead of registering your own PropertySourcesPlaceholderConfigurer utilize the default #PropertySource support.
Rewerite your jav config to the following
#Configuration
#PropertySource(name="main", value= "${spring.profiles.active}.main.properties")
public class PropertyTestConfiguration {
#Autowired
private Environment env;
#PostConstruct
public void initialize() {
String resource = env.getProperty("spring.profiles.sub") +".main.properties";
Resource props = new ClassPathResource(resource);
if (env instanceof ConfigurableEnvironment && props.exists()) {
MutablePropertySources sources = ((ConfigurableEnvironment) env).getPropertySources();
sources.addBefore("main", new ResourcePropertySource(props));
}
}
#Bean
public Main_PropertyTest main_PropertyTest(#Value("${main.property}") String property) {
Main_PropertyTest main_PropertyTest = new Main_PropertyTest(property);
return main_PropertyTest;
}
}
This should first load the dev.main.properties and additionally the test.main.properties which will override the earlier loaded properties (when filled ofcourse).
I had a similar issue with overwriting already existing properties in integration tests
I came up with this solution:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classes = {
SomeProdConfig.class,
MyWebTest.TestConfig.class
})
#WebIntegrationTest
public class MyWebTest {
#Configuration
public static class TestConfig {
#Inject
private Environment env;
#PostConstruct
public void overwriteProperties() throws Exception {
final Map<String,Object> systemProperties = ((ConfigurableEnvironment) env)
.getSystemProperties();
systemProperties.put("some.prop", "test.value");
}
}

Categories

Resources