What does exactly mean this sentence from this oracle java tutorial:
A relative path cannot be constructed if only one of the paths includes a root
Because p1
and p3
has different root.
If you use use "/home/sally/bar" instead of "home/sally/bar" for p3
, then p3.getRoot()
will return /
but p1.getRoot()
is null.
You'll know why you got this exception after you read following codes (comes from http://cr.openjdk.java.net/~alanb/6863864/webrev.00/src/windows/classes/sun/nio/fs/WindowsPath.java-.html Line374-375):
// can only relativize paths of the same type
if (this.type != other.type)
throw new IllegalArgumentException("'other' is different type of Path");
As other answers already mentioned this is due to the different roots in the path.
To work around that, you can use toAbsolutePath()
.
For example:
public class AnotherOnePathTheDust {
public static void main (String []args)
{
Path p1 = Paths.get("home").toAbsolutePath();
Path p3 = Paths.get("/home/sally/bar").toAbsolutePath();
Path p1_to_p3 = p1.relativize(p3);
Path p3_to_p1 = p3.relativize(p1);
System.out.println(p3_to_p1);
}
}
I did some tests of your example. Actually the exception you are mentioning appears only when one of the paths contains root and the other not (exactly like the sentence says) E.g:
It works ok if both paths contain roots. The "system dependent" means probably such case on Windows:
Above gives following exception:
java.lang.IllegalArgumentException: 'other' has different root
You will never face something like this (exception for both paths containing root - absolute paths) on Unix
System dependent here refers to the specific OS implementation I would assume. So Linux will handle this differently than Windows will, etc. Without root paths (i.e. paths starting with /), both paths are assumed to be siblings, sitting on the same level (i.e. in /home/sally). So when you try to relativize, if they are not on the same level, there is no guarantee where the non-root path is stored, which makes sense if you think about it. Does that help?