FileSystemXmlApplicationContext Reads Wrong Resource Location from JBoss
I have a legacy application which uses the following style to load Spring context:String rootDir = System.getProperty("rootDir"); StringBuffer path = new StringBuffer(); path.append(rootDir); path.append("/spring-context.xml"); ApplicationContext ctx = new FileSystemXmlApplicationContext(path.toString());
The 'rootDir' system property is defined in JBoss's standalone.xml as follow:
<system-properties> <property name="rootDir" value="/opt/jboss-as-7.1.1.Final/modules/someproject/main/conf"/> </system-properties>
The spring-context.xml file is put under "/opt/jboss-as-7.1.1.Final/modules/someproject/main/conf".
However, when I started JBoss and got this application running, it gave me this exception:
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from file [/root/opt/jboss-as-7.1.1.Final/modules/com/someproject/main/conf/spring-context.xml]; nested exception is java.io.FileNotFoundException: opt/jboss-as-7.1.1.Final/modules/com/someproject/main/conf/spring-context.xml (The system cannot find the path specified)
It was weird because from the log it tried to load Spring context from "
opt/jboss-as-7.1.1.Final/modules/someproject/main/conf" (there is no "/" before "opt").
What happened?
FileSystemXmlApplicationContext Source Code
I tried to search on the Internet but got no answer. So I decided to read through source code based on the exception stack trace.Finally I found the following code from FileSystemXmlApplicationContext.
protected Resource getResourceByPath(String path) { if (path != null && path.startsWith("/")) { path = path.substring(1); } return new FileSystemResource(path); }
So it was Spring that removed the beginning slash!
Spring's Javadoc explains why:
<b>NOTE:</b> Plain paths will always be interpreted as relative * to the current VM working directory, even if they start with a slash. * (This is consistent with the semantics in a Servlet container.) * <b>Use an explicit "file:" prefix to enforce an absolute file path.</b>
OK. So the solution to this problem is:
JBoss System Properties Setting for FileSystemXmlApplicationContext to Work
1. Add an additional "/" to the beginning of the path, like this:<system-properties> <property name="rootDir" value="//opt/jboss-as-7.1.1.Final/modules/someproject/main/conf"/> </system-properties>
2. Prefix with "file:" to the path
<system-properties> <property name="rootDir" value="file:/opt/jboss-as-7.1.1.Final/modules/someproject/main/conf"/> </system-properties>
I've tested solution 1 and it worked fine. I suppose solution 2 should also work.