Locating a file from servlet using a relative path

Michael Mendelson

Ranch Hand

Posts: 73

posted 16 years ago

Hi! I'm running Tomcat, and would like my servlet to locate a file (for reading) which lives in the same directory as the servlet. This works fine when I run the class as a non-servlet, but when I deploy as a servlet, the file cannot be found. If I use the complete path, it works fine. Why is this happening, and how can I fix it? I would rather not hard-code an absolute path into my app. Here's that code, in the interest of full disclosure:

Thanks, team!

William Brogden

Author and all-around good cowpoke
Rancher

Posts: 13078

6

posted 16 years ago

That usage requires that the JVM's "current directory" be the WEB-INF/classes directory so it obviously can't work. I like to pass a "working directory" to servlets in the initialization parameters, then you can address resources such as your ini file relative to that directory. This avoids hard coding a directory path. Bill

Michael Mendelson

Ranch Hand

Posts: 73

posted 16 years ago

Thanks Bill! It seems that for Tomcat, this is done by editing the WEB-INF/web.xml file. I'll look into it!

maha anna

Ranch Hand

Posts: 1467

posted 16 years ago

Michael, Yes. We need to modify the ../WEB-INF/web.xml file and in Servlet's init(..) method get the value of the init parameters. A related discussion :http://www.javaranch.com/ubb/Forum7/HTML/001790.html regds maha anna [This message has been edited by maha anna (edited April 20, 2001).]

Michael Mendelson

Ranch Hand

Posts: 73

posted 16 years ago

I have been having trouble getting InitParameters to work, though. Even Maha's example, the SnoopServlet that comes with Tomcat, doesn't seem to return anything, even after I uncommented the lines in the XML file. This should be very straight-forward. Am I missing something? Another thing - I assume that it is also possible to use getInitParameter("name") in the doGet method, instead of using init?

maha anna

Ranch Hand

Posts: 1467

posted 16 years ago

Michael, I made a small test for you. We can get the init params. I used two params 'Name' and 'Forum' with values 'Michael' and 'Servlet and JSP' in ROOT/web-inf/web.xml file and when we invoke the snoopservet like http://localhost/servlet/snoop it prints the following in browser. Please check and let us know the results.

[This message has been edited by maha anna (edited January 20, 2001).]

Michael Mendelson

Ranch Hand

Posts: 73

posted 16 years ago

Anna, thanks for posting that test. I went ahead and set it up. My results were not encouraging:

I know that web.xml is being parsed correctly, because it took a few tries. Web.xml is located in d:/java/code/Basic/WEB-INF/ I set the servlet up in a project called /basic. Here's its entry in server.xml:

Perhaps there's something strange about this definition. Other than that, I'm stumped! Perhaps it's something about the way Tomcat is set up...

7. Edit c:\jakarta-tomcat\conf\server.xml file and add the foll at end of the file. Also note that c:\ is the dir where I installed timcat 3.1 Basically you have to edit ..\conf\server.xml file. So take care of this.

8. Now load the server fresh from dos prompt 9. From any browser type this.

[In my previous post I said as http://localhost/servlet/snoop because I use the 80 (http) port and called invoked the SnoopServlet from ..root/WEB-INF/classes dir.So don't confuse with this. If you are using the default 8080 port STEP 9 will work. ] 10. You will get the output as following with 'Snoop Servlet' in BIG LETTERS.

Don't give up! Try it. Let's find out what's missing! regds maha anna

[This message has been edited by maha anna (edited January 23, 2001).]

Michael Mendelson

Ranch Hand

Posts: 73

posted 16 years ago

OK Maha, I finally figured it out! Of course, it was something simple. I was accessing the servlet by its default name, http://localhost/basic/servlet/SnoopServlet, rather than by its mapped name (defined in WEB.XML), http://localhost/basic/snoop. So the program was running, but those parameters were not coming through. Can you duplicate this? Being new to this game, I didn't imagine that there was a difference. So now my big question is WHY? Can you shed any light on this? Does Tomcat work this way by design? Thanks yet again for your help.

maha anna

Ranch Hand

Posts: 1467

posted 16 years ago

What are you getting in browser ? 404/500 (status codes)error? or blank page? Why are you giving http://localhost/basic.... instead of http://localhost:8080/basic.... ? Did you edit the c:/jakarta-tomcat/conf/server.xml file to modify the port from 8080(the default) to 80(http port)? If the port is 80, then we can omit the port number when we call from browser. Example :http://localhost/basic/snoop Did you do all the steps same as above? Regarding your question, web.xml's configuration takes precedence over the plain .../basic/servlet/SnoopServlet format. In other words, the container tries to map like this. 1. url pattern defined in web.xml matches or not 2. any servlet name matches with your browser url's servletname 3. if no match at all in web.xml, then the default ../basic/servlet/SnoopServlet will be invoked. In this case no way to send init params. Did you edit c:/java/code/basic/WEB-INF/web.xml file and put the entries which I showed in previous post? regds maha anna regds maha anna

All the stuff you suggested to do worked fine. My only problem was that I was invoking the servlet in the way I outlined above. Thanks, Michael

[This message has been edited by Michael Mendelson (edited January 28, 2001).]

Frank Carver

Sheriff

Posts: 6920

posted 16 years ago

This is deliberate behaviour. Imagine you have several "applications" each based on the same servlet (say a general purpose membership list servlet in use for a number of different clubs) You need to be able to set up the different servlet mappings so that they each get different initialization parameters:

Running a servlet via /servlet/ClassName is really just a special case defined as having no initialization parameters, so you don't have to set up the container if you don't need to. It's good practice to write your servlet to supply default values in case any of the parameters aren't supplied, so this then becomes a perfectly valid way of calling your servlet.

Thanks Frank for your reply. Now it all makes sense. Besides, I was beginning to think this was just a running dialogue between myself and Maha! This gives me hope that someone else might benefit from my learning curve! Since I have the attention of at least two moderators of this forum, You're Doing a Great Job! With way over 1000 posts apiece, I'm amazed that either of you find time to actually work! Thanks.