views:

771

answers:

4

I am trying to access a resource file from a servlet but getting HTTP Error 500 - access denied:

File file = new File("//warChildFolder//myFile.txt");
InputStream is = new FileInputStream(file); // <--error on this line

I am on google-app-engine.

Any help appreciated!

+1  A: 

Does it work if you use single path separators?

(updated to use relative paths):

File file = new File("warChildFolder/myFile.txt");

You need to escape the "\" character in Strings, so use "\", but a single "/" is all that is needed.

Update: It may be that the path being processed is not the same as you expect, you can try logging the absolute path of the file (with file.getAbsolutePath()) to check this.

Another thing to check is that the process has read permissions on the folder/file. If you're not on Windows this can be a problem.

Rich Seller
tried but getting the same error
JohnIdol
thanks for helping - I am also getting access denied from fiel.getAbsolutePath() - I would expect to get a file not found error if the path was wrong
JohnIdol
to me it sounds like a permissions issue then, have you checked them per my last paragraph?
Rich Seller
uh - do I check that? and do I make sure that the permission will be the same once it gets deployed to app-engine? :-/
JohnIdol
Permissions in Unix are checked by running "ls -l" from the shell (see link for details), but it looks like your problem was actually to do with absolute paths. http://en.wikipedia.org/wiki/File_system_permissions#Notation_of_traditional_Unix_permissions
Rich Seller
+1 that's interesting - thanks for your contribution, I also noticed just now you suggested a solution without the leading slash as well
JohnIdol
I missed that originally actually, I updated after the discussion on duffymo's answer
Rich Seller
+2  A: 

Google App Engine docs talk about "white listing" a file. Is that in play here?

I also wonder about this:

File file = new File("//warChildFolder//myFile.txt");

Doesn't the leading slash make this an absolute path?

I'd try it like this:

File file = new File("WEB-INF/warChildFolder/myFile.txt");

Make the path relative to the WAR root and be explicit about WEB-INF.

duffymo
no clue with regards how to white list a file. in my case the warChildFolder is a child of the WAR folder (not within WEB-INF)
JohnIdol
I think white listing is for classes rather than files, do you have a reference?
Rich Seller
Yep - had a look and the docs talk about white listing for classes no mention of files?
JohnIdol
I read the docs as saying it has to be under WEB-INF. And I was reaching with "white list" - first time I saw it as well.
duffymo
It's a good point about the leading slash though, on Unix systems a path prefixed with / is always absolute
Rich Seller
guys - you rock, I removed the the leading slash and it went through! rather strange anyway 'cause I would've expected a file not found error if it was looking in the wrong place
JohnIdol
Maybe it's because Google App Engine checks access before looking for the file. Glad you found it!
duffymo
+1  A: 

I'm not sure about Google App Engine but in my experience the only solution that works across containers and platforms is to use ServletContext.getRealPath().

new File(servletContext.getRealPath("/WEB-INF/warChildFolder/myFile.txt"));

The spec says: use forward slashes and a leading slash. This gives you platform independence and you're not relying on the process' current directory.

sigget
A: 

I tried sigget's proposal - getting the relative path to a resourec through ServletContext and it works for Google App Engine, otherwise GAE throws an Exception - cannot get requested resource because of security constraints. Thanks!

moisko