为什么 Jenkins 无法加载资源?

Why Jenkins fails to load the resources?

这是我的项目布局:

src/
  test/
    resources/
        ares/
          file1.xml
          file2.xml

这是 Jenkins 工作区的布局:

 my-module/
   target/
     test-classes/
       ares/
         file1.xml
         file2.xml

在eclipse下测试运行没有任何错误。 在 Jenkins 上,测试只是失败了。 Jenkins 无法定位资源。 以下是测试执行的一些输出:

日食

MyClass.class.getResourceAsStream(/ares/file1.xml) => java.io.BufferedInputStream@4f4b2f1a
MyClass.class.getResourceAsStream(ares/file1.xml) => null

Thread.currentThread().getContextClassLoader().getResourceAsStream(/ares/file1.xml) => null
Thread.currentThread().getContextClassLoader().getResourceAsStream(ares/file1.xml) => java.io.BufferedInputStream@5d402eeb

MyClass.class.getClassLoader().getResourceAsStream(/ares/file1.xml) => null
MyClass.class.getClassLoader().getResourceAsStream(ares/file1.xml) => java.io.BufferedInputStream@20c87621

詹金斯

MyClass.class.getResourceAsStream(/ares/file1.xml) => null
MyClass.class.getResourceAsStream(ares/file1.xml) => null

Thread.currentThread().getContextClassLoader().getResourceAsStream(/ares/file1.xml) => null
Thread.currentThread().getContextClassLoader().getResourceAsStream(ares/file1.xml) => null

MyClass.class.getClassLoader().getResourceAsStream(/ares/file1.xml) => null
MyClass.class.getClassLoader().getResourceAsStream(ares/file1.xml) => null

如您所见,Jenkins 没有找到我的资源。

我错过了什么?

我终于解决了我的问题。在类路径中,文件名为 /ares/file1.xml,而在我的代码中我调用文件 /ares/file1.XML。你注意到大写的 XML 了吗?

在 Windows 上没有区别,因为文件名不区分大小写。 在 Linux 上失败,因为文件名区分大小写。

最终想法,当您在与目标平台不同的平台上编写代码时,更喜欢小写文件名

我遇到了类似症状但不同原因和不同解决方案的问题。

在我的例子中,问题是 Jenkins 服务器是一台 Windows 机器,服务器上到资源位置的完整路径以 C:\Program Files (x86)\... 和 spaces 开头.如果您需要将 space 编码为 %20,而不是使用 new File(getClass().getResource(fileName).getFile()) 的流,则这些 space 会被编码为 File。这里 fileName 是一个包含资源名称的字符串。我通过添加对 URLDecoder.decode 的调用解决了这个问题。当没有 space 或您不在 Windows 上时(据我所知),这不会产生任何问题,但是如果您在沿线某处命名。完整的调用是:

 new File(URLDecoder.decode(getClass().getResource(fileName).getFile(), "UTF-8"))

我从几个问题中拼凑了这个,但是 none 将所有这些拼凑起来用于 Jenkins 案例,因此我在这里回答。其他相关问答:

  • Java: how to get a File from an escaped URL?
  • How do you unescape URLs in Java?
  • Resource files not found from JUnit test cases

由于我在经过半天的困惑之后才解决了我的问题,所以我来到这里两次,我想我应该添加我的解决方案来帮助未来的旅行者。

Jenkins 作业名称中的空格会中断 Java 项目中资源文件的加载。除非你为了安抚 Jenkins 而专门编写不同的加载代码。

我将其归结为一条非常令人沮丧的建议:不要在 JAVA 项目的 JENKINS 工作名称中放置空格。

你可以把几点放在一起...

第一,如果你在 jenkins 作业的名称中加上 space,那么 jenkins 不会想方设法隐藏那个 space。所以调用你的工作 "My Awesome New Job" 并且工作的路径变为 /home/jenkins/My%Awesome%New%20Job

第二,如果您的资源路径中有 %20,那么您的代码将需要 URL 解码资源路径以便能够加载资源。就像让我到达那里的另一个答案一样:

在我的情况下,这些资源文件仅用于测试,所以我只是用连字符替换了工作名称中的 space。