First, getRealPath isn't going anywhere. The notes in request.getRealPath (the deprecated one) tell you to use ServletContext.getRealPath which isn't deprecated. java.lang.String)" target="_blank" rel="nofollow">http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletRequest.html#getRealPath(java.lang.String)
Regardless of whether it's deprecated or not, it's not a great idea to rely on it. There can only be a path to a resource in a webapp if the app is being run from an exploded file system. If the application is being run from a packed war file, getRealPath will return null.
I've always felt it's better to make the path to any resources you want to write to configurable via context or servlet init-params. For read-only resources, it's better to rely on Request.getResourceAsStream java.lang.String)" target="_blank" rel="nofollow">http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletContext.html#getResourceAsStream(java.lang.String) [ December 27, 2005: Message edited by: Ben Souther ]
Were you suggesting to hard-code full path in an init-param?
I would follow Ben's advice on this. There are several different ways to configure this since getRealPath is not reliable, as Ben stated. You can put it in the web.xml as an init-param or you can put it in your own config of sorts. For example, on one project I worked on I had a simple properties file that I loaded on application startup via a context listener. I loaded the config file into a map and put it in application scope. I had a helper class that made it real easy for me to get the map back starting from the FacesContext.
But that is only one way. You could store the value in the database if you wanted to.
So, I'd just create a properties file and on each server, store the full path to the webRoot in there. Then, I could just concatenate the file name I need to create and I'm all set.
I was hoping this could be done programmatically, but perhaps this is the best and most reliable method.
Right, the problem with doing it all programmatically (by that I mean all from java code, no config type files) is that, like Ben already mentioned, there is no 100% reliable means to get the path you need.
For temporary files, go all the way back to basic java.io.File and use the create temp file method. Your appserver will generally customize the runtime, so as an example, createTempFile() when used in a Tomcat-deployed app will probably construct the file in TOMCAT_HOME/temp.
If you intend on reading and writing permanent files, What I'd recommend is that you define their location in your web.xml as env-entry items. This takes their definitions out of program code and places them in a file that can be edited using a deployment tool (Tomcat can also override the value in web.xml as a Context directive). Your webapp program code can retrieve the configured path info using JNDI (java:comp/env).
People tend to forget that the classpath for a webapp not only need not be sourcing from a directory tree, in fact, it need not even be coming from a local source. If Tomcat (or WebLogic for that matter), wanted to define a context as getting its classes from URL "svn://production-modules.myco.com/webapps/funnyapp.war", that's perfectly allowable under the servlet architecture. Which is why using a relative path may sound like a good idea, but isn't.
An IDE is no substitute for an Intelligent Developer.
If anyone still cares about this (this thread is a year old as of my post), I have solved this issue in my application.
I'm writing an Ajax application that has a dynamic call to a JFreeChart chart that I want to display only after the user has made some database queries. JFreeChart's writeChartAsPNG() function does not allow a null chart object to be passed, so I want to serve up a transparent png instead of the chart in the servlet which serves up the chart.
Using the Jakarta Commons IO package, my code looks like this:
This allows programmatic access to stream a resource from the web application's file system.
Joined: Jul 12, 2002
Interesting. Do you know if the JFreeChart ($) documentation covers the issue you solved?
I'm about to order it, but am wondering about "basic issues" (that is, that should be documented) like the one you solved (where the issue is nowhere to be found in the docs).