Java @PropertySource(factory=…)在加载META-INF/build-info.properties时中断@SpringBootTest

Java @PropertySource(factory=…)在加载META-INF/build-info.properties时中断@SpringBootTest,java,spring-boot,Java,Spring Boot,我正在尝试设置从HOCON语法.conf文件加载的自定义@ConfigurationProperties类 我有一个用@PropertySource(factory=TypesafePropertySourceFactory.Class,value=“classpath:app.conf”)注释的类。 和一个简单的测试类: @SpringBootTest @TestInstance(TestInstance.Lifecycle.PER_CLASS) class SomeTest { @T

我正在尝试设置从HOCON语法
.conf
文件加载的自定义
@ConfigurationProperties

我有一个用
@PropertySource(factory=TypesafePropertySourceFactory.Class,value=“classpath:app.conf”)注释的类。

和一个简单的测试类:

@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class SomeTest {
    @Test
    public void someCoolTest() {/* ... */}
    // ...
}
运行junit测试运行程序时,出现以下错误:

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.4.0.jar:1.4.0]
    at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:74) ~[config-1.4.0.jar:1.4.0]
    at com.typesafe.config.impl.PathParser.parsePath(PathParser.java:61) ~[config-1.4.0.jar:1.4.0]
...
如果我取消注释
ServerProperties
类上的@PropertySource行,测试将正常进行。我觉得奇怪的是,我的自定义
PropertySourceFactory
妨碍了默认的
.properties
文件解析过程

PropertySource和Factory类
//TypesafeConfigPropertySource.java
导入com.typesafe.config.config;
导入org.springframework.core.env.PropertySource;
公共类TypesafeConfigPropertySource扩展PropertySource{
公共类型安全配置属性源(字符串名称,配置源){
超级(名称、来源);
}
@凌驾
公共对象getProperty(字符串路径){
if(source.hasPath(path)){
返回source.getAnyRef(路径);
}
返回null;
}
}
//TypesafePropertySourceFactory.java
导入com.typesafe.config.config;
导入com.typesafe.config.ConfigFactory;
导入org.springframework.core.env.PropertySource;
导入org.springframework.core.io.support.EncodedResource;
导入org.springframework.core.io.support.PropertySourceFactory;
导入java.io.IOException;
导入java.util.Objects;
公共类TypesafePropertySourceFactory实现PropertySourceFactory{
@凌驾
公共属性源createPropertySource(字符串名称,EncodedResource资源)引发IOException{
Config Config=ConfigFactory.load(Objects.requirennull(resource.getResource().getFilename()).resolve();
字符串safeName=name==null?“类型安全”:name;
返回新类型SafeConfigPropertySource(safeName,config);
}
}
我是否缺少配置自定义属性资源工厂的一些基本信息,或者这是一个bug

版本
  • 弹簧靴2.3.4
  • Junit Jupiter 5.6.2

也许您也可以使用上下文初始值设定项来解决此问题,如以下答案所示:


也许您也可以使用上下文初始值设定项来解决此问题,如下面的答案所示:

TL;博士 如果无法在自定义impl中处理
路径
,则返回
null

public class TypesafeConfigPropertySource extends PropertySource<Config> {
    // ...    
    @Override
    public Object getProperty(String path) {
        try {
            if (source.hasPath(path)) {
                return source.getAnyRef(path);
            }
        } catch(ConfigException.BadPath ignore) {
        }
        return null;
    }
    // ...
}
公共类TypesafeConfigPropertySource扩展了PropertySource{
// ...    
@凌驾
公共对象getProperty(字符串路径){
试一试{
if(source.hasPath(path)){
返回source.getAnyRef(路径);
}
}捕获(ConfigException.BadPath忽略){
}
返回null;
}
// ...
}
解释 我正在进行有根据的猜测,但从功能上看,代码的行为方式似乎支持这一点

最有可能的场景是,在任何默认实现之前,解析顺序将考虑我们的自定义实现。在我们的实现中使用的方法将与包含“:”和“[”的任何路径一起出错,因为在检查路径是否存在时出错

我只是简单地包装
BadPath
异常,以便捕获任何问题,然后返回null表示不匹配 如果无法在自定义impl中处理
路径
,则返回
null

public class TypesafeConfigPropertySource extends PropertySource<Config> {
    // ...    
    @Override
    public Object getProperty(String path) {
        try {
            if (source.hasPath(path)) {
                return source.getAnyRef(path);
            }
        } catch(ConfigException.BadPath ignore) {
        }
        return null;
    }
    // ...
}
公共类TypesafeConfigPropertySource扩展了PropertySource{
// ...    
@凌驾
公共对象getProperty(字符串路径){
试一试{
if(source.hasPath(path)){
返回source.getAnyRef(路径);
}
}捕获(ConfigException.BadPath忽略){
}
返回null;
}
// ...
}
解释 我正在进行有根据的猜测,但从功能上看,代码的行为方式似乎支持这一点

最有可能的情况是,在任何默认实现之前,解析顺序将考虑我们的自定义实现。在我们的实现中使用的方法将在包含路径的错误中出现的任何路径中包含“:”和“”。


我只是简单地包装
BadPath
异常,以捕获任何问题,然后返回null表示不匹配。

我回家后会尝试,但这对我来说是一个计划B。我回家后会尝试,但这对我来说是一个计划B。
public class TypesafeConfigPropertySource extends PropertySource<Config> {
    // ...    
    @Override
    public Object getProperty(String path) {
        try {
            if (source.hasPath(path)) {
                return source.getAnyRef(path);
            }
        } catch(ConfigException.BadPath ignore) {
        }
        return null;
    }
    // ...
}