Property placeholder in bean class name results exception but bean is instantiated afterwards
See original GitHub issueAffects: 4.3.30, 5.2.13, 5.3.4
I tried all three, same result.
I have a Spring Web Application. The root context is loaded with:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/*.xml</param-value>
</context-param>
and files are:
/webapp/src/main/webapp/WEB-INF/spring
/webapp/src/main/webapp/WEB-INF/spring/jaxrs
/webapp/src/main/webapp/WEB-INF/spring/jaxws
/webapp/src/main/webapp/WEB-INF/spring/config-properties.xml
/webapp/src/main/webapp/WEB-INF/spring/root-context.xml
/webapp/src/main/webapp/WEB-INF/spring/x2tc-proxy-components.xml
Note JAX-RS and JAX-WS have their subcontexts. They do not matter now here.
config-properties.xml
is merely:
<beans:bean id="config" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<beans:property name="locations">
<beans:array>
<beans:value>classpath:x2tc-proxy.properties</beans:value>
<beans:value>classpath:x2tc-proxy-override.properties</beans:value>
<beans:value>file:${catalina.base}/conf/x2tc-proxy/tc-system.properties</beans:value>
<beans:value>file:${catalina.base}/conf/x2tc-proxy/credentials.properties</beans:value>
</beans:array>
</beans:property>
<beans:property name="ignoreResourceNotFound" value="true" />
</beans:bean>
x2tc-proxy.properties
contains:
...
teamcenter.auth.credentialsFactory.plain=....PlainCredentialsFactoryBean
teamcenter.auth.credentialsFactory.offlineSso=....OfflineSsoCredentialsFactoryBean
teamcenter.auth.credentialsFactory.onlineSso=...OnlineSsoCredentialsFactoryBean
All of these factory beans have everything autowired and return an object of interface type Credentials
. Now credentials.properties
contains specific config for a factory type, depending on a deployment. The properties file contains:
teamcenter.auth.credentialsFactory=onlineSso
# followed by all properties the `OnlineSsoCredentialsFactoryBean` requires.
x2tc-proxy-components.xml
contains:
<beans:bean id="credentialsFactory"
class="${teamcenter.auth.credentialsFactory.${teamcenter.auth.credentialsFactory}}" />
I’d like to configure the concrete factory bean class name in the properties file w/o fiddling the beans definition. At startup I see the following:
22:30:53.037 [localhost-startStop-1] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Ignoring bean class loading failure for bean 'credentialsFactory'
org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [${teamcenter.auth.credentialsFactory.${teamcenter.auth.credentialsFactory}}] for bean with name 'credentialsFactory' defined in ServletContext resource [/WEB-INF/spring/x2tc-proxy-components.xml]; nested exception is java.lang.ClassNotFoundException: ${teamcenter.auth.credentialsFactory.${teamcenter.auth.credentialsFactory}}
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1397)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:638)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:607)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1496)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:425)
but as it seems the factory bean is still wired and the objects from the factory are perfectly.
It is not clear whether this is intentional or bug. StackOverflow contains a bunch of questions where people try to provide a class name from a property.
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (3 by maintainers)
Yes, you have concluded correctly.
In general, if Spring logs something at DEBUG or TRACE level and your app still works fine, then the log messages are only there for informational purposes.
My tip: filter logging at INFO or WARN and only revert to DEBUG or TRACE if you run into issues.
Thanks a million. I can safely put this in production now.