V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
laqow
V2EX  ›  Java

求教 Java .nio.file.Paths.get 从 Linux 迁移到 Windows 时出错是什么原因

  •  
  •   laqow · 13 天前 · 694 次点击

    Java 小白,没调试环境,参照别人项目说明用 gradle 在 windows 上 build 了一个 jar 包,运行时出现 java.nio.file.InvalidPathException: Illegal char <:> at index 11: undefined/R:/temp 错误,感觉可能是 windows 盘符路径或反斜杠的坑,问题可能在后端也可能在前端,求教最可能的原因。同样操作在 linux 上运行是没有问题的。

    项目是这个 https://github.com/epam/NGB,因为没人回答 issue 来这里问问。项目大概是 tomcat 做 server,angurjs 还是啥的做的前端,用 REST 做服务。

    log 里面的错误前几行是:

    ERROR [06/04/2021 01:50:55][http-nio-8080-exec-9][com.epam.catgenome.controller.ExceptionHandlerAdvice] This operation has been aborted: uri=/catgenome/restapi/files;client=0:0:0:0:0:0:0:1.
    java.nio.file.InvalidPathException: Illegal char <:> at index 11: undefined/R:/temp
    	at sun.nio.fs.WindowsPathParser.normalize(Unknown Source)
    	at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
    	at sun.nio.fs.WindowsPathParser.parse(Unknown Source)
    	at sun.nio.fs.WindowsPath.parse(Unknown Source)
    	at sun.nio.fs.WindowsFileSystem.getPath(Unknown Source)
    	at java.nio.file.Paths.get(Unknown Source)
    	at com.epam.catgenome.manager.FileManager.loadDirectoryContents(FileManager.java:1919)
    	at com.epam.catgenome.controller.UtilsController.loadDirectoryContents(UtilsController.java:138)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    

    在 chrome 里面抓到的请求是下面这个,返回是个空的 400 错误

    http://127.0.0.1:58123/catgenome/restapi/files?path=R:\temp

    相关文件的代码是:

    com.epam.catgenome.manager.FileManager.loadDirectoryContents(FileManager.java:1919)

        /**
         * Returns contents of a directory, specified by path, to browse NGS files
         *
         * @param path a path to directory to browse
         * @return {@link List} of {@link FsDirectory}s, and {@link FsFile}, representing subdirectories and files
         * @throws IOException
         */
        public List<AbstractFsItem> loadDirectoryContents(String path) throws IOException {
    
            if(!StringUtils.isEmpty(path) && !Paths.get(path).startsWith(ngsDataRootPath)) { // 第 1919 行
                throw new AccessDeniedException(
                        String.format("Parameter path doesn't fall into 'ngs.data.root.path': %s", ngsDataRootPath));
            }
    
            if (!filesBrowsingAllowed || ngsDataRootPath.equals(FILE_SYSTEM_ROOT)) {
                throw new AccessDeniedException("Server file system browsing is not allowed");
            }
    
            List<File> parentDirs = new ArrayList<>();
            if (path == null) {
                parentDirs.add(new File(ngsDataRootPath));
            } else {
                parentDirs.add(new File(path));
            }
    
            Assert.isTrue(parentDirs.stream().allMatch(File::exists), "Specified path does not exist: " + path);
            Assert.isTrue(parentDirs.stream().allMatch(File::isDirectory), "Specified path is not a directory: " + path);
    
            List<AbstractFsItem> items = new ArrayList<>();
    
            boolean accessDenied = false;
            String fileName = "";
            String otherFileName = "";
    
            for (File parentDir : parentDirs) {
                if (parentDir.listFiles() == null) {
                    continue;
                }
    
                try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(parentDir.toPath())) {
                    for (Path child : dirStream) {
                        try {
                            File childFile = child.toFile();
                            if (childFile.isDirectory()) {
                                FsDirectory directory = new FsDirectory();
                                directory.setPath(childFile.getAbsolutePath());
                                if (childFile.canRead()) {
                                    directory.setFileCount(countChildrenFiles(child));
                                }
    
                                items.add(directory);
                            } else {
                                addFsFile(items, childFile);
                            }
                        } catch (AccessDeniedException e) {
                            LOGGER.error("Access denied:", e);
                            accessDenied = true;
                            fileName = e.getFile();
                            otherFileName = e.getOtherFile();
                        }
                    }
    
                    if (items.isEmpty() && accessDenied) {
                        throw new AccessDeniedException(fileName, otherFileName, "Access denied");
                    }
                }
            }
    
            return items;
        }
    

    com.epam.catgenome.controller.UtilsController.loadDirectoryContents(UtilsController.java:138)

        @ResponseBody
        @RequestMapping(value = "/files", method = RequestMethod.GET)
        @ApiOperation(
            value = "Returns directory contents",
            notes = "Returns directory contents, specified by path",
            produces = MediaType.APPLICATION_JSON_VALUE)
        @ApiResponses(
            value = {@ApiResponse(code = HTTP_STATUS_OK, message = API_STATUS_DESCRIPTION)
            })
        public Result<FilesVO> loadDirectoryContents(@RequestParam(required = false) String path)
            throws IOException {
            return Result.success(new FilesVO(fileManager.loadDirectoryContents(path), fileManager.getNgsDataRootPath())); // 第 138 行
        }
    
    6 条回复    2021-04-06 15:25:34 +08:00
    gitdoit
        1
    gitdoit   13 天前
    不是很明显吗,路径前面为什么会有 undefined ?这个 undefined 应该是前端传过来的吧
    borisz
        2
    borisz   13 天前
    undefined/R:/temp 这个地址有问题吧
    laqow
        3
    laqow   13 天前 via Android
    @gitdoit @borisz 谢谢。前端的请求应该就这个 http://127.0.0.1:58123/catgenome/restapi/files?path=R:\temp,linux 下也是 /home/啥啥啥 的,不知道这个 undefined 是哪里来的。机子上没有调试 java 的东西,能请问应该怎样 log UtilsController.loadDirectoryContents 收到的 path 出来吗?
    laqow
        4
    laqow   13 天前 via Android
    @gitdoit
    @borisz
    好像有点头绪了,我试试写几个请求看看能 log 出什么东西。能请问机子上没有调试 java 的东西,应该怎样 log UtilsController.loadDirectoryContents 收到的 path 出来吗?
    laqow
        5
    laqow   13 天前 via Android
    好吧,可以抄代码里面的 LOGGER.error("Access denied:", e);
    Githuboy
        6
    Githuboy   13 天前
    问题解决了吗,到底是啥原因呢
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2746 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 72ms · UTC 04:25 · PVG 12:25 · LAX 21:25 · JFK 00:25
    ♥ Do have faith in what you're doing.