All entries for Tuesday 18 April 2006
April 18, 2006
Testing configuration in spring
Useful tips for unit testing the configuration in spring:
If you have lots of references like "/WEB-INF/xyz" then Spring will convert these FieSystemResources. This is fine, if your root directory contains "/WEB-INF/", but it probably doesn't. Our project structure has "/WEB-INF" living underneath "/war". To fix this simply provide your own FileSystemResourceLoader:
FileSystemResourceLoader fileSystemResourceLoader = new FileSystemResourceLoader() {
protected Resource getResourceByPath(String path) {
path = "/war" + path;
return super.getResourceByPath(path);
}
};
Secondly, if you have an applicationContext and a number of -servlet and you are not explicitly listing the -servlet.xml in the ContextLoader then spring creates the parent applicationContext.xml and then creates child applicationContexts for each -servlet. You need to mirror this hierarchy, otherwise you may end up running into namespace clashes:
GenericWebApplicationContext parentCtx = new GenericWebApplicationContext();
parentCtx.setServletContext(new MockServletContext());
/**
* Files are referenced (e.g.) "/WEB-INF" however that won't resolve during this test
* so correct the path.
*/
FileSystemResourceLoader fileSystemResourceLoader = new FileSystemResourceLoader() {
protected Resource getResourceByPath(String path) {
path = "/war" + path;
return super.getResourceByPath(path);
}
};
FileSystemResourceLoader loader = fileSystemResourceLoader;
parentCtx.setResourceLoader(loader);
configureSystemProperties();
XmlBeanDefinitionReader parentXmlReader = new XmlBeanDefinitionReader(parentCtx);
/**
* Cannot use classpath because crappy Eclipse (or my crappy knowledge
* of eclipse ;)) won't let you have a folder as a classpath and show
* in package explorer. Besides which web-inf/classes is already on the
* classpath (for Chris + tomcat) and eclipse definately won't allow
* nested classpaths (i.e. /web-inf)
*/
String[] contextFiles = {
"applicationContext.xml",
"sitebuilderAdmin-servlet.xml",
"sitebuilderApi-servlet.xml",
"sitebuilderEdit-servlet.xml",
"sitebuilderError-servlet.xml",
"sitebuilderRender-servlet.xml",
"sitebuilderUser-servlet.xml"
};
/**
* Must load each context into it's own file to prevent name space clashes.
*/
for (String contextFile: contextFiles) {
GenericWebApplicationContext childCtx = new GenericWebApplicationContext();
childCtx.setServletContext(new MockServletContext());
childCtx.setParent(parentCtx);
childCtx.setResourceLoader(loader);
XmlBeanDefinitionReader childXmlReader = new XmlBeanDefinitionReader(parentCtx);
childXmlReader.loadBeanDefinitions(new FileSystemResource(FILE_PREFIX + contextFile));
childCtx.refresh();
}
And finally; move all external beans (JNDI, DataSource etc.) out of the applicationContext and into their own contexts. I had already done this, and the applicationContext imported them as it is good practice to fragment large XML files into smaller atomic units. Rather than applicationContext importing them directly, wire them up in the contextLoader:
contextConfigLocation
/WEB-INF/applicationContext.xml, /WEB-INF/hibernate-context.xml, /WEB-INF/tiles-context.xml
The last tip is rewrite crappy crappy tilesConfigurer! The problem is that the tilesConfigurer doesn't expect a number of resources, it expects a single comma seperated String :( This means that if you specify "/WEB-INF/" then everything will break because the directory doesn't exist (it is /war/WEB-INF).
The whole thing would have been much simpler if eclipse allowed you to specify a folder as being on the classpath and showed it in package explorer. At the moment as soon as a folder is marked as being on the class path it is hidden from the explorer.
HTH
Interesting article about blogs
Writing about web page http://elliottback.com.nyud.net:8080/wp/?p=1351
Nice article summarising the top 10 blogs (from a design point of view).
Please wait - comments are loading
Loading…