File paths in Java (Linux) - java

I have created a Java application that loads some configurations from a file conf.properties which is placed in src/ folder.
When I run this application on Windows, it works perfectly. However when I try to run it on Linux, it throws this error:
java.io.FileNotFoundException: src/conf.properties (No such file or directory)

If you've packaged your application to a jar file, which in turn contains the properties file, you should use the method below. This is the standard way when distributing Java-programs.
URL pUrl = this.getClass().getResource("/path/in/jar/to/file.properties");
Properties p = new Properties();
p.load(pUrl.openStream());
The / in the path points to the root directory in the jar file.

Instead of
String PROP_FILENAME="src/conf.properties";
use
String PROP_FILENAME="src" + File.separator + "conf.properties";
Check the API for more detail: http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html

I would also check what your current working directory is if your path to that file is relative. You just need to make a File test = new File("."); and then print that files canonical path name.
If you are referencing any other locations like user.dir or something to that effect by using System.getProperty(), you'll want to at least verify that the directory you are using as the relative root is where you think it is.
Also, as Myles noted, check the slashes used as file path separators. Although you can always use the "/" and it works.
And if you are referencing the path absolutely, you'll have trouble going between one OS and another if you do something silly like hard-code the locations.

What you want to do is check out System.getProperties() and look for file.separator. The static File.pathSeprator will also get you there.
This will allow you to build a path that is native for whatever system you're running on.
(If indeed that is the problem. Sometimes I like to get the current directory just to make sure the directory I think I'm running in is the directory I'm really running in.)

Check your permissions. If you (or rather, the user that the Java process is running under) doesn't have appropriate permissions to read the file, for example, you would get this error message.
This is a typical Windows -> Linux migration problem. What does ls -l src/conf.properties show when run from a prompt?
Additionally, check capitalisation. Windows isn't case-sensitive, so if the file was actually called e.g. CONF.properties it would still be found, whereas the two would be considered different files on Linux.

You should check the working directory of your application. Perhaps it is not the one you assume and that's why 'src' directory is not present.
An easy check for this is to try the absolute path (only for debugging!).

I would check your slashes, windows often uses '\' vs linux's '/' for file paths.
EDIT: Since your path looks fine, maybe file permissions or executing path of the app is different?

check your slashes and colons
in my case i set my PS1 to following value
PS1='\n[\e[1;32m]$SYSNAME(\u)#[\e[1;33m]\w [\e[1;36m](\d \T) [!]\e[0m]\n\$ '
i am trying to read from the env .such as system.getenv
Java was throwing exception
java.lang.IllegalArgumentException: Malformed \uxxxx encoding

Try the double slash, after doing things in JBoss I often had to refactor my code to use the double slashes

Related

Scanner cannot find (correct) file path

I'm programming in Java with IntelliJ and have been trying to use the Scanner class to read the file. Even with the correct path, I still get a "No such file or directory" error. Does anyone have any suggestions?
My working directory is /Users/kevinliu/Desktop/test
Here is a picture of how the project is set-up.
Are you trying to create a swing/console application using maven?
If yes, maven is not able to find the source. You have to add it on the pom file. See here on how to add it on pom file.
if no, do you have rights to access the address of the image file? Some times, folder are protected by the OS.
You can also use YourClassName.class.getResource("input/input1.txt") to locate file/s under the directory that your class was in.
Even with the correct path, I still get a "No such file or directory" error.
The path is NOT correct. That path says look for a directory called "src" in the root directory of your computer. That is almost certainly not where the input file lives.
If you are going to use an absolute pathname for a file within the working directory that you stated, it should look like this:
/Users/kevinliu/Desktop/test/src/input/input1.txt
(You can check what it will actually be using a file browser ... outside of Intellij.)
If you want to use a relative pathname, try this
src/input/input1.txt
Notes:
There is no leading "/" on a relative pathname. A leading "/" means it is an absolute pathname. Absolute pathnames start at the root directory.
A relative path is resolved relative to the >>current<< working directory. That will depend on where and how you run the application ...
For a production application, you would not want to refer to a file in the source tree. The end user typically won't have the source tree.
Consider making the path a command line argument or configuration setting for your application.
Consider making the file a "resource" that is part of the application's JAR file. (You would open it a different way ...)
If you ever get a "No such file or directory" message, that means that the path is not correct in some sense. You might be in the wrong place, you might not have permission on a parent directory, the file may have been removed or renamed, there may be a you, or something else. Either way, that error comes from the operating system and the OS doesn't make mistakes about these things. The mistake will be yours (or the user's).

Java Cross Platform File Operations

I developed a software in netbeans + Ubuntu and then converted the runnable .jar file of netbeans to .exe file using a converter software.
I used:
File f = new File("./dir/fileName");
which works fine in Ubuntu but it gives an error in Windows, because the directory pattern of both OSs are different.
Absolute paths should not be hardcoded. They should be read e.g. from a config file or user input.
Then you can use the NIO.2 File API to create your file paths: Paths.get(...) (java.io.File is a legacy API).
In your case it could be:
Path filePath = Paths.get("dir", "fileName");
I used: File f = new File("./dir/fileName") which works fine in Ubuntu but it gives error in Windows, bcz the directory pattern of both os are different.
It is presumably failing because that file doesn't exist at that path. Note that it is a relative path, so the problem could have been that the the path could not be resolved from the current directory ... because the current directory was not what the application was expecting.
In fact, it is perfectly fine to use forward slashes in pathnames in Java on Window. That's because at the OS level, Windows accepts both / and \ as path separators. (It doesn't work in the other direction though. UNIX, Linux and MacOS do not accept backslash as a pathname separator.)
However Puce's advice is mostly sound:
It is inadvisable to hard-code paths into your application. Put them into a config file.
Use the NIO2 Path and Paths APIs in preference to File. If you need to assemble paths from their component parts, these APIs offer clean ways to do it while hiding the details of path separators. The APIs are also more consistent than File, and give better diagnostics.
But: if you do need to get the pathname separator, File.separator is an acceptable way to get it. Calling FileSystem.getSeparator() may be better, but you will only see a difference if your application is using different FileSystem objects for different file systems with different separators.
You can use File.separator as you can see in api docs:
https://docs.oracle.com/javase/8/docs/api/java/io/File.html

Best way to process command line file path argument in Java

I'd like to pass a file path argument to my application in a relative form, e.g ~/test.conf or ../test.conf, but i can't get a proper full file path, though i've tried it with old java.io and new java.nio Files/Paths. Is there a general way to get a resolved file path without large amount of code? It would be fine for the solution to work only in unix envs like OsX or Debian.
Update
With a provided argument like ~/test.conf
in case of getAbsolutePath it returns a path with a prefixed current folder - /Users/currentUser/Projects/Personal/TestProject/~/text.conf. Canonical path returns the same.
The hard bit here is dealing with POSIX home directories, and sure you deal with ~otheruser/dir/test.conf too (if you want to do it properly).
Luckily that's covered in How to handle ~ in file paths.
TL;DR - use something like:
path.replace("~/", System.getProperty("user.home") + "/");
Once you've done that, and as others have commented, you can just use standard java.io methods (including getCanonicalPath()).

Thread.currentThread().getContextClassLoader().getResourceAsStream() returns null

I have following code block in my application;
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(FilePath);
Here 'FilePath' is an absolute path of the file.
Above code works fine in linux and in windows when i run the application in normal mode.(ie: in command prompt)
But this is NOT working, when I run the application as a windows service. I get input stream as 'null'.
Anyone encountered such issue before? I could not find any information regarding this other than java classloaders . Here we use "ContextClassLoader", which is the right classloader to be used..
Any clue on this?
I think this happens because you have "." (the current folder) on the classpath. That is a) a bad idea and b) makes your app break in odd ways.
What you need to understand is the difference between a file and a resource. A file is something outside of the classpath.
You should use File and FileReader to access them.
A resource is something on the classpath. Paths for resources always use / as file separator and not File.separator.
Another way to fix this is to add $HOME/repository/ (Linux) or %HOME%/repository/ to the classpath and load the resource using "resources/api_templates/api.xml". for this to work, resources must be a folder in $HOME/repository/.
If you don't do this, then all files in your home directory (or whatever directory you happen to start the application in) are added as resources to the classpath.

Java - Get server absolute path

How to get the absolute path of server location in my machine?
Suppose I am using glassfish server then I need to get absolute path of glassfish docroot location as below:
C:\glassfish3\glassfish\domains\domain1\docroot
At run time, I need to create file on that location using java io package like:
C:\glassfish3\glassfish\domains\domain1\docroot\myfile.txt
If you use GlassFish to start GlassFish, i.e. use asadmin start-domain|start-instance then we offer the following iron-clad guarantee:
The current working directory of the JVM is absolutely, positively guaranteed to be the config directory of the domain or server. In the default case that would be:
c:/glassfish3/glassfish/domains/domain1/config
If you want to write something to (the default) docroot, you can do this:
File f = new File("../docroot/yourfile");
Another option that is guaranteed to always work in every scenario even if you start the server with java directly (e.g. java -jar glassfish.jar) is to use the value of the System Property like so:
File f = new File(System.getProperty("com.sun.aas.instanceRoot") + "/docroot/yourfile");
I don't know if this is the best way, but it works for me :)
String path = new File("").getAbsolutePath() + File.separator + "docroot";
you can try following:
System.getProperty("catalina.base");
And you can find other properties by watching following variable in debug mode.
Properties properties = System.getProperties();
I had an similar problem and ended up with using
path = getClass().getProtectionDomain().getCodeSource().getLocation()
because I needed the path on a static function. This points somwhere to the WEB-INF/classes directory. With this you could point to something like path.subString(0,path.indexOf("WEB-INF")).
One problem that I had with this: When running a test from Eclipse, it pointed me to the "build" directory of the project.
This is a very bad idea. If you are running in a WAR or EAR file the docroot will not be on a writable filesystem. Assuming this is the case may lead to headaches later.
Use a different method, such as a servlet initialization parameter, to specify a writable filesystem location.
For that you need not to go for complete path because
when you are creating file than by default it will create at ROOT of you server
which is C:\glassfish3\glassfish\ here.
hope this will help you.

Categories

Resources