What happens behind the scenes when a property placeholder is defined in a Spring context (JNDI-wise)?

StackOverflow https://stackoverflow.com/questions/21702005

Question

I have a Java web application using Spring and JSF, deployed in Tomcat. For the record, in web.xml, only the Faces servlet is configured; there is no Spring servlet.

The entry point to my Spring context is applicationContext.xml, which looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">

    <context:component-scan base-package="my.pack" annotation-config="true" />
    <context:property-placeholder location="file:${admin.config.path}/database.properties"/>

    <context:spring-configured />
    <context:annotation-config />
    <aop:aspectj-autoproxy />
</beans>

In the property-placeholder definition one can see that I'm injecting an external property, which, in this case, is an environment variable. This property is passed via Tomcat context configuration, like this:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/cntxt">
    <Environment name="admin.config.path" value="d:/conf/"
         type="java.lang.String" override="false"/>
</Context>

I'm also injecting this environment variable in one of my Spring-managed beans, like this:

@Value("${java:comp/env/admin.config.path}")
private String confDir;

(This is because I'm also using that directory for some other configuration files, which are not .properties files).

With the configuration above, everything works just fine - all the wirings are performed without any flaw.

But, at some moment, I stopped needing injecting properties via the property placeholder configurer from database.properties (but I still need the other files from the admin.config.path), therefore I removed the <context:property-placeholder> line from applicationContext.xml. At that moment, the injection using @Value stopped working in my Spring-managed bean.

Does anybody know what actually happened? It seems like the JNDI injection fails if the property placeholder configurer is not defined in the Spring context. Is there any way I can re-enable this kind of injection (without defining a dummy property placeholder pointing to an empty properties file)?

Était-ce utile?

La solution

You need a property placeholder configurer instance, the sole purpose of it is to replace placeholders with actual values. If you remove it no placeholders will be replaced.

Either add a <context:property-placeholder /> and leave out the location field or add a bean of the type PropertySourcesPlaceholderConfigurer. Either way will re-enable your placeholder support.

Small suggestion remove the java:comp/env part of the property, by default it will do a JNDI lookup if the property cannot be resolved in other locations (servlet context, properties, system properties etc.).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top