file:move() fails when moving to another file system

Tuesday, 11 February 2020 · 7 messages · last reply 12 Feb 2020
ZD
Zimmel, Daniel11 Feb 2020 16:39 #
Hi, I am able to file:copy() or file:write() a file from a Linux system to a Windows mount (via cifs). I am not able to file:move() to the same target. The error says "file:io-error: Die Operation ist nicht erlaubt" BaseX version is 9.2.1 Is this a bug or a known restriction with moving things around in Java? Thanks, Daniel
CG
Christian Grün11 Feb 2020 16:46 #
Hi Daniel, BaseX uses standard Java NIO to move files [1]; see [2] for a more comprehensive documentation. You could enable debugging, and we could have a look at the full command line output; maybe that gives us some hints what goes wrong here. Did you try the alternative to copy your files and delete the source afterwards? Best, Christian [1] https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/query/func/file/FileCopy.java#L79 [2] https://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#move(java.nio.file.Path,%20java.nio.file.Path,%20java.nio.file.CopyOption.. .)
Quoted text · Daniel · 19 lines
Zimmel, Daniel <D.Zimmel at esvmedien.de> schrieb am Di., 11. Feb. 2020, 16:39: > Hi, > > I am able to file:copy() or file:write() a file from a Linux system to a > Windows mount (via cifs). > I am not able to file:move() to the same target. > > The error says "file:io-error: Die Operation ist nicht erlaubt" > > BaseX version is 9.2.1 > > Is this a bug or a known restriction with moving things around in Java? > > Thanks, Daniel > > > > >
ZD
Zimmel, Daniel11 Feb 2020 17:50 #
Christian,
basexclient -d gives only

[file:io-error] ... : Die Operation ist nicht erlaubt        at org.basex.api.client.ClientSession.receive(ClientSession.java:192)
        at org.basex.api.client.ClientSession.execute(ClientSession.java:161)
        at org.basex.api.client.ClientSession.execute(ClientSession.java:166)
        at org.basex.api.client.Session.execute(Session.java:36)
        at org.basex.core.CLI.execute(CLI.java:92)
        at org.basex.BaseX.<init>(BaseX.java:100)
        at org.basex.BaseXClient.<init>(BaseXClient.java:35)
        at org.basex.BaseXClient.main(BaseXClient.java:22)
Stopped at ., 1/10:
My alternative works:
      file:copy($sourcefilepath,$archivedir||file:dir-separator()||$file),
      if (file:exists($archivedir||file:dir-separator()||$file))
      then (file:delete($sourcefilepath))
but I think the if/then can be left out, because the query will always fail sequentially before the delete if something goes wrong with the copy (?) Thanks, Daniel
Quoted text · Christian Grün · 21 lines
Von: Christian Grün <christian.gruen at gmail.com> Gesendet: Dienstag, 11. Februar 2020 16:47 An: Zimmel, Daniel <D.Zimmel at ESVmedien.de> Cc: BaseX <basex-talk at mailman.uni-konstanz.de> Betreff: Re: [basex-talk] file:move() fails when moving to another file system Hi Daniel, BaseX uses standard Java NIO to move files [1]; see [2] for a more comprehensive documentation. You could enable debugging, and we could have a look at the full command line output; maybe that gives us some hints what goes wrong here. Did you try the alternative to copy your files and delete the source afterwards? Best, Christian [1] https://github.com/BaseXdb/basex/blob/master/basex-core/src/main/java/org/basex/query/func/file/FileCopy.java#L79 [2] https://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#move(java.nio.file.Path,%20java.nio.file.Path,%20java.nio.file.CopyOption...) Zimmel, Daniel <D.Zimmel at esvmedien.de<mailto:D.Zimmel at esvmedien.de>> schrieb am Di., 11. Feb. 2020, 16:39: Hi, I am able to file:copy() or file:write() a file from a Linux system to a Windows mount (via cifs). I am not able to file:move() to the same target. The error says "file:io-error: Die Operation ist nicht erlaubt" BaseX version is 9.2.1 Is this a bug or a known restriction with moving things around in Java? Thanks, Daniel
CG
Christian Grün11 Feb 2020 17:53 #
Quoted text · Zimmel, Daniel · 1 line
>: Die Operation ist nicht erlaubt
A last try: What do you get if you run it with basex (the standalone, not the client)?
Quoted text · Zimmel, Daniel · 1 line
> I think the if/then can be left out, because the query will always fail
sequentially before the delete if something goes wrong with the copy (?) Exactly.
ZD
Zimmel, Daniel12 Feb 2020 09:44 #
Quoted text · Christian Grün · 1 line
> A last try: What do you get if you run it with basex (the standalone, not the client)?
java.nio.file.FileSystemException: [...]: Die Operation ist nicht erlaubt
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
        at java.base/sun.nio.fs.UnixCopyFile.copyFile(UnixCopyFile.java:288)
        at java.base/sun.nio.fs.UnixCopyFile.move(UnixCopyFile.java:476)
        at java.base/sun.nio.fs.UnixFileSystemProvider.move(UnixFileSystemProvider.java:263)
        at java.base/java.nio.file.Files.move(Files.java:1413)
        at org.basex.query.func.file.FileCopy.relocate(FileCopy.java:75)
        at org.basex.query.func.file.FileCopy.relocate(FileCopy.java:53)
        at org.basex.query.func.file.FileMove.item(FileMove.java:18)
        at org.basex.query.func.file.FileFn.item(FileFn.java:25)
        at org.basex.query.func.file.FileCopy.item(FileCopy.java:18)
        at org.basex.query.expr.ParseExpr.value(ParseExpr.java:50)
        at org.basex.query.expr.ParseExpr.iter(ParseExpr.java:45)
        at org.basex.query.scope.MainModule.iter(MainModule.java:97)
        at org.basex.query.QueryContext.iter(QueryContext.java:332)
        at org.basex.query.QueryProcessor.iter(QueryProcessor.java:90)
        at org.basex.core.cmd.AQuery.query(AQuery.java:107)
        at org.basex.core.cmd.XQuery.run(XQuery.java:22)
        at org.basex.core.Command.run(Command.java:257)
        at org.basex.core.Command.execute(Command.java:93)
        at org.basex.api.client.LocalSession.execute(LocalSession.java:132)
        at org.basex.api.client.Session.execute(Session.java:36)
        at org.basex.core.CLI.execute(CLI.java:92)
        at org.basex.BaseX.<init>(BaseX.java:100)
        at org.basex.BaseX.main(BaseX.java:42)
org.basex.query.QueryException: [...]: Die Operation ist nicht erlaubt
        at org.basex.query.QueryError.get(QueryError.java:1431)
        at org.basex.query.func.file.FileFn.item(FileFn.java:35)
        at org.basex.query.func.file.FileCopy.item(FileCopy.java:18)
        at org.basex.query.expr.ParseExpr.value(ParseExpr.java:50)
        at org.basex.query.expr.ParseExpr.iter(ParseExpr.java:45)
        at org.basex.query.scope.MainModule.iter(MainModule.java:97)
        at org.basex.query.QueryContext.iter(QueryContext.java:332)
        at org.basex.query.QueryProcessor.iter(QueryProcessor.java:90)
        at org.basex.core.cmd.AQuery.query(AQuery.java:107)
        at org.basex.core.cmd.XQuery.run(XQuery.java:22)
        at org.basex.core.Command.run(Command.java:257)
        at org.basex.core.Command.execute(Command.java:93)
        at org.basex.api.client.LocalSession.execute(LocalSession.java:132)
        at org.basex.api.client.Session.execute(Session.java:36)
        at org.basex.core.CLI.execute(CLI.java:92)
        at org.basex.BaseX.<init>(BaseX.java:100)
        at org.basex.BaseX.main(BaseX.java:42)
Caused by: java.nio.file.FileSystemException: [...]: Die Operation ist nicht erlaubt
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
        at java.base/sun.nio.fs.UnixCopyFile.copyFile(UnixCopyFile.java:288)
        at java.base/sun.nio.fs.UnixCopyFile.move(UnixCopyFile.java:476)
        at java.base/sun.nio.fs.UnixFileSystemProvider.move(UnixFileSystemProvider.java:263)
        at java.base/java.nio.file.Files.move(Files.java:1413)
        at org.basex.query.func.file.FileCopy.relocate(FileCopy.java:75)
        at org.basex.query.func.file.FileCopy.relocate(FileCopy.java:53)
        at org.basex.query.func.file.FileMove.item(FileMove.java:18)
        at org.basex.query.func.file.FileFn.item(FileFn.java:25)
        ... 15 more
org.basex.core.BaseXException: Stopped at ., 1/10:
[file:io-error] [...]: Die Operation ist nicht erlaubt
        at org.basex.core.Command.execute(Command.java:94)
        at org.basex.api.client.LocalSession.execute(LocalSession.java:132)
        at org.basex.api.client.Session.execute(Session.java:36)
        at org.basex.core.CLI.execute(CLI.java:92)
        at org.basex.BaseX.<init>(BaseX.java:100)
        at org.basex.BaseX.main(BaseX.java:42)
Caused by: org.basex.query.QueryException: [...]: Die Operation ist nicht erlaubt
        at org.basex.query.QueryError.get(QueryError.java:1431)
        at org.basex.query.func.file.FileFn.item(FileFn.java:35)
        at org.basex.query.func.file.FileCopy.item(FileCopy.java:18)
        at org.basex.query.expr.ParseExpr.value(ParseExpr.java:50)
        at org.basex.query.expr.ParseExpr.iter(ParseExpr.java:45)
        at org.basex.query.scope.MainModule.iter(MainModule.java:97)
        at org.basex.query.QueryContext.iter(QueryContext.java:332)
        at org.basex.query.QueryProcessor.iter(QueryProcessor.java:90)
        at org.basex.core.cmd.AQuery.query(AQuery.java:107)
        at org.basex.core.cmd.XQuery.run(XQuery.java:22)
        at org.basex.core.Command.run(Command.java:257)
        at org.basex.core.Command.execute(Command.java:93)
        ... 5 more
Caused by: java.nio.file.FileSystemException: [...]: Die Operation ist nicht erlaubt
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:100)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
        at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
        at java.base/sun.nio.fs.UnixCopyFile.copyFile(UnixCopyFile.java:288)
        at java.base/sun.nio.fs.UnixCopyFile.move(UnixCopyFile.java:476)
        at java.base/sun.nio.fs.UnixFileSystemProvider.move(UnixFileSystemProvider.java:263)
        at java.base/java.nio.file.Files.move(Files.java:1413)
        at org.basex.query.func.file.FileCopy.relocate(FileCopy.java:75)
        at org.basex.query.func.file.FileCopy.relocate(FileCopy.java:53)
        at org.basex.query.func.file.FileMove.item(FileMove.java:18)
       at org.basex.query.func.file.FileFn.item(FileFn.java:25)
        ... 15 more
Quoted text · Christian Grün · 9 lines
Von: Christian Grün <christian.gruen at gmail.com> Gesendet: Dienstag, 11. Februar 2020 17:54 An: Zimmel, Daniel <D.Zimmel at ESVmedien.de> Cc: BaseX <basex-talk at mailman.uni-konstanz.de> Betreff: Re: [basex-talk] file:move() fails when moving to another file system >: Die Operation ist nicht erlaubt A last try: What do you get if you run it with basex (the standalone, not the client)? > I think the if/then can be left out, because the query will always fail sequentially before the delete if something goes wrong with the copy (?) Exactly.
LQ
Liam R. E. Quin12 Feb 2020 10:15 #
Quoted text · Daniel · 3 lines
On Wed, 2020-02-12 at 08:44 +0000, Zimmel, Daniel wrote: > > A last try: What do you get if you run it with basex (the > > standalone, not the client)?
Looks to me like query/func/file/FileCopy.java uses Files.move() when it thinks i can, but this will fail on Unix-like systems if you try to move a file across file system boundaries (because then the kernel would need to copy the data). One approach might be to catch failure of Files.move() and try again with Files.copy(). Liam
-- Liam Quin, https://www.delightfulcomputing.com/ Available for XML/Document/Information Architecture/XSLT/ XSL/XQuery/Web/Text Processing/A11Y training, work & consulting. Barefoot Web-slave, antique illustrations: http://www.fromoldbooks.org
CG
Christian Grün12 Feb 2020 13:45 #
Quoted text · Liam R. E. Quin · 4 lines
> Looks to me like query/func/file/FileCopy.java uses Files.move() when > it thinks i can, but this will fail on Unix-like systems if you try to > move a file across file system boundaries (because then the kernel > would need to copy the data).
True, I thought similarly. It turns out these cases seems to be already considered by the Java implementation (if preferred, however, all this magic can be disabled via an ATOMIC_MOVE flag [1]). In found some entries reg. problems with Files.move in the JDK bug reports, but nothing that matches our observations in detail. So I think we’ll need to live with copy & delete for the moment until we can reproduce this more easily. [1] https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html#move-java.nio.file.Path-java.nio.file.Path-java.nio.file.CopyOption...-

⚡Generated with XQuery