config
config copied to clipboard
Substitutions are broken when using Config.resolveWith in a merged node that is a direct decendant of the root node
Trivial reproduction:
val fallback = parseConfig("a: 123")
val conf = parseConfig("b: 234, a: ${b}")
val merged = conf
.withFallback(fallback)
.resolveWith(
ConfigFactory.empty(),
ConfigResolveOptions.defaults().setAllowUnresolved(true)
).resolve()
This is somewhat similar to various other issues in the issue tracker.
There is a trivial fix, namely to return this on line 245 of ResolveSource.java. That code even exists but is commented out in favor of throwing an exception. I have not been able to find any case that currently works that is broken by this code change.
I have a patch in the works (with a bunch of tests) to fix this in the above mentioned trivial fashion, but I am currently awaiting response on if I can sign the CLA from employer.
Is this the same as https://github.com/lightbend/config/issues/332 ? If so there's some discussion on that issue from the last time I looked into it, with the punchline suggesting the same PR you came up with, but maybe you can read what it says on that issue and double-check that it matches your understanding.
It's not the exact same, e.g. allowUnresolved is set to true in my example, and you use optional substitutions, I use mandatory ones. But yeah, these issues are clearly related.
Didn't see it when looking for older issues. My bad.
A few comments on your comment, though. The ResolveContext that throws the error didn't fail to maintain it's root path, it does not need a path as it is the root. It gets created in ResolveContext.java:227. That constructor will create the object with the path set to null, because we are at the root, so there is no path. Null in a linked list means an empty list.
If you put the node inside another node, everything works.
E.g. {a:{b: ${c}}} does work as expected.