Spring 3.1 brought a lot of good changes to the framework but with any version change, behaviors can be different. Spring does a good job documenting most of this API changes but there is one that I apparently missed or underestimated the impact of.

Property files can be “imported” into the Spring context so that the values can be inserted into configuration using ${ } with the property value inside of the brackets. This is a handy feature that I use frequently in my Spring projects. The PropertyPlaceholderConfigurer has been replaced by PropertySourcesPlaceholderConfigurer in Spring 3.1. One minor difference between them is the latter has the ability to read @Value annotations for direct injection of property values. The other side effect is that the 3.1 class puts system properties ahead of your property file’s values. 3.0, on the other hand, let your property file win if a name matched one as a system parameter.

I ran into this problem because my 3.0 configuration had a replacement parameter for a data source name injected by JNDI. The JNDI name is different between environments at my client, so I had to parameterize it. In Spring 3.0, my configuration was as so:

[gist 1855160]

You’ll notice the context:property-placeholder element has a single properties file. The values read in are:

[gist 1855426]

and they are used in my JNDI configuration:

[gist 1855169]

When I switched to 3.1, I updated the XML namespace to point at 3.1. This changes things behind the scenes to go to PropertySourcesPlaceholderConfigurer. If you want to retain the original 3.0 behavior, you can keep the XMLNS at 3.0 or add system-properties-mode=”FALLBACK”.

[gist 1855156]

I suspected something was happening with the behavior when I saw in the log files that the data source couldn’t be cast as a string. I pulled out my hair trying to figure it out and ended up renaming pavDataSource to PavDataSource and it worked fine. This problem came back up deploying to another environment having the lower case name and I have no ability to change it. Switching back to 3.0 behavior fixed this because I suspect a system parameter was being created with pavDataSource as the name.

[gist 1855239]

Confusing and frustrating as hell, but the simple mode switch made it right as rain.