RE: io path information in servlets
Howdy, OK, so my question - if I want to do this, where in the file system should I stick the xml file so it doesn't get overwritten if the war is redeployed? A user's home directory? That will force the user to mess with the configuration. I'm a out of my league on this, so I'd appreciate any advice. Of of course, I could give up on file storage and go with jdbc, but that seems like overkill for this little app I am writing. If you don't need the XML files to be persisted, you can read/write them from the context's temporary directory (javax.servlet.context.tempdir property). If you do need them persisted, you have some options: 1) Pass in an init-param to one of your servlets a directory where these files will be stored. 2) Use JDBC and write the files to a database. (This is not that bad a solution, especially if your schema is easy and the files aren't huge). 3) Use JNDI and have a bean or service persist the files for you. Good luck, Yoav Shapira Millennium ChemInformatics -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: io path information in servlets
On Thu, 18 Jul 2002, Will Hartung wrote: This all came out of the fact that it seems essentially impossible to create a webapp according to the 2.3 spec that uses file based storage and have it be usable out of the box with zero basic configuration to start up. For example, I don't think that there is a (portable) way for a servlet to change its own parameters. Say the webapp comes with some reasonable default for File pathnames, but a user wishes to change them. They cannot do that using the servlet itself (through some HTML Form/GUI mechanism), in a portable way. The approach I would use for this is to pass the default pathname as an env-entry in the web.xml file, and access it via JNDI calls in the servlet. Containers that support JNDI resources for webapps (which means Tomcat 4 plus every J2EE server in the world) provide mechanisms for the administrator to change the value of environment entries, either in a configuration file (like server.xml for Tomcat) or as part of the process of deploying the application, with zero changes to the WAR itself. The mechanism to do the configuration customizaton is not portable in the sense of being identical on every server, but it is available. Even with a databased app, there's no way for a servlet to change its default JDBC URL and persist that change, it has to be done through the configuration files or in the webapp itself. That's actually a good thing (changing it via configuration). Consider an environment with three servers (development, test, and production). Naturally, each is connected to a different database. The last thing you want to do is have to change JDBC strings in your webapp depending on which server you are deploying to. Using a resource-ref to declare a reference to a connection pool that is configured for you by the server administrator is much less tedious and error prone -- and you don't have to do anything at all to your application itself. JNDI resources are your friend. That would be a nice bit to concentrate on in the future I think. Best Regards, Will Hartung ([EMAIL PROTECTED]) Craig -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: io path information in servlets
From: Craig R. McClanahan [EMAIL PROTECTED] Sent: Wednesday, July 17, 2002 11:19 PM Subject: Re: io path information in servlets On Wed, 17 Jul 2002, Will Hartung wrote: It has CONVENTIONALLY been done this way, as it's a fairly obvious optimization to handle a web app (who wants to constantly grind through a jar file for crying out loud). However, what is convention, and what is specification are two completely different things. Be sure you run some benchmarks before complaining too loudly about constantly grind through a jar file. You will find, for example, that Tomcat will never do that more than once to load a class or JAR file, and for most static resources in the WAR it will also unpack them once and only once. In the very large majority of cases, whether a webapp is unpacked or not will have zero impact on performance for typical installations of Tomcat. Yes, this was a premature statement, and I didn't actually expect a container to literally continually access the files from the jar files. So, specifically, if you are relying upon the fact that getRealPath will give you a location that you can actually perform read/write file I/O upon, then you are relying on a Container specific behavior that MAY not be portable to other containers. A simple contrived example is that if you were deploying your WAR to, say, an Oracle Application Server, then Oracle can easily deploy the WAR into DBMS Tables and not use a file system at all, and this behavior is perfectly legal within the specification. (Mind you, I don't know what Oracle does. Like I said, a contrived example). As a matter of fact, Oracle has web containers that do exactly this -- funny thing, they run *faster* than the filesystem in many cases, because they take advantage of the DBMS's optimized I/O and caching capabilities :-). Yeah, it makes you wonder about things like Oracle's Internet File System. Another example is that your WAR may be deployed into a container where the webapp is exploded in an area where you may only have READ permission, and not WRITE. Also legal. It's actually a bit of a nit of mine that by specification, there is no guaranteed, portable way for a Servlet to get access to some writeable area for file I/O. It can be a parameter, say in the WAR, but the container itself is not guaranteed to have to deliver this kind of functionality to a Servlet. Not true. File workdir = (File) getServletContext().getAttribute(javax.servlet.context.tempdir); You don't get any assurances about the persistence of any files you store here, but this returns a perfectly useful directory for temporary files that you might need to create during execution of your business logic. (See section 3.7.1). Ah good! This is really necessary I think. I also like how they required that it contain File objects, thus you're able to get Streams and Writers as necessary. Pity about persistence, however. This all came out of the fact that it seems essentially impossible to create a webapp according to the 2.3 spec that uses file based storage and have it be usable out of the box with zero basic configuration to start up. For example, I don't think that there is a (portable) way for a servlet to change its own parameters. Say the webapp comes with some reasonable default for File pathnames, but a user wishes to change them. They cannot do that using the servlet itself (through some HTML Form/GUI mechanism), in a portable way. Even with a databased app, there's no way for a servlet to change its default JDBC URL and persist that change, it has to be done through the configuration files or in the webapp itself. That would be a nice bit to concentrate on in the future I think. Best Regards, Will Hartung ([EMAIL PROTECTED]) -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
io path information in servlets
I have a webapp that stores some data in an xml file. (I am using jdom to read and write the xml files.) Right now I am using a construct like: String prefix = sc.getRealPath(/) + /WEB-INF/dirName/; to get the path. I then concatonate that with the file name and it works fine. However, in the javadocs for javax.servlet I read: 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). I am not exactly sure what this means. If I deploy this application as a .war, does the sc.getRealPath stop working? Thanks Paul Phillips -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: io path information in servlets
From: Paul Phillips [EMAIL PROTECTED] Sent: Wednesday, July 17, 2002 5:20 PM Subject: io path information in servlets I have a webapp that stores some data in an xml file. (I am using jdom to read and write the xml files.) Right now I am using a construct like: String prefix = sc.getRealPath(/) + /WEB-INF/dirName/; to get the path. I then concatonate that with the file name and it works fine. However, in the javadocs for javax.servlet I read: 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). I am not exactly sure what this means. If I deploy this application as a .war, does the sc.getRealPath stop working? What it is refering to is the fact that there is nothing in the specification that says when a WAR is deployed into a server, that the WAR is actually exploded into something resembling a filesystem, much less something that you may actually have write access too (or, heck, even READ access for that matter). It has CONVENTIONALLY been done this way, as it's a fairly obvious optimization to handle a web app (who wants to constantly grind through a jar file for crying out loud). However, what is convention, and what is specification are two completely different things. So, specifically, if you are relying upon the fact that getRealPath will give you a location that you can actually perform read/write file I/O upon, then you are relying on a Container specific behavior that MAY not be portable to other containers. A simple contrived example is that if you were deploying your WAR to, say, an Oracle Application Server, then Oracle can easily deploy the WAR into DBMS Tables and not use a file system at all, and this behavior is perfectly legal within the specification. (Mind you, I don't know what Oracle does. Like I said, a contrived example). Another example is that your WAR may be deployed into a container where the webapp is exploded in an area where you may only have READ permission, and not WRITE. Also legal. It's actually a bit of a nit of mine that by specification, there is no guaranteed, portable way for a Servlet to get access to some writeable area for file I/O. It can be a parameter, say in the WAR, but the container itself is not guaranteed to have to deliver this kind of functionality to a Servlet. I think that for PORTABILITY, you should make the path that you save your XML file to be a ENV-ENTRY in the WAR, that, at least in TC 4, can be overridden by the Context that deploys the WAR. This gives the person deploying your application the control over where your webapp can write to its disk. For those containers that do not have the ability to override the ENV-ENTRY in the Context, they're stuck unpacking the WAR and fixing it there (so much for validating the integrity of your WAR buy signing it, though to be honest I don't know if the specification mentions anything about signed WARs). Which is another nit. Something like the ENV-ENTRY override needs to be standardized. Also, if you're writing stuff to the exploded webapp directory, then remember that it can go away if the container, for whatever reason, decided to redeploy your WAR. Basically, what you're doing with TC is probably fine, even semi-long term, but it's not portable behavior as documented in the specification. These limitations are not there specifically to screw up your code, they're in the spec to let the container developers have a lot more flexibility in how they build their containers. Best Regards, Will Hartung ([EMAIL PROTECTED]) -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: io path information in servlets
With Tomcat, normally when you deploy a .war file, it gets expanded and the context is run out of the directory created upon expansion, not the .war file itself. For intance if you put a myapp.war file in TOMCAT_HOME/webapps (and haven't defined the context in server.xml because, if defined, it doesn't expand for some reason...known bug...) Tomcat automatically extracts the contents of the .war file to a directory called myapp. Then the context is run from that directory. However, you can specify your appbase as the myapp.war file itself. Tomcat can serve your entire application out of the archive. Given this, myapp/WEB-INF is not on the file system. It exists ony iside the archive where no file IO is possible. So, a call to getRealPath/) will return null because there is no real system file path to be found. You can avoid this issue by always making sure to use your .war archive to distribute the app and make sure that the system is set up to expand the archive so the app is run out of a directory on the file system. Hope that helps. Jake At 07:20 PM 7/17/2002 -0500, you wrote: I have a webapp that stores some data in an xml file. (I am using jdom to read and write the xml files.) Right now I am using a construct like: String prefix = sc.getRealPath(/) + /WEB-INF/dirName/; to get the path. I then concatonate that with the file name and it works fine. However, in the javadocs for javax.servlet I read: 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). I am not exactly sure what this means. If I deploy this application as a .war, does the sc.getRealPath stop working? Thanks Paul Phillips -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: io path information in servlets
On Wed, 17 Jul 2002, Paul Phillips wrote: Date: Wed, 17 Jul 2002 19:20:00 -0500 From: Paul Phillips [EMAIL PROTECTED] Reply-To: Tomcat Users List [EMAIL PROTECTED] To: Tomcat Users List [EMAIL PROTECTED] Subject: io path information in servlets I have a webapp that stores some data in an xml file. (I am using jdom to read and write the xml files.) Right now I am using a construct like: String prefix = sc.getRealPath(/) + /WEB-INF/dirName/; to get the path. I then concatonate that with the file name and it works fine. However, in the javadocs for javax.servlet I read: 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). I am not exactly sure what this means. If I deploy this application as a .war, does the sc.getRealPath stop working? Yes; assuming that Tomcat doesn't unpack the WAR into a directory, this definitely stops working. In that case, getRealPath() will return null because there is no such thing as a real path to this resource path. Note that the ability to run an application from an unpacked directory at all is *not* a feature that the servlet spec requires -- the only requirement is to accept a WAR. If you want to do this kind of thing in a manner guaranteed to be portable, you should make your servlet accept an initialization parameter of some sort that identifies the directory in which output files should be stored. Thanks Paul Phillips Craig -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]
Re: io path information in servlets
On Wed, 17 Jul 2002, Will Hartung wrote: It has CONVENTIONALLY been done this way, as it's a fairly obvious optimization to handle a web app (who wants to constantly grind through a jar file for crying out loud). However, what is convention, and what is specification are two completely different things. Be sure you run some benchmarks before complaining too loudly about constantly grind through a jar file. You will find, for example, that Tomcat will never do that more than once to load a class or JAR file, and for most static resources in the WAR it will also unpack them once and only once. In the very large majority of cases, whether a webapp is unpacked or not will have zero impact on performance for typical installations of Tomcat. So, specifically, if you are relying upon the fact that getRealPath will give you a location that you can actually perform read/write file I/O upon, then you are relying on a Container specific behavior that MAY not be portable to other containers. A simple contrived example is that if you were deploying your WAR to, say, an Oracle Application Server, then Oracle can easily deploy the WAR into DBMS Tables and not use a file system at all, and this behavior is perfectly legal within the specification. (Mind you, I don't know what Oracle does. Like I said, a contrived example). As a matter of fact, Oracle has web containers that do exactly this -- funny thing, they run *faster* than the filesystem in many cases, because they take advantage of the DBMS's optimized I/O and caching capabilities :-). Another example is that your WAR may be deployed into a container where the webapp is exploded in an area where you may only have READ permission, and not WRITE. Also legal. It's actually a bit of a nit of mine that by specification, there is no guaranteed, portable way for a Servlet to get access to some writeable area for file I/O. It can be a parameter, say in the WAR, but the container itself is not guaranteed to have to deliver this kind of functionality to a Servlet. Not true. File workdir = (File) getServletContext().getAttribute(javax.servlet.context.tempdir); You don't get any assurances about the persistence of any files you store here, but this returns a perfectly useful directory for temporary files that you might need to create during execution of your business logic. (See section 3.7.1). I think that for PORTABILITY, you should make the path that you save your XML file to be a ENV-ENTRY in the WAR, that, at least in TC 4, can be overridden by the Context that deploys the WAR. This gives the person deploying your application the control over where your webapp can write to its disk. That's one reasonable way to do it. All J2EE containers, by the way, need to provide mechanisms for defining the values corresponding env-entry resources. For those containers that do not have the ability to override the ENV-ENTRY in the Context, they're stuck unpacking the WAR and fixing it there (so much for validating the integrity of your WAR buy signing it, though to be honest I don't know if the specification mentions anything about signed WARs). Which is another nit. Something like the ENV-ENTRY override needs to be standardized. It is ... across every J2EE container. Also, if you're writing stuff to the exploded webapp directory, then remember that it can go away if the container, for whatever reason, decided to redeploy your WAR. Basically, what you're doing with TC is probably fine, even semi-long term, but it's not portable behavior as documented in the specification. Well, there's always databases ... last I heard they are pretty good at long term storage :-). These limitations are not there specifically to screw up your code, they're in the spec to let the container developers have a lot more flexibility in how they build their containers. Best Regards, Will Hartung ([EMAIL PROTECTED]) Craig McClanahan -- To unsubscribe, e-mail: mailto:[EMAIL PROTECTED] For additional commands, e-mail: mailto:[EMAIL PROTECTED]