File object not working in Java Web App - java

I have a simple java class in my web application in which i have written the below code but its not working
File test= new File("/templates/xmdForModel.xsd");
templates folder is inside the root folder of the application.
the location of the file is ----> application-root/package/test.java
location of the file is --------> application-root/testRoot/template/xmdForModel.xsd
Error
Failed to read schema document 'file:/templates/xmdForModel.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not .

If you want to look up the file name for files inside of your web application, you can use ServletContext#getRealPath.
However, I would recommend loading your resources using the classloader with Class#getResourceAsStream. This way, it even works if the file does not really exist as a file (for example only inside of a jar).
If this is a file that a user is supposed to edit (or that you write to), I would place it outside of the web application, and then specify an absolute path (for example "/etc/myapp/conf/xmd.xsd") with a configurable prefix.

Path in the File constructor can be absolute or relative. When you start the path with '/' (in a linux based os), it is going to consider that path as an absolute path and create a file/folder in the root of your file structure (not in the root of the project). It will be like specifying c:\templates in windows machine.
Try removing the first slash and running your program. Removing first slash will make the part relative from your .java file. So you can use ../ to switch to parent folder.
java: application-root/package/test.java
file: application-root/testRoot/template/xmdForModel.xsd
So from your java file you will need to change directory to application root folder and then select template folder. Like following.
File x = new File("../testRoot/template/xmdForModel.xsd");
src:http://docs.oracle.com/javase/tutorial/essential/io/path.html
/home/sally/statusReport is an absolute path. All of the information
needed to locate the file is contained in the path string.
A relative path needs to be combined with another path in order to
access a file. For example, joe/foo is a relative path. Without more
information, a program cannot reliably locate the joe/foo directory in
the file system.

Related

How to Set a Path to Create Directory

This question header isn't the best, but I am trying to create a directory from the person's computer in java, then when a button is clicked, to navigate to that created directory and create a file. I just need to get the path then create the directory. Here is a sample:
File theDir = new File("Users/" + System.getProperty("user.name") + "/InfoSaveFiles");
if (!theDir.exists()) {
if (theDir.mkdirs()) {
}
}
The only problem is that when I run this, (from a compiled jar file or from my IDE), it just creates a directory Users/(name)/InfoSaveFiles instead of navigating to that particular path and creating the directory InfoSaveFiles as I would like.
How can I make it go to the specified path, then create the directory?
If you want to are using that file path, it will look for Users/(name)/InfoSaveFiles in the present working directory, in case of IDE, the root of the project file. So, if you add a slash / before it, like '/Users/(name)/InfoSaveFiles`, then it will look for the hierarchy from the root of the current heirarchy. In case of windows, from the drive you're running the program.
For example, if you set the file path with slash before it and you're running the program in the E:// drive, then the program will look for Users/(name)/InfoSaveFiles in that drive, and will create the hierarchy if not exists.
So, if you want to do that in specific drive, you need to mention that too at the front of that file path.
For Linux, starting with / indicates the root directory. So you can achieve it in linux giving the current file path you've mentioned with an added / in the front. It will look for that path from the root directory then.
Hope that answers your question.

Using relative path in a maven project

I have a maven project with these standard directory structures:
src/main/java
src/main/java/pdf/Pdf.java
src/test/resources
src/test/resources/files/x.pdf
In my Pdf.java,
File file = new File("../../../test/resources/files/x.pdf");
Why does it report "No such file or dirctory"? The relative path should work. Right?
Relative paths work relative to the current working directory. Maven does not set it, so it is inherited from whatever value it had in the Java process your code is executing in.
The only reliable way is to figure it out in your own code. Depending on how you do things, there are several ways to do so. See How to get the real path of Java application at runtime? for suggestions. You are most likely looking at this.getClass().getProtectionDomain().getCodeSource().getLocation() and then you know where the class file is and can navigate relative to that.
Why does it report "No such file or dirctory"? The relative path should work. Right?
wrong.
Your classes are compiled to $PROJECT_ROOT/target/classes
and your resources are copied to the same folder keeping their relative paths below src/main/resources.
The file will be located relative to the classpath of which the root is $PROJECT_ROOT/target/classes. Therefore you have to write in your Pdf.java:
File file = new File("/files/x.pdf");
Your relative path will be evaluated from the projects current working directory which is $PROJECT_ROOT (AFAIR).
But it does not matter because you want that to work in your final application and not only in your build environment. Therefore you should access the file with getClass().getResource("/path/to/file/within/classpath") which searches the file in the class path of which the root is $PROJECT_ROOT/target/classes.
No the way you are referencing the files is according to your file system. Java knows about the classpath not the file system if you want to reference something like that you have to use the fully qualified name of the file.
Also I do not know if File constructor works with the classpath since it's an abstraction to manage the file system it will depend where the application is run from. Say it is run from the target directory at the same level as source in that case you have to go one directory up and then on src then test the resources the files and finally in x.pdf.
Since you are using a resources folder I think you want the file to be on the classpath and then you can load a resource with:
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("<path in classpath>");
Then you can create a FileInputStream or something to wrap around the file. Otherwise use the fully qualiefied name and put it somewere like /home/{user}/files/x.pdf.

Sharing a Java Object Stream

I've got a project to do with 2 other classmates.
We used Dropbox to share the project so we can write from our houses (Isn't a very good choice, but it worked and was easier than using GitHub)
My question is now about sharing the object stream.
I want to put the file of the stream in same dropbox shared directory of the code.
BUT, when i initialize the file
File f = new File(PATH);
i must use the path of my computer (C:\User**Alessandro**\Dropbox)
As you can see it is linked to Alessandro, and so to my computer.
This clearly won't work on another PC.
How can tell the compiler to just look in the same directory of the source code/.class files?
You can use Class#getResource(java.lang.String) to obtain a URL corresponding to the location of the file relative to the classpath of the Java program:
URL url = getClass().getResource("/path/to/the/file");
File file = new File(url.getPath());
Note here that / is the root of your classpath, which is the top of the directory containing your class files. So your resource should be placed inside the classpath somewhere in order for it to work on your friend's computer.
Don't use absolute paths. Use relative paths like ./myfile.txt. Start the program with the project directory as the current dir. (This is the default in Eclipse.) But then you have to ensure that this both works for development and for production use.
As an alternative you can create a properties file and define the path there. Your code then only refers to a property name and each developer can adjust the configuration file. See Properties documentation.

Getting XML file not in the same root as the source file in Java

I have a problem where I can't seem to link to a xml file, see the layout below:
Folder Name
-Folder
-Folder
-SourceFiles
-packagename
-all my java files
-myXml.xml
Build is where all the class files etc is stored.
src is where the projectFolder is, and within it the java files
Code I am using to link XML File for Synth: SynthDialog.class.getResourceAsStream("synthtest/synthDemo.xml")
Now I want to link to the myXML.xml file in the top-level folder. It would be the PHP Equivelent of ../../Folder/
Thanks
You appear to be attempting to access the file using getResourceAsStream with a relative name. If that is the case, then the resource should be in located in a JAR file or directory on the classpath, and the location will be resolved relative to the FQN of the class.
I can't tell where the ".class" files are located in the tree, or how your classpath is set up, so I can't be more specific.
UPDATED
If you are executing out of that build directory, then your build process needs to copy the XML file to the appropriate place in the build tree so that the class-relative path ends up referring to the file. (Or use a path that starts with "/" so that you don't depend on the classes FQN at all.)
In the long term, you will probably execute out of a JAR file, and the data file will need to be inside it.
Use "getSystemResourceAsStream" instead of "getResourceAsStream" to access files outside of your codebase.

How to specify relative file path in Java file so that it can still work after the file is put in jar file?

Suppose I have a Java class that needs to access a file with absolute path
/home/gem/projects/bar/resources/test.csv:
package com.example
class Foo {
String filePath = ????? // path to test.csv
String lines = FileInputStream(new File(filePath).readAllLines();
}
Where the path to Foo.java is /home/gem/projects/bar/src/com/example.
Of course I cannot specify absolute path to the resource file. This is because jar file will be distributed as library for any clients to use in their own environments.
Assume the resource file like test.csv is always in the same path relative to project root. When a jar is created containing Foo.class, this jar also contains test.csv in the same relative path ( relative to project root).
What is the way to specify relative path that would work no matter where the project bar is moved to? Also how can I create a jar file (which can be in any location) so that the path to the resource file test.csv would still be correct.
To keep things simple, I have used invalid Java API ( readAllLines() which reads all the lines and return a string containing entire file content. Also not using try/catch).
Assume csv file can be read as well as written to.
I hope this makes it clear now.
Put the test.csv file into the src folder and use this:
Foo.class.getResourceAsStream("/test.csv")
To get an InputStream for the file. This will work wherever the project is moved, including packaged as a JAR file.
Example:
ProjectX\src\Test.java
ProjectX\resources\config.properties
If you have the above structure and you want to use your config.properties file, this is how you do it:
InputStream input = new FileInputStream("./resources/config.projects");
In this example you don't have to worry about packaging your source into jar file. You can still modify your resources folder anytime.
Use getResource(), as shown here.

Categories

Resources