项目场景:
本地项目启动,报 java.lang.IllegalStateException: Invalid name=“org.apache.dubbo.config.ApplicationConfig#0” 异常,除了本地其他环境都正常。
问题描述
Caused by: java.lang.IllegalStateException: Invalid name=“org.apache.dubbo.config.ApplicationConfig#0” contains illegal character, only digit, letter, ‘-’, ‘_’ or ‘.’ is legal.
at org.apache.dubbo.config.utils.ConfigValidationUtils.checkProperty(ConfigValidationUtils.java:592)
at org.apache.dubbo.config.utils.ConfigValidationUtils.checkName(ConfigValidationUtils.java:548)
at org.apache.dubbo.config.utils.ConfigValidationUtils.validateApplicationConfig(ConfigValidationUtils.java:388)
at org.apache.dubbo.config.bootstrap.DubboBootstrap.checkGlobalConfigs(DubboBootstrap.java:543)
at org.apache.dubbo.config.bootstrap.DubboBootstrap.initialize(DubboBootstrap.java:525)
at org.apache.dubbo.config.bootstrap.DubboBootstrap.init(DubboBootstrap.java:508)
at org.apache.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:237)
at org.apache.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:205)
at org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor.doGetInjectedBean(ReferenceAnnotationBeanPostProcessor.java:144)
at com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor.getInjectedObject(AbstractAnnotationBeanPostProcessor.java:359)
at com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor$AnnotatedFieldElement.inject(AbstractAnnotationBeanPostProcessor.java:539)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:130)
at com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor.postProcessPropertyValues(AbstractAnnotationBeanPostProcessor.java:142)
… 18 common frames omitted
原因分析:
从报错来看,在 checkProperty(检查属性)的时候,发现 ApplicationConfig 配置项包含非法字符。于是就检查 application.properties 配置,发现所有的配置项都没有问题,觉得很奇怪,就怀疑编译出了问题,于是检查 target 包,发现配置文件没了。
什么原因导致呢?于是检查近期提交记录,发现 pom.xml 提交一段打包去配置项的代码:
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.yml</exclude>
</excludes>
</resource>
</resources>
解决方案:
注释掉该代码,重新编译,启动成功!原来这段代码不止打包时会剔除配置文件,本地编译也会!那么为什么会加这段代码呢,因为线上环境在 jar 包外配置了 application.properties,但是读取到了 jar 包里面的配置,当时觉得很奇怪,jar 包外的配置项优先级更高才对,也没仔细检查配置项就把 jar 包里的配置文件剔除了。后来发现 jar 包里比外面多了一个配置,虽然这个配置不是必需项,但也会透过优先级更高的配置往优先级低的配置里读。那么 spring 读取 application.properties 配置文件的优先级是怎样的呢?
1. 第一优先级:jar 包同级目录 config 文件夹里的配置;
2. 第二优先级:jar 包同级目录里的配置;
3. 第三优先级:jar 包内部 resources 下 config 文件夹里的配置;
4. 第四优先级:jar 包内部 resources 下的配置;
所以没必要在打包的时候剔除掉 jar 包内部的配置,如果读到了 jar 包内部配置项,大概率是外部配置文件比 jar 包内部少了配置项。而且这段代码也隐藏了一些坑,线上环境验证的时候字体一直读取不到导致报错,字体也是放在了 resources 下面的,把这段代码注掉就好了。