I've got some XML files under my WEB-INF directory:
- lyricsBaseApp-servlet.xml
- hibernate.xml
- dataSource.xml
- beans.xml
the servlet xml imports other xml files:
<import resource="dataSource.xml"/>
<import resource="hibernate.xml"/>
<import resource="beans.xml"/>
I would like my junit4 JukeboxTest
class to include entire spring configuration. Using default filename I have created a JukeboxTest-content.xml
file. And finally, I do not know what to put there...
I've tried:
<import resource="/WEB-INF/dataSource.xml"/>
<import resource="/WEB-INF/hibernate.xml"/>
<import resource="/WEB-INF/beans.xml"/>
or
<import resource="classpath:./WEB-INF/dataSource.xml"/>
<import resource="classpath:./WEB-INF/hibernate.xml"/>
<import resource="classpath:./WEB-INF/beans.xml"/>
and some other ideas but all failed. Could someone point me how to access those files and what way spring interprets those filepaths?
try this
Option 1 (should be preferred as it's the best practice):
Refactor your config files under
WEB-INF
and move the common parts (that you want to access also from integration tests) tosrc/main/resources/
. Then write test specific configuration files insrc/test/resources/
(if you only need to import several different config files fromsrc/main
to assemble your test context, then skip this, and use@ContextConfiguration
preferably).Option 2 (hack):
Use references like:
Option 3 (hack):
If you have a Maven project, you can configure the
maven-surefire-plugin
(used in the test phase) to declaresrc/main/webapp
as an additional classpath element during test execution.The latter two options are considered as hack, because files under
src/main/webapp
are simply not supposed to be on the classpath.Now the detailed explanation:
The reason why you can't refer to these files as
classpath:/WEB-INF/*.xml
is that they are indeed not on the classpath. It's important to understand how your webapp is packaged, and what exactly ends up on the classpath. Assuming a default Maven project structure:src/main/java
go to/WEB-INF/classes
after compilation.src/main/resources
go to/WEB-INF/classes
as well./WEB-INF/lib
.src/main/webapp
goes to/
(root of the package). This means that all files fromsrc/main/webapp/WEB-INF
go to/WEB-INF
, of course.The most important thing to know is that the classpath will only contain
/WEB-INF/classes
and one entry for each jar in/WEB-INF/lib
. Consequently, resources outside these two locations are completely invisible for the classloader. This is also true for the xml config files directly under/WEB-INF
, which is why the referenceclasspath:/WEB-INF/dataSource.xml
will never work.You may ask yourself, how the hell are then these xml config files loaded by Spring if they are not reachable from the classpath? The answer is simple: When you start your webapp (as opposed to executing just unit/integration tests), it is running in a Servlet Container which provides access to the
ServletContext
(an actual class from the Servlet API), so it usesServletContext.getResourceAsStream()
to load these files. The key for understanding is the following quote from the javadoc of this method:Sorry this become way too long, but that's the whole story...