Up until now I have been using Spring 4.0.8, and the following worked just fine:
In my unit test, I was putting a value in the jndi environment:
SimpleNamingContextBuilder _simpleNamingContextBuilder =
new SimpleNamingContextBuilder();
_simpleNamingContextBuilder.bind(
"java:comp/env/myBoolVar", true);
_simpleNamingContextBuilder.activate();
Then in my class, I access it like this:
@Value("#{environment.myBoolVar}")
private Boolean _myBoolVar = Boolean.FALSE;
I have upgraded to Spring 4.1.2 and this no longer works. The default value, false, is always used, because Spring isn't able to find the value.
If I use the old way of accessing this value:
@Resource(mappedName = "java:comp/env/myBoolVar")
it does work.
I have been scouring SO and the web at large and I have seen tons of information but none has helped me to fix the problem. My understanding is that the Spring Environment has access to all the values @Value does. So I'm not sure what the problem is.
FYI for anyone out there struggling with this. In the end I put the code that added the "myBoolVar" value to the SimpleNamingContextBuilder in a method with a @BeforeClass annotation, and it works fine now.
Basically what was happening is, upon startup Spring tries to sort out what PropertySources it has, in the StandardServletEnvironment.customizePropertySources() method. When it comes time to look for a jndiProperties, it does the following:
if(JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
propertySources.addLast(new JndiPropertySource("jndiProperties"));
}
And that method, JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable(), does the following:
try {
new InitialContext().getEnvironment();
return true;
}
catch (Throwable ex) {
return false;
}
Ini my case, the call to getEnvironment() was throwing a NoInitialContextException:
javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial
Which prevented Spring from creating a jndiProperties PropertySource, and as such my boolean var was getting lost.
So I started looking all over the web for why this was happening ... but then found an old article on the Spring Forum saying this put my code in a @BeforeClass block, et voilà.
I hope this saves someone some pain and suffering at some time on the future.