maven打包时报Could not resolve placeholder

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.PropertyPlaceholderConfigurer的 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

上一篇:Windows 免密码登录


下一篇:Logstash could not be started because there is already another instance using the configured data d