2

I'm trying to do exactly what @Laplie Anderson suggested here Spring Environment backed by Typesafe Config but in a spring-boot application.

I want to load different config files for different spring active profiles. Here's an example.

@Configuration()
@Import(value = {CommonConfiguration.class})
@PropertySource(factory=TypesafePropertySourceFactory.class, value="config/dev/app.conf")
@Profile("dev")
public class DevConfig {}

@Configuration()
@Import(value = {CommonConfiguration.class})
@PropertySource(factory=TypesafePropertySourceFactory.class, value="config/prod/app.conf")
@Profile("prod")
public class ProdConfig {}

But this results in the following error on app startup..

java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration.buildProperties
    at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:64) ~[spring-boot-autoconfigure-1.5.6.RELEASE.jar!/:1.5.6.RELEASE]
    at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:102) ~[spring-context-4.3.10.RELEASE.jar!/:4.3.10.RELEASE]
    ...
Caused by: com.typesafe.config.ConfigException$BadPath: path parameter: Invalid path 'spring.info.build.location:classpath:META-INF/build-info.properties': Token not allowed in path expression: ':' (you can double-quote this token if you really want it here)
    at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:155) ~[config-1.3.1.jar!/:na]
    at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:74) ~[config-1.3.1.jar!/:na]
    ...

What am I missing?
Is there a better way to accomplish this?

The following versions are at play here..
spring-boot: 1.5.6.RELEASE
typesafe config: 1.3.1

Gagan
  • 135
  • 1
  • 1
  • 11

3 Answers3

0

Maybe you can also solve it with the use of a ContextInitializer as I suggested in the answer here: https://stackoverflow.com/a/58789778/142671

Fabian
  • 2,428
  • 2
  • 21
  • 19
0

For me it works by ignoring the typesafe config unsupported characters.

public class TypesafeConfigPropertySource extends PropertySource<Config> {

  public TypesafeConfigPropertySource(String name, Config source) {
    super(name, source);
  }

  @Override
  public Object getProperty(String name) {
    if (name.contains("["))
      return null;
    if (name.contains(":"))
      return null;
    if (source.hasPath(name)) {
      return source.getAnyRef(name);
    }
    return null;
  }
}

Notes:

  • It works like a charm with both Environment.getProperty(property) and @Value;
  • I would expect the type-safe configuration properties to work as well. Didn't try yet.
jtonic
  • 609
  • 1
  • 7
  • 10
-1

just noticed that spring-boot supports .yml files that have almost all features that I need, esp 'Placeholders in properties'. I'll try to use this instead - https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-yaml

I'd still like to know the answer to the original question. Is it just because ':' is unacceptable in a typesafe-config value? Is there no workaround?

Gagan
  • 135
  • 1
  • 1
  • 11