I have a central class (RuntimeConfiguration
) that holds around 100
parameters for my application. These parameters are taken from an XML file which I stored in the WEB-INF
folder. On my development box, I hard-coded the path, but for very obvious reasons, this is not a productive solution.
For portability reasons (my application might be executed on a Tomcat or a Jetty and under Windows OR Unix), I want to have a generic access way to this file from within my RuntimeConfiguration
class.
I know, I can use getRealPath
in case I have a servlet, BUT RuntimeConfiguration
is NOT started within a servlet context. It is invoked from a job (a crawler) which in turn is started from quartz job control via applicationContext.xml
. Now this seems to be the core of my problem.
Can anyone tell me, how to get the absolute path to my XML in this environment?
I tried this ClassLoader
approach, but it gives me a NullPointerException
:
ClassLoader loader = this.getClass().getClassLoader();
loader.getResource("WEB-INF");
result = loader.getSystemResource(RTCF).toString();
I also tried
URL url = this.getClass().getClassLoader().getResource("WEB-INF");
which also throws a null pointer exception
Can anyone give me a portable solution, one that works on my dev-machine and on a production system where my application is deployed as a WAR-file?
By the way, the method should at best be able to handle Windows AND Mac OS X / Unix based systems.
You can always use the holder pattern : you create a class, with a static field (with its static getter) that will contain the real path of the WEB-INF
directory. This class should implement ApplicationContextAware
You create in root spring application context an instance of this holder class, Spring give it a pointer to the ApplicationContext that will be a WebApplicationContext
as you are in a web application.
In the init method, you use the WebApplicationContext
to get the path and store it in the static field. Thanks to Spring, you are sure that the method is called once and only once before the application really starts.
Now anywhere in the application where you want to get the path, you can use it by calling the static getter.
public class ResourcePathHolder implements ApplicationContextAware, InitializingBean{
private WebApplicationContext wac;
private static String resourcePath;
private static ServletContext sc;
private String path = "WEB-INF";
public static String getResourcePath() {
return resourcePath;
}
public static ServletContext getServletContext() {
return sc;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
wac = (WebApplicationContext) applicationContext;
}
public void setPath(String path) {
this.path = path;
}
@Override
public void afterPropertiesSet() throws Exception {
ResourcePathHolder.sc = wac.getServletContext();
ResourcePathHolder.resourcePath = sc.getRealPath(path);
}
}
This implementation also gives you access to the ServletContext
to allow you to use ServletContext.getResource()
EDIT :
Using the full path may not work on production servers that would not explode the war. From the javadoc for ServletContext.getRealPath()
: This method returns null if the servlet container is unable to translate the given virtual path to a real path. But in that case, you can always access to the files as resources with ServletContext.getResource()
or ServletContext.getResourceAsStream()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With