Apache Tomcat - Access Files Outside Webroot - java

I had deployed an application in the application server Apache
Tomcat. My GWT application needs to access files in folder "C:
\Storage". In development mode the application runs like a charm but
in an external web server (Apache Tomcat) it does not run, crashes
when it tries to copy files from "C:\Storage" to "\docs". I think this
might be because i'm trying to access files outside the webroot. How
can i solve this situation? Using apache commons libs to deal with
files? Could be permissions? I need some enlightment, some help will
be very apreciated.
Thanks in advance,
João Cavaleiro.

Another (wild) guess: if you deploy wars without unpacking as real files, getRealPath("/doc") will return null. (You have no files inside a war). So you have to configure Tomcat:
http://tomcat.apache.org/tomcat-5.5-doc/config/context.html
upackWAR = true

Thanks you all for the replies. I actually figured out what the problem was: Paths.
"\docs" is the folder located in the root of the app.
Unfortunately Apache didn't wrote any exception on catalina.out log (the code catch the exceptions ocurred).
Simply i didn't create a new File(pathname) with the absolute path of the destination location, i was using only the "docs/filename.txt" assuming that the File classe would recognize the full path, "knowing" the location in the filesystem of the app. I assume that this is a situation to keep in mind with sepecific application servers because with eclipse/Jetty it works but with Apache Tomcat don't (I am developing a GWT application).
But in the matteer of fact, the debbug was not easy, the debbug mode with external server didn't work in the server side in the peace of code where i it's needed to do this io operations strange), and the System.out.println that i managed to help me figure out the problem didn't show up in the catalina.stdout (strange to and yes, i have compiled and deployed it on the Apache Tomcat with that modifications twice).
Thanks to everyone.

Related

Java FileNotFoundException when using Apache Tomcat

I have a Java application which runs on an Apache Tomcat server. The Java application is a web service.
From within one of the Java classes I try to access a file, however the following section of code throws a FileNotFoundException.
DataModel dm = new FileDataModel(new File("data/WheelChairData.csv"));
However if I run this Java application without using the server, I don't get the error message which means that it's apache that's not be able to find it. So where can I store the file WheelChairData.csv so that the server can find it ? is it possible to store it within Apache Tomcat, if so can you please point me in the right direction
Thank you.
Use this line and see where the path is:
System.out.println(new File(".").getAbsoluteFile());
(or if you are using logger, put output into it)

getting eclipse project absolute path (in web application using tomcat server)

i'm trying to get the absolute path of my eclipse project :
so i write this;
File file= new File("");
System.out.println(file.getCanonicalPath());
projectPath=file.getCanonicalPath();
so it gives me the right path when i execute it in a class as java application C:\Documents and Settings\Administrateur\Bureau\ready code\JavaServerFacesProject
But when i try to use it in my web application it gives this :
C:\Documents and Settings\Administrateur\Bureau\eclipse\eclipse
So any idea how to do it
Many thanks
Reading a file from a web application is a classical pitfall, whenever you do this you will suffer.
Web apps (especially Java EE) are not thought out to use the file-system for read/write operation, they rely on the fact that the container (in your case Tomcat) knows how to get the needed resources.
So the basic advice is : don't do it.
But since I basically hate this kind of answers I will give you some advice.
Never use the working directory
You never know where your working directory is, and, more often then not, in any production system, the web-app has no right to write on the working directory.
For example, if you deploy your webapp to a tomcat server, run as a service on a windows machine, you'll find that your working directory is \Windows\System32
You really don't want to write some uploaded files there for example...
You have a few option, what I prefer is to set a path into the web-xml and possibly override it from server configuration (using context).
Second option, even better is, to save a path into a db-table accessed by the web app.
ex:
in the web.xml you set
<context-param>
<description>Uploaded files directory</description>
<param-name>file-storage</param-name>
<param-value>c:\app\storage\uploaded</param-value>
</context-param>
Then in the you server.xml (or you could use the context dir and place there a file with the following code) you override this setting in context.
<Context
<Parameter
name="file-storage"
value="E:\app\storage\uploaded"
type="java.lang.String"
override="false" />
</Context>
Check tomcat documentation
Third option, in the slightly happier situation, you want to write just some temporary file, there is the webapp working dir accessible as a servlet context param named :
javax.servlet.context.tempdir
If I where you I would go for the database table.
All this complexity is because you can have multiple instance of the same app on different instances of tomcat, even on different machines, and even different web application into the same instance, so there is no easy way to make a 'relative' path is all situations.
Most web-app resolve to serialize data on db (using lobs or similar objects), whenever there is such necessity, or to rely on some kind of service (FTP, cifs, nfs ...).
In Eclipse, you can set a Working Directory for your project in the Run Configurations dialog.
Have you tried setting a non-default one there?
(If you cannot set anything, you could try the JVM option suggested here: https://stackoverflow.com/a/7838900/1143126 )

Tomcat Deploying 2 Projects

I have a requirement that I need to use a single server machine to run 2 totally different applications.
The server machine has Apache Tomcat 6.0 installed. 1 of the applications is deployed on it and is running successfully for a long time. Initially, the clients used to connect to it by invoking the url "http://machine-name/1stProjectName/initialPage". I have also mentioned the "initialPage" as the Welcome Page in web.xml of this project. But somehow, later some ports or relating things were changed by the server maintenance team, and to connect to the application, now one has to use the url "http://machine-name" or "http://machine-name/initialPage", i.e. the machine name has started behaving like the project name folder because now if I invoke the url "http://machine-name/1stProjectName/initialPage", it gives 404 error saying that "/1stProjectName/1stProjectName/initialPage" resource not available.
Now, when I deploy the WAR of the second application into the webapps folder of Tomcat (just like I did for the first application), it unpacks it properly. But, the issue is how do I connect to this second project. If I use "http://machine-name", it takes me to the 1st application and if I use "http://machine-name/2ndProjectName/initialPage", it gives me an error that "/1stProjectName/2ndProjectName/initialPage" not available.
Kindly help or guide me in some direction.
Thanks in advance.
Your URLs should look like this if you did things properly:
Project 1: http://host:port/war-name-1
Project 2: http://host:port/war-name-2
That means no changes to content.xml to modify the path.
I would talk to your "server maintenance team" and let them know what you are trying to do (since they are the ones who made these changes in the first place). But it sounds to me that they just mapped a path to a specific location, that is your machine-name root is mapped to 1stProjectName.

Deploying an identical war file with a different name causes the old one to stop?

We have an Apache tomcat server that runs a current web service. We were trying to deploy a second version (with a few tweaks) however when we copy the war file over, the first one stops working. Why??
Does your webapp contain context.xml configuration for Tomcat? If the two webapps use the same docbase then they are accessing the same folder.
If your application writes to a database, and another copy of it is competing for the same data in the same database, this can result in such behaviour. Does your application write to a "fixed" database? If so, you will need to create another database, or change the way the application deals with the database.
Is the Context root different in the war files. If not I believe the server will not validate the url correctly.

Is it possible to read a properties file from all .war files deployed in a JBoss container

I've managed to deploy a .war to the Jboss web container containing and read the pom.properties located under /META-INF/groupid-dir/artifactid-dir/
To access the file I've used the following code inside a JSP in the same war:
ServletContext servletContext = getServletConfig().getServletContext();
InputStream in = servletContext.getResourceAsStream("META-INF/maven/groupid-dir/artifactid-dir/pom.properties");
This works just fine. But I want to be able to dynamically read pom.propertes from ALL .war deployed in the container. Is this possible or do I only have access to the context for the one war holder my jsp?
-mb
Basically, your application is running on the same machine as the JBoss container, so accessing the files on the local filesystem should be possible, much in the same way you're accessing your own .properties file. I'm not familiar with anything that should prevent you from doing this.
If you want to access files within the war file, you'll need to use the java.util.zip package, as war files are of course normal zip files. Just a friendly reminder.
You will likely have to do something tricky like go through the JBoss MBeans. I realize this is vague, but consider looking into that approach. Here is a link on how to get the MBean server from an application within JBoss (add http://) www.jboss.org/community/wiki/FindMBeanServer (Stackoverflow is preventing me from pasting a link). I would imagine that you could find the Jboss Web mbean, peel off all web application mbeans, then ask each one for its classloader, then proceed to do what you already mentioned.
I don't think that reading a zip or using a jboss mbean are the right way.
I don't think it is tricky and you were on the right track by using ServletContext.getResourceAsStream.
You can probably use ServletContext.getResourcePaths, but several times it seems, to identify subdirectories groupid and artifactid.
Something like
servletContext.getResourceAsStream(servletContext.getResourcePaths(
(String) servletContext.getResourcePaths("/META-INF/maven/")
.iterator().next())
.iterator().next() + "pom.properties")
or
servletContext.getResourceAsStream(servletContext.getResourcePaths(
(String) servletContext.getResourcePaths("/META-INF/maven/")
.iterator().next())
.iterator().next() + "pom.xml")
for pom.xml
If the WAR file is exploded as folder , you should be able to use
String basePath=getServletContext().getRealPath("/");
This approach may not work if WAR file is in archive format
You can only look for resources in your current classpath. The normal operation of a web container is to create a specific classpath for each deployed artifact without access to the other artifacts deployed in the container.
This is very important to avoid artifact A which uses foo-1.0.jar to not accidentially use foo-0.9.jar which is deployed with artifact B.
Hence you will need ask the container for help. This in turn mean you need to write container specific code to do so. This will make you vendor dependent - you may not want that.

Categories