3

I'm trying to run a test that uses a resource in sbt. The test depends on a util that loads a resource via ClassLoader.getSystemResourceAsStream(...), which results unexpectedly in null. If I run the same test in Intellij or via bazel, the test succeeds. I additionally performed a test by creating a main class to list all resources according to the ResourceList example given in an answer to this question, and this confirmed that that file and many others were inaccessible at runtime.

These resources are not contained in the resources directories that sbt usually uses; they are contained in a jar file that is included in the lib directory. The sources in my project built by sbt depend heavily on this jar, and compilation is successful, so it appears the issue may be specific to resources. One thing I noticed is that the resource can be loaded if I use a ClassLoader object and call getResourceAsStream instead of using the static method ClassLoader.getSystemResourceAsStream.

Does anyone know how to resolve this issue (short of copying out all resources from the jar file in lib)?

jonderry
  • 23,013
  • 32
  • 104
  • 171
  • Did you tried [this](https://www.scala-sbt.org/1.0/docs/Howto-Customizing-Paths.html#Change+the+default+resource+directory) ? – Luis Miguel Mejía Suárez Jan 28 '19 at 23:01
  • That looks like instructions for setting resources that are defined as part of the project itself. I'm trying to include resources that are included in a jar that is in the `lib` directory. – jonderry Jan 28 '19 at 23:12

1 Answers1

2

Try running tests in forked JVM:

Test / fork := true

Unmanaged dependencies in lib/ should end up by default on all the classpaths, including test, without having to do anything special:

Dependencies in lib go on all the classpaths (for compile, test, run, and console).

Note, when running tests in IntelliJ you might be using IntelliJ's internal build system as opposed to SBT shell, which could be the reason why it worked in IntelliJ. To run tests in IntelliJ via sbt shell, select Use sbt checkbox in Edit Configurations...

I would suggest using getClass.getResourceAsStream, as this anyways uses system ClassLoader as 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);
    }
Mario Galic
  • 47,285
  • 6
  • 56
  • 98