I wrote a desktop java application with a class (say ClassA) that reads the content of a file, processes it and returns some results. The filename was specified relative to the project using
File input = new File("config.xml");
Now, I want to upgrade the project into a web project. I wrote a servlet which calls the same java class (i.e. ClassA) for reading the content of the same file but this time I get an error message saying file not found.
How do I refactor my code so that both the desktop and the web versions run smoothly.
Just copy the file config.xml into the proper location on the web server e.g. public_html/www/
The "working directory" of a web application is different - depends on the configuration of the web server you are deploying it to.
If you read a file without specifying a path, it is read from the current dir, which you can access with System.getProperty("user.dir");
So you can try to find out what value is returned by System.getProperty("user.dir") in your web app and place the file there.
But this may differ depending on the environment and servlet server (Tomcat etc.) and may be not a reliable solution.
Another way is to change your code, so it reads the file from the user.home directory and place the file there.
Related
I am writing a Quarkus application which reads data over http. In my application.properties file, I have this line:
my.resource=http://path/to/file
Every time I run the app, it has to download the file so I created a smaller version of the file locally for developing purpose. The problem is that I don't know how to put it in the properties file.
Ideally, I want something like this:
my.resource=http://path/to/file
%dev.my.resource=file://${project-dir}/sample_data/file
And I have to use the absolute path because I used new URI(resource).toURL() method which requires an absolute URI.
Thanks in advance.
Application properties is something that is used when your application is deployed to adopt your application to the target environment, does the user of the deployed application know anything about project directory? Project directory is something that makes sense when you are developing your application. having said that using project directory in that file does not make sense at all.
I have a configuration project that few projects are using it.
All of my project under the same workingspace.
workingspace/configuration
workingspace/webapp1
workingspace/mongoDB
workingspace/model
mongoDB and the model project are using the configuration jar project and able to read the xml files using relative path ../configuration/conf/....xml
when using the
System.out.println("Working Directory = " +
System.getProperty("user.dir"));
inside both of them, I'm getting the correct path (workspace)
while trying to do it from the web app servlet i'm getting the folder of eclipse.exe that causing some problems.
How can i fix the user.dir defalte path for the web app?
At runtime, e.g. when you're not running from inside eclipse, you probably want to work in a defined directory as well - I'd suggest to explicitly configure a specific directory. When you're running within an appserver, you might run as an unpriviledged user that doesn't have a home directory writeable at all (when the account is properly administered with minimal permissions). This differs from applications that are launched ad hoc. In fact, you probably can't assume that your application server runs as the same user as your standalone apps do.
Another alternative is to utilize the system's temp directory - if these are truly temporary files. This could be assumed writeable, or complaints if it isn't do make sense.
I have created a dynamic web project, and use Apache Tomcat as a server.
In my servlet I'm creating a text file and want to reuse that in a JSP. However they are by default created in the installation folder of Eclipse when I do something as simple as the following:
File f = new file("test.txt").
I don't know why this happens. Is there a way to create the file in the WebContent directory as I want to make that file available for download in my JSP.
Java has a concept of the "current directory". When you start an application via Eclipse, this may indeed point to your installation directory. If you don't specify any path, a file will be created in this current directory. Hence the reason why your test.txt ends up there.
The WebContent directory is a something that is specific to Eclipse. Your code should not depend on putting anything there. You only start your application via Eclipse when you're developing it, not when you're deploying it to a live server.
The content of this directory will become the root of your .war, which is a well known location independent of how you start & deploy you app, BUT you still cannot depend on writing anything to this location at run-time. You might deploy your application as a packaged .war (likely for live deployments) or you may deploy your application unpackaged but then your application server may simply not pick up any changes done at run-time.
What you can do if you are sure your application only runs on a single server is writing the files to a well known location on your file system, such as /tmp, or /var/yourapp/files, etc. The code serving up those files can then pick them up from that location.
If you want to play it 100% safe according to the Java EE rules, you'd store your files on something like an FTP server that has a configurable address. Technically your war could be shipped between nodes on a cluster and requests could end up going to different machines, so depending on a local filesystem wouldn't work then.
Executing this statement this.getServletContext().getRealPath (""), you'll obtain the path where Tomcat WebServer is pointing at at runtime. You could add a folder "MyFolder" and call this statement:
new File(this.getServletContext().getRealPath ("") + "/MyFolder/test.txt");
Anyway, the default path looks something like:
...\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\<NameOfYourProject>
Note that when you create a new file, it won't appear in your immediate workspace (check the .metadata path), unless you change the runtime location tomcat should point at.
My development environment is windows, using JSP,Apache server 5.5. I developed an application with the help of geolitecity provided by MaxMind. I have uploaded geolitecity.dat into my server in the same folder of my website(I dont know its the correct procedure, I am doing it first time).And I used
String systemPath=new java.io.File(".").getCanonicalPath();
to get the current directory path, so that I can read from it. But I am not getting the full path. am only getting upto tomcat5.5.3\bin. Is it possible to read the file with this path? I dont have much knowledge in linux.
In Servlet/JSP:
String path = getServletContext().getRealPath("/yourfilename.txt");
This will give you complete path of given file name.
Note: It will work when you will deploy it in tomcat and run from out side eclipse. As eclipse has its own internal structure when it deploy the web application [if not changed].
I want to read a file from a java web application. I don't want to give the absolute path of the file. I just want to put the file in some directory of my web application.
Or
It can be placed along with .war file (packaged web application).
What relative path to give for the file. I tried ./filename.csv but it didn't work.
========Updated========
I will deliver a WAR file (packaged web application) to my client. This web application will read a file (lets say SuppliedFile.csv) which will be copied to the server by the client. So I need a mechanism (that will work irrespective of whether the application server will unpak the WAR or not) so that web application can read that file.
Note:
I am not using the SuppliedFile.csv in a servlet... I am using it in a plain Java class...
Do you really need to load it from a file? If you place it along your classes (in WEB-INF/classes) you can get an InputStream to it using the class loader:
InputStream csv =
SomeClassInTheSamePackage.class.getResourceAsStream("filename.csv");
You may be able to simply access a pre-arranged file path on the system. This is preferable since files added to the webapp directory might be lost or the webapp may not be unpacked depending on system configuration.
In our server, we define a system property set in the App Server's JVM which points to the "home directory" for our app's external data. Of course this requires modification of the App Server's configuration (-DAPP_HOME=... added to JVM_OPTS at startup), we do it mainly to ease testing of code run outside the context of an App Server.
You could just as easily retrieve a path from the servlet config:
<web-app>
<context-param>
<param-name>MyAppHome</param-name>
<param-value>/usr/share/myapp</param-value>
</context-param>
...
</web-app>
Then retrieve this path and use it as the base path to read the file supplied by the client.
public class MyAppConfig implements ServletContextListener {
// NOTE: static references are not a great idea, shown here for simplicity
static File appHome;
static File customerDataFile;
public void contextInitialized(ServletContextEvent e) {
appHome = new File(e.getServletContext().getInitParameter("MyAppHome"));
File customerDataFile = new File(appHome, "SuppliedFile.csv");
}
}
class DataProcessor {
public void processData() {
File dataFile = MyAppConfig.customerDataFile;
// ...
}
}
As I mentioned the most likely problem you'll encounter is security restrictions. Nothing guarantees webapps can ready any files above their webapp root. But there are generally simple methods for granting exceptions for specific paths to specific webapps.
Regardless of the code in which you then need to access this file, since you are running within a web application you are guaranteed this is initialized first, and can stash it's value somewhere convenient for the rest of your code to refer to, as in my example or better yet, just simply pass the path as a paramete to the code which needs it.
If you have a path for that file in the web server, you can get the real path in the server's file system using ServletContext.getRealPath(). Note that it is not guaranteed to work in every container (as a container is not required to unpack the WAR file and store the content in the file system - most do though). And I guess it won't work with files in /WEB-INF, as they don't have a virtual path.
The alternative would be to use ServletContext.getResource() which returns a URI. This URI may be a 'file:' URL, but there's no guarantee for that.
Many popular Java webapps, including Jenkins and Nexus, use this mechanism:
Optionally, check a servlet context-param / init-param. This allows configuring multiple webapp instances per servlet container, using context.xml which can be done by modifying the WAR or by changing server settings (in case of Tomcat).
Check an environment variable (using System.getenv), if it is set, then use that folder as your application data folder. e.g. Jenkins uses JENKINS_HOME and Nexus uses PLEXUS_NEXUS_WORK. This allows flexible configuration without any changes to WAR.
Otherwise, use a subfolder inside user's home folder, e.g. $HOME/.yourapp. In Java code this will be:
final File appFolder = new File(System.getProperty("user.home"), ".yourapp");
The alternative would be to use ServletContext.getResource() which returns a URI. This URI
may be a 'file:' URL, but there's no guarantee for that.
You don't need it to be a file:... URL. You just need it to be a URL that your JVM can
read--and it will be.
there is another way,
if you are using a container like Tomcat :
String textPath = "http://localhost:8080/NameOfWebapp/resources/images/file.txt";