my dog learned polymorphism*
The moose likes Servlets and the fly likes Issue w/ accesing file from a Servlet Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "Issue w/ accesing file from a Servlet" Watch "Issue w/ accesing file from a Servlet" New topic
Author

Issue w/ accesing file from a Servlet

M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Hello, I am trying to use a servlet to access a file called conf.xml. This is used to initialize the JPreference classes I am testing.

The servlet is using the servlet context's getRealPath() to find the location of the file: <web-app>/web/config/conf.xml. If it makes a differences, the web-app is running from a set of binaries configured as a context within the servlet container and not deployed as a war.

For some reason, it doesn't seem like the servlet is accessing the conf.xml. However, I am not gettting a FileNotFoundException either.

I am inlcluding my code at the bottom of this post. If this question is better suited for the Apache/Tomcat, Open Source Tools, or some other forum, please accept my apologies for posting here. I feel like it is a servlet issues having to do with accessing files, but maybe it is something specific to JPreferences or Tomcat.

Thanks!



The result is always "No name was supplied".
Byron Estes
Ranch Hand

Joined: Feb 21, 2002
Posts: 313
I guess I'd start by issolating this statement...

webContext.getRealPath( "config\\conf.xml" )

...and sending the returned value to System.out to see what it was passing.

Based upon the error text it does not appear that statement is resolving the absolute addreess associated with the string you provided. Is it possible that the virtual path you provided does not exist in your app server?


Byron Estes<br />Sun Certified Enterprise Architect<br />Senior Consulant<br />Blackwell Consulting Services<br />Chicago, IL<br /><a href="http://www.bcsinc.com" target="_blank" rel="nofollow">www.bcsinc.com</a>
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Thanks for the response. Here is the output for the real path:


When I add a BufferedReader to read and display the file contents, it is able to show me everything. When I try to access a value from the key defined in the XML for JPreferences, it acts like I can't. This may be a preferences BackingStore issue. Do you happen to know if I need to configure preferences differently for a web-context v. stand-alone. The code works in stand-alone app.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

The getRealPath function only works if you are running the app from an exploded file system.

Use ServletContext.getResourceAsStream if the file bundled with your webapp.
If not, configure the path as a servlet or context init-param and set it to a full absolute path.


Java API J2EE API Servlet Spec JSP Spec How to ask a question... Simple Servlet Examples jsonf
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Also, you would never use a backslash "\" as a file delimiter with either getRealPath or with getResourceAsStream.

http://java.sun.com/j2ee/1.4/docs/api/javax/servlet/ServletContext.html
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Ok, so are you saying that in using getRealPath(), I would always pass a string representing a single resource (e.g. "conf.xml instead of "config/conf.xml")? If that is the case, all of the resources would have to be stored in <<web-app>>/web, correct?

In the end, what I would like to acheive is a conf.xml file accessible only to the app and not the browser. I don't want clients hitting http://blah/conf.xml and seeing all of the preferences. So I may be setting this up wrong to begin with since I am storing it in my application under <<web-app>>/web/config.xml. Maybe it should be moved to WEB-INF somewhere.

Also, I don't want to retrieve the resource by making an external http request to get it either. I just want to point the location locally via an application relative path or absolute if there is no alternative.

If I use the getResourceAsStream() and create a new File() from the result, and then use that file to create my XmlStore(), I should be golden, right? That method will give me access from a servlet to any file in the app or server file system (assuming proper rights).

Am I getting warmer?
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Originally posted by M Kozelek:
Ok, so are you saying that in using getRealPath(), I would always pass a string representing a single resource (e.g. "conf.xml instead of "config/conf.xml")? If that is the case, all of the resources would have to be stored in <<web-app>>/web, correct?

Yes, a virtual path with '/' being the root of your webapp.


In the end, what I would like to acheive is a conf.xml file accessible only to the app and not the browser. I don't want clients hitting http://blah/conf.xml and seeing all of the preferences. So I may be setting this up wrong to begin with since I am storing it in my application under <<web-app>>/web/config.xml. Maybe it should be moved to WEB-INF somewhere.

Yes, I would put it under WEB-INF and access it with:
getServletContext().getResourceAsStream("/WEB-INF/myFile.xml");


Also, I don't want to retrieve the resource by making an external http request to get it either. I just want to point the location locally via an application relative path or absolute if there is no alternative.

You won't need to.


If I use the getResourceAsStream() and create a new File() from the result, and then use that file to create my XmlStore(), I should be golden, right? That method will give me access from a servlet to any file in the app or server file system (assuming proper rights).
Am I getting warmer?

getResourceAsStream is for files within your webapp.
You would need to use new File(..) for files on the file system that are not within your webapp.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

If I use the getResourceAsStream() and create a new File() from the result, and then use that file to create my XmlStore(), I should be golden, right? That method will give me access from a servlet to any file in the app or server file system (assuming proper rights).
Am I getting warmer?


You shouldn't need to go through the extra step of converting the stream to a file. Just parse the stream.

SimpleStream at http://simple.souther.us is an example that uses getResourceAsStream to access a file hidden behind WEB-INF
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
I'm actually confused on your servlet. I'm not seeing how the image is streamed to the webpage unless that href is just inserting those bites as a image right then and there since it is a mapping to the servlet and the servlet just returns that stream. I like that approach, though. I'll have to mess around with that.

Please help bridge the gap here then. So I can get the file from behind WEB-INF as long as it is in bytes. However, I the JPreferences API creates the XML file store using the following methods:


Both of these are just string represenations of the path (which is the reason I was trying to use an real/absolute path).

So even if I get the buffered stream back, I'm not sure I can leverage it.

Feeling stuck...

http://my.unidata.ucar.edu/content/staff/caron/prefs/javadoc/index.html
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Originally posted by M Kozelek:
I'm actually confused on your servlet. I'm not seeing how the image is streamed to the webpage unless that href is just inserting those bites as a image right then and there since it is a mapping to the servlet and the servlet just returns that stream. I like that approach, though. I'll have to mess around with that.

That is what it's doing.


Please help bridge the gap here then. So I can get the file from behind WEB-INF as long as it is in bytes. However, I the JPreferences API creates the XML file store using the following methods:


Both of these are just string represenations of the path (which is the reason I was trying to use an real/absolute path).

So even if I get the buffered stream back, I'm not sure I can leverage it.

Feeling stuck...

That's all they give you?
Nothing that takes a stream?

You could write the file to the tempdir and read it from there.
It seems kind of lame that you can't pass a stream to that class.
Do you have a link to the API?


http://my.unidata.ucar.edu/content/staff/caron/prefs/javadoc/index.html[/QB]
I work in a unidata shop.
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Ahh, scratch that. It seems we are using an older library and I was totally ignoring the method description right there in the API online. I downloaded the source files and see that there is a way to create the Xml store from a stream. Testing it out now.

Jeepers...
[ May 11, 2005: Message edited by: M Kozelek ]
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Okay, I am still testing the inputstream, but it's still not working:

For the code:



This is the result:

Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

XMLStore userStore = XMLStore.createFromInputStream( in1, in2, null );

What is it looking for in that argument list?
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Here is the method implementation from the source file:

Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Did you try it without reading the bytes from the beginning of th stream to do the println statments?



I don't fully understand why it wants two copies of the same stream.


(different Unidata (I was thinking about the IBM database)).
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
No I haven't tried that. To be honest I don't event know how and would have to spend some time looking that up so I don't end up stuck there as well.

As far as why they need those two instances, here is the private implementation of the method:

Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Looks like they DO want two copies of the same stream..

I meant something like this:
balasg jothi
Greenhorn

Joined: Sep 06, 2004
Posts: 6
Hi,

Its very simple to access a XML file from Servlet.

Use env entry in Web.xml and put the evn value and access the env entry using InitialContext Object

If you want code snippet let me know

Thanks
Bala L
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Thanks, Balasg. A code snippet would be great. It's been a while since I've worked with the servlet context stuff and I've been pulled away to focus on something else, but will have to resolve this at some point.

In the meantime, I will try to get back up to speed on how the container lets you leverage all the environment setup.

Thanks again!!!

mk
balasg jothi
Greenhorn

Joined: Sep 06, 2004
Posts: 6
Hi,

Add the following entry in Web.xml and restart the server

<env-entry id="EnvEntry_1">
<env-entry-name>ConfigFile</env-entry-name>
<env-entry-value>/export/home/bala/test.xml</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>

and use the following code in ur servlet.

javax.naming.Context context = new javax.naming.InitialContext();
String initialConfigFile = (String) context.lookup ("java:comp/env/ConfigFile");

Thats it

Thanks
Bala L
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Originally posted by balasg jothi:
Hi,

Add the following entry in Web.xml and restart the server

<env-entry id="EnvEntry_1">
<env-entry-name>ConfigFile</env-entry-name>
<env-entry-value>/export/home/bala/test.xml</env-entry-value>
<env-entry-type>java.lang.String</env-entry-type>
</env-entry>

and use the following code in ur servlet.

javax.naming.Context context = new javax.naming.InitialContext();
String initialConfigFile = (String) context.lookup ("java:comp/env/ConfigFile");

Thats it

Thanks
Bala L


That just returns a string.
The issue at hand is how to read a an XML file that may or may not exist as
a file on the file system. In this case it's not. It's packed in a war file binary. That is what getResource and getResourceStream are designed to handle. They return the same results either way.
[ May 13, 2005: Message edited by: Ben Souther ]
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Actually, I may not have been as clear as I should have. The project is not deployed as a war. It is external to Tomcat and Tomcat is using the binaries from a context I set up in:

C:\Program Files\Apache Software Foundation\Tomcat 5.0\conf\Catalina\localhost\myapp.xml.

Don't know from a container perspective if that changes anything. The file is still stored in the WEB-INF/config/conf.xml.

The developer of the API I am using thinks the code looks right but wants me to make sure that the two inputstreams are non-null. Since I was using a reading line by line to the console, that tells me that it is not non-null, but maybe I misunderstand I/O.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

OK, I misunderstood. I thought you were running from a war file when you said from 'binaries'.

In that case you can just set the path to the xml file with either the env option as listed above or you can use simple servlet or context init-params.

I have examples of both at http://simple.souther.us

If you ever plan on running this from a packed war file, you would need to place the xml file somewhere outside of the web app to access it this way.
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
So what is the difference between storing the path in the env-context and just giving it a hard-coded path.

I've tried hard coding it just to get there, but that doesn't return a stream either. The input stream is always null.

Does putting the path in the serlvet context somehow manipulate permissions to the file as well that normally wouldn't be there by just passing a path as a string? The end result of either approach is a String value representing the path anyway, right?

I can't believe how hard I'm making this.
Ben Souther
Sheriff

Joined: Dec 11, 2004
Posts: 13410

Is the xml file an actual file sittig on your hard drive?
Could you use that hard coded path to open it with a text editor?

Or..

Is it inside a war file?
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
I am running this application off the binaries in a expoleded format external the tomcat program. In a totally other location on my local hard drive. The only relationship between my files and tomcat's is the context xml that points tomcat to my classes.

The conf.xml is a physical file located on my local file system. I am manipulating it in Netbeans, running tomcat from netbeans, and debugging from the IDE as well.

I have tried to access this physical file in every way I know how so at this point I'm at a loss. The debugger is now showing that the classes are not null, but they don't have any real state either. Just the default initial values.
M Kozelek
Greenhorn

Joined: Feb 08, 2005
Posts: 21
Ok, here is my latest attempt and the output. I'm using a FileInputStream because it doesn't return null like the InputStream alone does.



The result is the following:



Is there something here that I am missing? It seems I can get to the file and write it's content out, but I can't do anything else.
 
 
subject: Issue w/ accesing file from a Servlet
 
Similar Threads
my servlet can't initialize: null
Logging Problem with unpackWARs="false"
object required in java script error
Cannot access a servlet from a Java application
Preferences API