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

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").

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

Related

object mockito is not a member of package org

Relatively new to sbt and Mockito.
I want to use Mockito in tests, but I'm getting errors related to the Mockito imports when I compile the tests
Imports in test file:
import org.scalatest._
import org.mockito.Mockito._
import org.scalatest.mockito.MockitoSugar
sbt file:
name := "blah"
version := "0.1"
scalaVersion := "2.13.0"
libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.8"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % "test"
libraryDependencies += "org.mockito" % "mockito-core" % "1.8.5" % "test"
I get these error messages when the tests (fail to) compile:
object mockito is not a member of package org [error] import org.mockito.Mockito._
and also:
Symbol 'type org.mockito.MockSettings' is missing from the classpath.
[error] This symbol is required by 'value org.scalatest.mockito.MockitoSugar.mockSettings'.
I've had a play around with changing some of the versions of scalatest and mockito in the sbt file, but not really if that's getting at the root of the problem or not.
Thanks for any help!
You're using a very old version of Mockito, which is older than the one Scalates relies on, you probably need some 2.x.x version.
On the other hand, I'd recomend you to go fo mockito-scala rather than mockito-core and skip the Scalatest provided classes altogether as they are quite basic.
I suspect you have a caching problem. This happens especially with Intellij.
Here 2 ideas:
Reload the sbt project. See https://stackoverflow.com/a/20466144/2750966
Close the project / delete .idea an open the project newly with Intellij.
Let me know if it is not related with Intellij

Not found object error when importing external library in intellij

Here is my sbt file myproject/build.sbt
version := "1.0"
scalaVersion := "2.12.1"
libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-actor" % "2.4.16",
"io.circe" %% "circe-core" % "0.6.1",
"io.circe" %% "circe-generic" % "0.6.1",
"io.circe" %% "circe-parser" % "0.6.1"
)
Here is my scala file myproject/src/test.scala
package mytest
import akka._
object test {
def main(args: Array[String]) {
print(2)
}
}
I verified that my external library contains, akka
but intellij keep saying that
Error:(7, 8) not found: object akka
import akka._
I am using intellij community edition 2016.3 with the latest scala plugin (which should include latest sbt)
Can someone give me a hint on how to resolve this?
To fix the problem, you have to place your Scala source file into src/main/scala directory. Otherwise IntelliJ/SBT can't recognize it as file related to the project, so it can't associate project dependencies with it.
By default Scala source files can be placed either in the root directory of your project, or in src/main/scala (for main sources, there is also src/test/scala for tests).
If you want to use some other directories to store your Scala source files, you can configure it this way in your build.sbt:
sourceDirectories in Compile += new File("src")
I had a similar problem and it was nothing to do with the directory structure in my case. IntelliJ asks you to refresh when you add a new dependency in build.sbt. I also manually refreshed it form the SBT Shell and still same error.
In the end I closed the project and re-opened and it was fixed.

SBT remote debugging works in intellij but not when executing tests

I execute the following command in the terminal sbt -jvm-debug 9999 and start a remote debug configuration with default values in Intellij 15.0.4-1. Next I execute the sbt task run and breakpoints work as expected. When I execute the test task instead debugging wont work anymore despite the fact that the same code gets executed.
Using play-scala activator seed with Play Framework 2.4. Tests are written in spec2.
Has anyone an idea what I might do wrong?
Here is my code:
Class DebugTest.scala
object DebugTest {
def helloWorld(): Unit ={
println("Oh my")
}
}
Class ApplicationSpec.scala
import org.specs2.mutable._
import play.api.test._
import play.api.test.Helpers._
class ApplicationSpec extends Specification {
"Application" should {
"just print oh my in console" in new WithApplication{
DebugTest.helloWorld()
}
}
}
File build.sbt
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.11.7"
libraryDependencies ++= Seq( jdbc,
ws,
specs2 % Test,
"org.webjars.bower" % "adminlte" % "2.3.3",
"org.pac4j" % "play-pac4j" % "2.2.0-SNAPSHOT",
"org.pac4j" % "pac4j-http" % "1.9.0-SNAPSHOT",
"com.typesafe.play" % "play-cache_2.11" % "2.4.6"
)
resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
resolvers += "Sonatype snapshots repository" at "https://oss.sonatype.org/content/repositories/snapshots/"
routesGenerator := InjectedRoutesGenerator
fork in run := true
fork in test := false
File test.sbt
fork in test := false
Play sbt plugin defines the following setting:
fork in Test := true
So, when you are launching your tests, a different jvm is started (without remote debugging).
You just have to add in your build.sbt:
fork in Test := false
You could even create a test.sbt file containing only that line and ignore it from your source control.
This should only be used during debugging. After, please come back to the default behavior; or you can get unexpected results when launching tests multiple times in the same sbt session.

Why does sbt give "object scalacheck is not a member of package org" after successful scalacheck resolve?

I have added the following in build.sbt:
libraryDependencies <<= scalaVersion { scala_version => Seq(
<other entries>
"org.scalacheck" %% "scalacheck" % "1.10.0" % "test",
<other entries>
)
}
Upon compile the project in sbt, the dependencies are resolved successfully as can be seen in the logs:
[info] Resolving org.scalacheck#scalacheck_2.9.1;1.10.0 ...
...
Done updating
However, I get the following error during compilation of one file.
object scalacheck is not a member of package org
import org.scalacheck.Gen
^
What can be the reason for this?
Is there a way to see the classpath that sbt is using during the compile task?
Sbt version: 0.11.2
OS: Windows 7
Scala version: 2.9.1
Note that the project builds fine in ScalaIDE. (I use sbteclipse to generate the eclipse .classpath file. The generated .classpath has proper scalacheck entry.)
The way you import the dependency makes Scalacheck only available for the command test:
"org.scalacheck" %% "scalacheck" % "1.10.0" % "test"
You should use:
"org.scalacheck" %% "scalacheck" % "1.10.0"
But why do you use Scalacheck somewhere else than in tests ? See this link for more explanations about testing in sbt.

How to set up managed dependencies in an SBT 0.11 project having Build.scala

I am building a simple Scala project with SBT 0.11.
All the code files are in ~/MyProject/src/main/scala/
~/MyProject/build.sbt is the following
name := "MyProject"
version := "1.0"
scalaVersion := "2.9.1"
libraryDependencies ++= Seq(
"mysql" % "mysql-connector-java" % "5.1.+",
"c3p0" % "c3p0" % "0.9.1.2",
"org.apache.commons" % "commons-lang3" % "3.0.1",
"commons-lang" % "commons-lang" % "2.6",
"javassist" % "javassist" % "3.12.1.GA"
)
~/MyProject/project/Build.scala is the following
import sbt._
object MyProjectBuild extends Build {
lazy val MyProject = Project("MyProject", file("."))
}
This seems to work almost fine. The project does compile and run. The project name is set correctly (if I don't use Build.scala, then the name seems to appear something like "default-????", despite it being specified in build.sbt).
But the problem is that dependencies do not seem to work - update command doesn't download anything. How to fix this? Do I need to specify my dependencies in Build.scala rather than in build.sbt in this case?
Is it possible that you've already retrieved the project dependencies, but don't realize it because they are stored in the Ivy cache? You can view the managed classpath from the SBT console with the command
show managed-classpath
Recent versions of SBT do not store the managed dependencies in the project directory, unless the project is configured to do so. If you want, you can add the following to your build.sbt file:
retrieveManaged := true
This will create a ~/MyProject/lib_managed/ directory and contents.