1、问题
今天打包时,遇到一个很奇怪的事,在我打包的时侯报如下问题,但是我用IDEA启动却没有任何异常。
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'zookeeper.file.cache' in value "${zookeeper.file.cache}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:178)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:124)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236)
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:175)
at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveStringValue(BeanDefinitionVisitor.java:296)
at org.springframework.beans.factory.config.BeanDefinitionVisitor.resolveValue(BeanDefinitionVisitor.java:222)
at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitPropertyValues(BeanDefinitionVisitor.java:147)
at org.springframework.beans.factory.config.BeanDefinitionVisitor.visitBeanDefinition(BeanDefinitionVisitor.java:85)
at org.springframework.beans.factory.config.PlaceholderConfigurerSupport.doProcessProperties(PlaceholderConfigurerSupport.java:225)
... 43 more
2、查找原因
2.1 通常的原因
我在网上搜了一下,都是项目启动的时候报这个问题,而没有说打包的时候会有这个问题
启动时报错的原因一般都是除去properites文件路径错误、拼写错误外,出现"Could not resolve placeholder"很有可能是使用了多个PropertyPlaceholderConfigurer或者多个context:property-placeholder的原因。
比如我有一个dao.xml读取dbConnect.properties,还有一个dfs.xml读取dfsManager.properties,然后web.xml统一load这两个xml文件
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
WEB-INF/config/spring/dao.xml,
WEB-INF/config/spring/dfs.xml
</param-value>
</context-param>
如果这两个xml文件中分别有
<!-- dao.xml -->
<context:property-placeholder location="WEB-INF/config/db/dbConnect.properties" />
<!-- dfs.xml -->
<context:property-placeholder location="WEB-INF/config/dfs/dfsManager.properties" />
那么,一定会出"Could not resolve placeholder"。
一定要记住,不管是在一个Spring文件还是在多个Spring文件被统一load的情况下,直接写
<context:property-placeholder location="" />
<context:property-placeholder location="" />
是不允许的。
一般的解决方案:
(1) 在Spring 3.0中,可以写:
<context:property-placeholder location="xxx.properties" ignore-unresolvable="true" />
<context:property-placeholder location="yyy.properties" ignore-unresolvable="true" />
注意两个都要加上ignore-unresolvable=“true”,一个加另一个不加也是不行的
(2) 在Spring 2.5中,context:property-placeholder没有ignore-unresolvable属性,此时可以改用PropertyPlaceholderConfigurer。其实<context:property-placeholder location=“xxx.properties” ignore-unresolvable=“true” />与下面的配置是等价的
<bean id="随便" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="xxx.properties" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
正因为如此,写多个PropertyPlaceholderConfigurer不加ignoreUnresolvablePlaceholders属性也是一样会出"Could not resolve placeholder"。
虽然两者是的等价的,但估计大家还是喜欢写<context:property-placeholder>
多一些,毕竟简单一些嘛。所以如果是Spring 3.0,直接用解决方案(1)再简单不过了;如果是Spring 2.5,需要费点力气改写成PropertyPlaceholderConfigurer
原因:
Spring容器采用反射扫描的发现机制,在探测到Spring容器中有一个 org.springframework.beans.factory.config.PropertyPlaceholderConfigure
r的 Bean就会停止对剩余PropertyPlaceholderConfigurer
的扫描(Spring 3.1已经使用PropertySourcesPlaceholderConfigurer
替代 PropertyPlaceholderConfigurer了)。
而<context:property-placeholder/>
这个基于命名空间的配置,其实内部就是创建一个PropertyPlaceholderConfigurer
Bean而已。换句话说,即Spring容器仅允许最多定义一个PropertyPlaceholderConfigurer
(或<context:property-placeholder/>
),其余的会被Spring忽略掉(其实Spring如果提供一个警告就好了)。
2.2 非通常的情况
但是我按上面的方式检查后,发现我并没有出现多个context:property-placeholder
,于是我想起来在test包下有一个测试环境,里面引入的context:property-placeholder
,所以我把test包删掉,发现打包一切正常了。
当一般工作中,是协同环境,不能删除test包,所以在pom.xml文件中需要添加一个插件来在打包的时候跳过test
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip> true </skip>
</configuration>
</plugin>
</plugins>
3、参考
https://blog.csdn.net/u012149181/article/details/80767327
cnblogs.com/YingYue/p/5699962.html