I'm facing a strange behaviour of the JVM. I wanted to change the user directory, i.e. the dir where files are looked up, that normally corresponds to the path where the java
command is run.
So I wrote the following code:
System.setProperty("user.dir", "/tmp/");
File f = new File("myfile");
System.out.println(f.exists());
System.out.println(f.getCanonicalFile().exists());
The file /tmp/myfile
exists and is readable by the JVM, but if I'm not in /tmp/
when I run that code, the result is:
false true
They are the same file, Java is able to retrieve the correct canonical form of it, but the relative one does not exist, while the canonical one exists.
Is it a bug? Is there a way to reliably change the JVM user directory?
Changing the code is not an option, as I'm trying to run external libraries.
The exists() function is a part of the File class in Java. This function determines whether the is a file or directory denoted by the abstract filename exists or not. The function returns true if the abstract file path exists or else returns false. Parameters: This method does not accept any parameter.
A canonical path is always an absolute path. Converting from a path to a canonical path makes it absolute (usually tack on the current working directory so e.g. ./file. txt becomes c:/temp/file. txt ).
The canonical path is always an absolute and unique path. If String pathname is used to create a file object, it simply returns the pathname. This method first converts this pathname to absolute form if needed. To do that it will invoke the getAbsolutePath() Method and then maps it to its unique form.
For example, "/var/tmp/foo" is a canonical path while "/var/tmp/foo/" is not.
This behavior is normal, the reason is, there is a difference between
File f = new File("myfile");
and
File cf = new File("myfile").getCanonicalFile();
The first denotes a filepath relative to your current WORKING DIR, which could be your project path. Using the relative path, the user.dir
property is NOT USED, even when setting user.dir
as JVM parameter -Duser.dir=/tmp/
. The resolution of Java file handles to native file entities is done natively by the underlying Fileystem implementation.
But when invoking getCanoncialFile()
before resolving the native file handle the relative path is resolved using the user path information - in your case user.dir = /tmp/
.
Apparently, there is no file myfile
in <WORKING_DIR>
but in /tmp/
.
The behavior is the same for f.getAbsoluteFile()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With