Q: Using i18n resources from WEB-INF in Junit test I think I ran into an error with my classpath settings.
I want to test an internationalized web-app which has the messagesource defined like this:
<bean id="messageSource"
  class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>/WEB-INF/i18n/errors</value>
            <value>/WEB-INF/i18n/messages</value>
            <value>/WEB-INF/i18n/links</value>
            <value>/WEB-INF/i18n/forms</value>
            <value>/WEB-INF/i18n/communication</value>
        </list>
    </property>
</bean>

Loading these values works perfectly in a production environment.
When running a Junit Test however, it can't resolve those property files because they are not on the classpath.
However, I want them to be NOT on the classpath because then I can make use of the feature where I can change something in the property files and it's reflected on the website immediately: Since application servers typically cache all files loaded from the classpath, it is necessary to store resources somewhere else (for example, in the "WEB-INF" directory of a web app). Otherwise changes of files in the classpath will not be reflected in the application.
The spring applicationContext is located there: /src/main/resources/spring/applicationContext.xml
and loaded into the Junit test with these annotations:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/spring/applicationContext.xml"})

How can I get Junit to pick up those non-classpath resources as well?
The property files are on /src/main/webapp/WEB-INF/i18n/*
Junit: 4.7.
Spring: 3.0.5.

A: I fixed my initial problem in the meantime.
Matthew's solution didn't help me - still very good input.
And he couldn't know that I was using maven in my project since I never told.
However, within maven, I found a solution to my problem:
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <skipTests>true</skipTests>
                <additionalClasspathElements>
                    <additionalClasspathElement>src\main\webapp\</additionalClasspathElement>
                </additionalClasspathElements>
            </configuration>
        </plugin>

I configured the surefire-plugin to pickup additional elements for the classpath.

A: It seems to me the simplest solution is just use a property which you override when junit is executing:
<bean id="messageSource"
  class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basenames">
        <list>
            <value>${path.prefix}/WEB-INF/i18n/errors</value>
            <value>${path.prefix}/WEB-INF/i18n/messages</value>
            <value>${path.prefix}/WEB-INF/i18n/links</value>
            <value>${path.prefix}/WEB-INF/i18n/forms</value>
            <value>${path.prefix}/WEB-INF/i18n/communication</value>
        </list>
    </property>
</bean>

You set the default value for this in the PropertyPlaceholderConfigurer
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
    <property name="properties">
        <props>
            <prop key="path.prefix"></prop> <!-- empty -->
        </props>
    </property>
</bean>

This propertyConfigurer bean definition needs to be before the messageSource bean definition. In the junit tests, you can either:


*

*set the property through using a different version of the propertyConfigurer specific to your tests, or

*setting the system property through a -Doption on the command line or System.setProperty("path.prefix", "src/main/webapp") in your @Before.


Note that if you do (2), then Spring sometimes caches the values of system properties, so you can't subsequently change the system property. It uses the original value.
