Sargon1
Sargon1

Reputation: 874

Why is subpath() throwing IllegaArgumentException in this case?

I'm writing an app for folder synchronization. I have two dir structures, Source and Target, and I need to somehow refer to the eqivalent file/folder in the other dir structure when recursing through the other. This method attempts to achieve that by first extracting the sublocation of the file in Source by lobbing off the root folder that was previously selected by the user and stored as a global variable and then appending it to the root folder of Target, which is likewise user selected and stored globally. Why isn't this working? The arguments seem fine; from the length of the sourcePath to the index of the last element.

private Path getEquivalentFileInTarget(Path pathOfSource) {
    Path sourceSublocation = pathOfSource.subpath(sourcePath.getNameCount(), -1);
    return targetPath.resolve(sourceSublocation);
}

Error log:

Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1771)
    ... 48 more
Caused by: java.lang.IllegalArgumentException
    at sun.nio.fs.WindowsPath.subpath(WindowsPath.java:634)
    at sun.nio.fs.WindowsPath.subpath(WindowsPath.java:44)
    at sample.FolderSyncerMainWindowController.getEquivalentFileInTarget(FolderSyncerMainWindowController.java:133)
    at sample.FolderSyncerMainWindowController.putInTreeViewCompare(FolderSyncerMainWindowController.java:120)
    at sample.FolderSyncerMainWindowController.handleCompareButton(FolderSyncerMainWindowController.java:92)
... 58 more

Upvotes: 0

Views: 631

Answers (3)

fge
fge

Reputation: 121710

You are misusing Path.

Now, I don't know whether your different Paths are issued from different file system providers, but if they are not you can just do that:

final Path subpath = sourceRoot.relativize(fullPathInSource);
final Path fullPathInTarget = targetRoot.resolve(subpath);

This will also work if subpath is the empty path (this is what sourceRoot.relativize(sourceRoot) will return).

Upvotes: 1

QuakeCore
QuakeCore

Reputation: 1926

From the documentation website:

Path subpath(int beginIndex,
           int endIndex)

Parameters:beginIndex - the index of the first element, inclusiveendIndex - the index of the last element, exclusive

Throws:IllegalArgumentException - if beginIndex is negative, or greater than or equal to the number of elements. If endIndex is less than or equal to beginIndex, or larger than the number of elements.

and since endIndex must be larger than beginIndex and the beginIndex must be larger than zero then the endIndex must also be larger than zero and you passed -1

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726579

The second parameter of subpath method must be a number that is strictly greater than the first parameter, because it's an index of the subpath element. There is no situation when it would be allowed to be negative.

You should subtract 1 from the count, like this:

Path sourceSublocation = pathOfSource.subpath(0, sourcePath.getNameCount()-1);

Upvotes: 1

Related Questions