31

getRealPath() is returning the actual path in the local system, but returns null when deployed with a .war file.

<%@ page import="java.io.*" %>
<%@ page contentType="text/html;charset=ISO-8859-1" %> 
<%
int iLf = 10;
char cLf = (char)iLf;
String a= application.getResource("/");
//String myfile = application.getRealPath("/")+ "generate.xml";
//String myfile = request.getContextPath()+"generate.xml";
//String myfile = request.getRealPath("/")+"generate.xml";

out.println(myfile);    
File outputFile = new File(myfile);
outputFile.createNewFile();
FileWriter outfile = new FileWriter(outputFile);
outfile.write(" <?xml version='1.0' encoding='UTF-8'?> "+cLf);
outfile.write(" <playlist version='1' xmlns = 'http://xspf.org/ns/0/' > " +cLf);
outfile.write(" <title>My Band Rocks Your Socks</title> "+cLf); 
outfile.write("<trackList>"+cLf); 
%>
 <%! String[] sports; %>
 <%
    sports = request.getParameterValues("sports");

    out.println("<html><body><h1>hello</h1></body></html>");

    if (sports != null)
    { 
         for (int i = 0; i < sports.length; i++)
         { 
              // outfile.writeln (sports[i]); 
              String total=sports[i];
              String[] sa=total.split("[,]");
              // String[] sub=new String();
              outfile.write("<track>"+cLf);
              for (int j=0;j<sa.length;j++)
              {
                // outfile.writeln(sa[j]);
                // outfile.writeln("sa["+j+"]="+sa[j]);
                if( j == 0)
                {
                     outfile.write("<location>" + sa[0] +"</location>"+cLf); 
                }
                else if (j == 1)
                     {
                        outfile.write("<image>" + sa[1] +"</image>"+cLf); 
                     }
                     else if( j==2)
                          {
                            outfile.write("<title>" + sa[2] +"</title>"+cLf);
                          }

               }// end of inner for loop()       
               outfile.write("</track>"+cLf);
         //outfile.writeln();
      }// end of outer for()
    } 
    //else outfile.writeln ("<b>none<b>");

  outfile.write(" </trackList> "+cLf);
  outfile.write(" </playlist> "+cLf);
  outfile.close();

  %>
<object type="application/x-shockwave-flash" width="400" height="170"
          data="xspf_player.swf?playlist_url=generate.xml">
          <param name="movie" value="xspf_player.swf?playlist_url=generate.xml" />

</object>

Can anyone provide me with an alternative for this? It would be very helpful if you showed some sample code too.

Georg Schölly
  • 124,188
  • 49
  • 220
  • 267
musicking123
  • 3,385
  • 9
  • 32
  • 33
  • Any chance you can clean up the code a bit more please? – David Grant Feb 11 '09 at 10:29
  • Explanation: http://stackoverflow.com/questions/12160639/what-does-servletcontext-getrealpath-mean-and-when-should-i-use-it Answer: http://stackoverflow.com/questions/2161054/where-to-place-and-how-to-read-configuration-resource-files-in-servlet-based-app – BalusC Apr 01 '16 at 10:17

10 Answers10

39

For a start, ServletRequest.getRealPath(String path) is deprecated. The appropriate replacement is:

ServletContext context = session.getServletContext();
String realContextPath = context.getRealPath(request.getContextPath());

However, the API docs for ServletContext.getRealPath(String path) state:

"This method returns null if the servlet container cannot translate the virtual path to a real path for any reason (such as when the content is being made available from a .war archive)."

So the API is fulfilling its contract! However, all is not lost, as you can load a resource from the WAR using the following method, as defined in ServletContext:

ServletContext context = session.getServletContext();
InputStream is = context.getResourceAsStream("generate.xml");
David Grant
  • 13,929
  • 3
  • 57
  • 63
  • 3
    What if I actually do need the path? for example in this question: http://stackoverflow.com/questions/6889728/referencing-a-file-within-servlet the function setOutputProperty needs to get a String of a path, what would i do then? – Nachshon Schwartz Aug 01 '11 at 10:46
  • 2
    What do you do if you want to *write* to the file? getResourceAsStream returns an InputStream, right? – ars-longa-vita-brevis Oct 26 '11 at 09:16
  • 'http://www.coderanch.com/t/372437/java/java/javax-net-ssl-keyStore-system' Unfortunately the javax.net.ssl.trustStore property cannot read the data from classpath but expect it to be a file path. – ggb667 Feb 06 '14 at 14:26
  • 2
    this.getClass().getResource("/").getPath(); – Vishnudev K Aug 13 '14 at 19:41
  • 1
    @VishnudevK worked for me. I had a key file at `/WEB-INF/classes/myKey.pem` and got the full String path using `this.getClass().getResource("/myKey.pem").getPath()`. IMO, this is much more elegant/straight forward than playing around with ServletContext, and no InputStream. Simply uses the standard class loader. – Don Cheadle Dec 30 '14 at 20:01
18

Bit late, but I came across this question when I was having this issue in WebLogic. My solution was to add this to my weblogic.xml:

<?xml version='1.0' encoding='UTF-8'?>
<weblogic-web-app>
    <container-descriptor>
        <show-archived-real-path-enabled>true</show-archived-real-path-enabled>
    </container-descriptor>
</weblogic-web-app>

I found this solution better for when you don't want to (or can't) edit the configuration on the WebLogic server.

WIlfinity
  • 905
  • 9
  • 10
7

do you use Weblogic?

If yes - then this is a Weblogic issue which you may fix in Weblogic admin console ->Domain->Web Applications - click the checkbox "Archived Real Path Enabled".

See: http://ananthkannan.blogspot.com/2009/12/servletcontextgetrealpath-returns-null.html

user2094587
  • 71
  • 1
  • 1
3

I had the same problems too. Calling getRealPath() return null when deployed to a standalone server. After searching around for a while, I found the solution for this, it's not in the code. It's in the config of your web server.

For me it's Weblogic 10.3, you go to Home - - Configuration - Web Application, set Archived Real Path Enabled to true. Restart server and everything works fine.

Hope this help, Regards.

VnMa
  • 35
  • 1
  • 6
3

This solves the problem also:

weblogic.xml

<?xml version = '1.0' encoding = 'windows-1252'?>
<weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd" xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">

<container-descriptor>
  <index-directory-enabled>true</index-directory-enabled>
  <show-archived-real-path-enabled>true</show-archived-real-path-enabled>
</container-descriptor>

<virtual-directory-mapping>
  <local-path>bla.war</local-path>
  <url-pattern>*</url-pattern>
</virtual-directory-mapping>

<context-root>bla</context-root>

Gauthier Boaglio
  • 10,054
  • 5
  • 48
  • 85
user5101998
  • 209
  • 3
  • 9
3

Take note context.getRealPath() can return null when there is user permission problem, check Web server running under which user.

cdeszaq
  • 30,869
  • 25
  • 117
  • 173
skr
  • 31
  • 1
  • This was exactly our problem, since the folder had (by accident) no read access for a specific user. Thanks for pointing that out! – LukeSavefrogs Aug 29 '23 at 14:44
2

if you want to write into

use

this.getClass().getResource("/").getPath();

to get the path

Vishnudev K
  • 2,874
  • 3
  • 27
  • 42
2

I do not believe it is possible to do what you're trying to do.

You should use getResource to read the xml file from inside your war file (this also works without war)

servletContext.getResourceAsStream("/generate.xml")

The leading slash depends on where the generate.xml is stored.

krosenvold
  • 75,535
  • 32
  • 152
  • 208
  • classloader and servletcontext may have different ideas of what is /generate.xml -- one is looking via classpath, another one is through application context (which is counted not from WEB-INF/classes but from the root of the WAR). So the right way is to use ServletContext.getResourceAsStream. – Vladimir Dyuzhev Feb 11 '09 at 15:10
  • answer the question is the main goal. this answer does not provide any solution that works! – Stephan Oct 05 '16 at 10:38
0

The following fix working fine for me.

// I am using Struts2 
ServletContext sc = (ServletContext) ac.get(StrutsStatics.SERVLET_CONTEXT);
fileInputStream = sc.getResourceAsStream("test.xls");

After deployed war file, I am able to get the file from the context path.

Aleksandr M
  • 24,264
  • 12
  • 69
  • 143
-1

The following fix my problem.

  public EHWInit()
  {
   String resetRootPath = ""; 

   try{
   resetRootPath = this.getClass().getResource("/").getPath();
      boolean isWinOS = System.getProperty("os.name").startsWith("Windows");
   if( isWinOS )
      {resetRootPath = resetRootPath.substring(1, resetRootPath.lastIndexOf("chucec"));}
   else
      {resetRootPath = resetRootPath.substring(0, resetRootPath.lastIndexOf("chucec"));}

   resetRootPath = resetRootPath.replace("%20", " ");
   System.out.println("EHWInit#75:resetRootPath=" + resetRootPath); 

When you try to get getRealPath by this.getClass().getResource("/").getPath() when OS is Windows, then you may get a string like following:

EHWInit#73:getPath=/C:/Program%20Files%20(x86)/Apache%20Software%20Foundation/Tomcat%208.5/webapps/chucec/WEB-INF/classes/

Therefor, you need do some extra works on the returning string.Furthermore, if you want to get getRealPath by request. You can replace the code like follows:

  public void resetSystemPath(HttpServletRequest paramHttpServletRequest)
  {
    //String str = paramHttpServletRequest.getRealPath("/");

    HttpSession session = paramHttpServletRequest.getSession(true);
    String str = session.getServletContext().getRealPath("/");
    System.out.println("getRealPath:"+str);