The behavior of OWNER is that imported properties have lowest priority over the one associated to the Config
object or the ones specified by the @Sources
annotation.
I thought that this was the best behavior, but actually I felt that there was no reasonable reason to why I decided it (I also wrote a junit test to fix this behavior as "correct").
Now reading an email I just received, I feel like the use case specified by Ivan makes sense, and it is also not an uncommon thing to do. See email below.
So I wrote a test to reproduce the bug and to redefine the correct behavior and keep it safe from regressions, see 3178f1a:
/*
src/test/resources/org/aeonbits/owner/ImportConfigTest$ImportedPropertiesHaveHigherPriority.properties
minAge=18
*/
interface ImportedPropertiesHaveHigherPriority extends Config {
Integer minAge();
}
@Test
public void testImportedPropertiesShouldOverrideSources() {
ImportedPropertiesHaveHigherPriority cfg = ConfigFactory.create(ImportedPropertiesHaveHigherPriority.class);
assertEquals(Integer.valueOf(18), cfg.minAge());
ImportedPropertiesHaveHigherPriority cfg2 = ConfigFactory.create(ImportedPropertiesHaveHigherPriority.class,
new Properties() {{
setProperty("minAge", "21");
}},
new Properties() {{
setProperty("minAge", "22");
}}
);
assertEquals(Integer.valueOf(21), cfg2.minAge());
}
I already rolled out version 1.0.3.1 as a bugfix release, and I am waiting for a feedback from Ivan before to promote the version to the maven central repository.
Received a mail from Ivan G.
Hi Luigi,
Basically, I have an executable JAR containing a PROPERTIES file inside some resources folder. This is handled by Maven, so after the build is complete, BenchmarkConfig.properties will be in the same folder as BenchmarkConfig.java. The structure is somewhat as follows:
src/
main/
java/
SomeDriver.java
BenchmarkConfig.java
resources/
BenchmarkConfig.properties
I intend to run the JAR file as follows:
Usage:
java -jar some.jar <properties-path>
Example:
java -jar some.jar --
Uses the default properties file bundled inside the JAR.
java -jar some.jar SomeOtherConfig.properties
Uses the specified properties file to completely override
the default one.
However, when I try to run my JAR with the second method, there seems to be no option to completely override the default properties file when I do the following call:
1 try {
2 Properties props = new Properties();
3 props.load(new FileInputStream("path/to/SomeOtherConfig.properties");
4
5 /* Can't do this, because it will find the key-value pair from the default
6 * properties file (BenchmarkConfig.properties) first, and not even bother
7 * searching from SomeOtherConfig.properties
8 */
9 BenchmarkConfig cfg = ConfigFactory.create(BenchmarkConfig.class, props);
10
11 } catch (IOException e) {}
When I do the above, even when I specified a different properties file (someOtherPropertiesPath) and passed it in through props on line 6, it will still find the key-value pair from the default properties file.
I don't want this behavior. Instead, what I want is, when I pass in the props argument on the create() call, I want to completely override the entire default properties file with the file I've specified.
Is there a way to do this in your framework? I've only seen the @LoadPolicy(FIRST)
and @LoadPolicy(MERGE)
, but I don't think those two seem fit for my purpose.