Custom NIO filesystem doesn't load through SBT's test task

229 views Asked by At

For testing, I'm using an in-memory NIO FileSystem implementaion ( memoryfs ). I've taken advantage of it before, and it seems to run fine through e.g. Maven.

However, now, in an SBT project, it's impossible to initialize a new FileSystem.

Here's a minimal SBT configuration to reproduce the problem:

import sbt._
import Keys._

name := "testfs"
organization := "com.example
version := "0.1-SNAPSHOT"

scalaVersion := "2.11.6"

libraryDependencies ++= { 
  val scalaTestVersion = "2.2.5"
  Seq(
    "org.scalatest" %% "scalatest" % scalaTestVersion % "test",
    "org.mockito" %  "mockito-core" % "1.10.19" % "test",
    "de.pfabulist.lindwurm" %  "memoryfs" % "0.28.3"   % "test"
  )}

And here's a test:

import de.pfabulist.lindwurm.memory.MemoryFSBuilder
import org.scalatest.{FlatSpec, MustMatchers}


class FsDummySpec extends FlatSpec with MustMatchers {

  it must "init the FS" in {
    new MemoryFSBuilder().watchService(true).name("testFs").build() //init here
  }
}

Running sbt test will result in:

[info] FsDummySpec:
[info] - must init the FS *** FAILED ***
[info]   java.nio.file.ProviderNotFoundException: Provider "memoryfs" not found
[info]   at java.nio.file.FileSystems.getFileSystem(FileSystems.java:224)
[info]   at de.pfabulist.kleinod.paths.Pathss.getOrCreate(Pathss.java:76)

Here's the thing: this should run without any problems. My question is: why, and how to fix it?

Glancing over the custom FS provider docs it looks like SBT borks the classpath somehow, but its hard to say why.

Note: interestingly enough, IntelliJ IDEA's test runner seems to work without a hitch, the problem is only on the command line (in "SBT proper").

1

There are 1 answers

0
mikołak On BEST ANSWER

The comment by openCage hinted at the solution.

It turns out custom file systems do require an additional element, i.e. a service provider definition file located in META-INF/services.

If you use a custom NIO FileSystem, you need to make that provider definition file available in the test classpath.

The simplest way is probably just to fork the test VM, i.e. add the following to your build.sbt:

fork in Test := true