【问题标题】:FileNotFoundException on linux machine when using getClassLoader().getResource使用 getClassLoader().getResource 时 Linux 机器上的 FileNotFoundException
【发布时间】:2014-07-23 22:05:20
【问题描述】:

我已经在互联网上对这个问题进行了相当多的研究。到目前为止我没有运气。基本上,这段代码在我的 Junit 测试 src\test\java\com\project\utils\MyTestCase.java 上运行良好:

URL urlApplicationContext = this.getClass().getClassLoader().getResource("applicationContext.xml");
final String[] paths = { urlApplicationContext.getFile()};
ApplicationContext ctx = new FileSystemXmlApplicationContext(paths);

这个文件位于那里:

\src\test\resources\applicationContext.xml

但是在 linux 上运行的 Jenkins 机器上我得到了以下错误:

testSimple(com.project.ClientImplTest): IOException 解析 XML 文件中的文件 [/data/continuous/workspace/sonar/main_proj/data/continuous/workspace/sonar/main_proj/target/main/WEB-INF/test-classes/applicationContext.xml]; 嵌套异常是 java.io.FileNotFoundException: 数据/连续/工作区/声纳/main_proj/target/main/WEB-INF/test-classes/applicationContext.xml (没有这样的文件或目录)

我已经验证文件 /data/continuous/workspace/sonar/main_proj/target/main/WEB-INF/test-classes/applicationContext.xml 确实存在。

为什么 getResource() 在 Linux 上找不到正确的路径。由于某种原因,它似乎找到了 data/continous/... 而不是 /data/continous/...因此 FileSystemXmlApplicationContext 可能会因为找不到文件而返回异常。

谢谢

【问题讨论】:

    标签: java linux


    【解决方案1】:

    我在我的项目中遇到了同样的问题 - 它是由路径中的空格引起的 - 要处理这种情况,您需要使用 URL 的 toURI() 方法 - 执行以下操作:

    ApplicationContext ctx;
    URL urlApplicationContext = this.getClass().getClassLoader().getResource("applicationContext.xml");
    if (urlApplicationContext != null) {
        File appCtxFile = new File(urlApplicationContext.toURI());
        ctx = new FileSystemXmlApplicationContext(new String[]{ appCtxFile.getAbsolutePath() });
    } else {
        throw new RuntimeException("Cannot find XML file 'applicationContext.xml'");
    }
    

    【讨论】:

      【解决方案2】:

      尝试添加一些调试输出。 URL 有很好的toString() 方法。因此,您将获得应用程序在哪里寻找文件。

      看起来你在一开始就错过了斜线。在资源加载器中将 data/continuous/... 替换为 /data/continuous/...

      【讨论】:

      • 您好,加载资源的方法是 this.getClass().getClassLoader().getResource("applicationContext-hibernate-junit.xml") 。 linux机器上的路径是动态检索的。我不知道您所说的“资源加载器”是什么意思?
      • getResource 只给你一个网址。然后你通过 url 加载 xml 并得到异常,因为斜杠丢失 => 路径不正确。加载此 xml 的方法我称为资源加载器。如果此方法在 Jenkins 内部,则可能是您使用错误。
      • 尝试:1)System.out.println(urlApplicationContext); 2) ctx = new FileSystemXmlApplicationContext("target/main/WEB-INF/test-classes/applicationContext.xml");
      • 谢谢谢尔盖。这行代码 ctx = new FileSystemXmlApplicationContext("target/main/WEB-INF/test-classes/applicationCon‌​text.xml");解决了这个问题。
      【解决方案3】:

      因为我没有足够的代表来投票或评论或任何我会在这里说我需要说的话lol

      Oifan 完全正确(阅读答案需要接受)。

      在 Jenkins 上遇到了同样的问题。代码在测试期间试图访问文件,路径中有空格,导致FileNotFoundException。该文件绝对位于正确的位置。

      我的测试还表明,空格是罪魁祸首。我们只是要在 Jenkins 中重命名项目,这将导致我们的目录结构中不再有空格。然后我遇到了 Oifan 的回答。

      URLgetResource() 转换为URI 并将其传递给File() 也为我们解决了这个问题。

      顺便说一句,这个问题并不局限于 linux。我在 Windows Jenkins slave 上也看到过这种行为。

      【讨论】:

        【解决方案4】:

        其实Jenkins并没有抱怨applicationContext.xml文件,而是这个:data/continuous/workspace/sonar/main_proj/target/main/WEB-INF/test-classes/applicationContext-hibernate-junit.xml

        【讨论】:

        • 原帖中有错误的复制粘贴。 Jenkins 抱怨 applicationContext.xml。我修改了帖子。
        【解决方案5】:

        为什么 getResource() 在 Linux 上找不到正确的路径。

        我认为您需要再次查看您的代码和堆栈跟踪。

        getResource() 方法不会抛出 IOExceptionIOException 的任何子类。从来没有。

        您看到的异常是由...其他东西引发的。从消息中可以清楚地看出,引发该异常的代码也不是寻找名为“applicationContext.xml”的文件。

        更新

        即使经过您的更正,getResource() 不会导致FileNotFoundException 仍然是一个不可逆转的事实。您正在查看错误的代码。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-04-17
          • 2010-10-12
          • 1970-01-01
          • 2013-01-22
          • 1970-01-01
          • 2017-08-12
          • 2023-03-21
          • 2015-04-13
          相关资源
          最近更新 更多