【问题标题】:Unable to get a resource when running an main class or test in sbt在 sbt 中运行主类或测试时无法获取资源
【发布时间】:2019-01-30 19:55:11
【问题描述】:

我正在尝试运行一个使用 sbt 中的资源的测试。该测试依赖于通过ClassLoader.getSystemResourceAsStream(...) 加载资源的实用程序,这会意外导致null。如果我在 Intellij 或通过 bazel 运行相同的测试,则测试成功。我还根据this question 的答案中给出的ResourceList 示例通过创建一个主类来列出所有资源进行了测试,这证实了该文件和许多其他文件在运行时无法访问。

这些资源不包含在 sbt 通常使用的resources 目录中;它们包含在一个 jar 文件中,该文件包含在 lib 目录中。我的项目中由 sbt 构建的源在很大程度上依赖于这个 jar,并且编译成功,所以看起来问题可能是特定于资源的。我注意到的一件事是,如果我使用ClassLoader 对象并调用getResourceAsStream 而不是使用静态方法ClassLoader.getSystemResourceAsStream,则可以加载资源。

有谁知道如何解决这个问题(没有从lib 的jar 文件中复制出所有资源)?

【问题讨论】:

  • 你试过this吗?
  • 这看起来像是设置资源的说明,这些资源被定义为项目本身的一部分。我正在尝试包含 lib 目录中的 jar 中包含的资源。

标签: scala sbt


【解决方案1】:

尝试在forked JVM 中运行测试:

Test / fork := true

lib/ 中的Unmanaged dependencies 应该默认在所有类路径上结束,包括test,而无需做任何特别的事情:

lib 中的依赖关系在所有类路径上(对于 compiletestrun、 和console)。

注意,在 IntelliJ 中运行测试时,您可能使用的是 IntelliJ 的内部构建系统,而不是 SBT shell,这可能是它在 IntelliJ 中工作的原因。要通过 sbt shell 在 IntelliJ 中运行测试,请选中 Edit Configurations... 中的 Use sbt 复选框

我建议使用getClass.getResourceAsStream,因为无论如何这都使用系统 ClassLoader 作为fallback

     public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
    }

【讨论】:

    猜你喜欢
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 2018-11-09
    • 1970-01-01
    • 1970-01-01
    • 2014-03-01
    • 1970-01-01
    • 2011-03-28
    相关资源
    最近更新 更多