Sbt forking issue

I’ve been having problems with sbt. Previously to get around one of the problems, I was forking and setting java.library.path like this:

javaOptions += "-Djava.library.path=" + file(".").getAbsolutePath

The down side to this is that the program did not echo characters correctly when doing interactive work (it was if it was buffering output until input was entered and then displayed it afterwards).

However, now things have moved on (perhaps software has updated) and I’m getting the following problem:

i) If I do not fork, the first time I run a program from the sbt interactive mode (i.e. by just loading up sbt), the program works fine. When the program exits correctly through System.exit(0), the next time the program runs, I get a java.lang.UnsatisfiedLinkError: no lib***java in java.library.path and to fix it, I have to exit sbt and reload. It will then work on the first run in a new sbt session.

ii) If I do fork, when the program is in a loop, it phantomly reads input and echos “unrecognised input” - the output comes from my program (shown below), and will do this as if in an infinite loop and the console quickly fills up with the output.

My sbt file is:

ThisBuild / scalaVersion     := "2.13.1"
ThisBuild / version          := "0.1.0-SNAPSHOT"
ThisBuild / organization     := "com.example"
ThisBuild / organizationName := "example"

lazy val root = (project in file("."))
  .settings(
    name := "myproj",
    
    libraryDependencies += "org.typelevel" %% "cats-core" % "2.0.0",
    libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2",
   
//    fork := true,
     javaOptions += "-Djava.library.path=" + file(".").getAbsolutePath,
    
    scalacOptions ++= Seq("-deprecation", "-feature", "-Xfatal-warnings"),
    
  )

My runner is:

def run(): Unit = {

  var continue = true
  while(continue) {
    for ((cmd, i) <- availableCommands.zipWithIndex) {
      println(s"$i: ${cmd.name}")
    }
    try {
      val input = scala.io.StdIn.readLine("> ").toInt
      continue = runCommand(input)
    }
    catch {
       case ex: NumberFormatException =>
         println("unrecognised command - please enter a number")
    }
  }
}

The infinite loop output is

[info] > unrecognised command - please enter a number
[info] 0: Exit
[info] > unrecognised command - please enter a number
[info] 0: Exit
[info] > unrecognised command - please enter a number
[info] 0: Exit
...

(where Exit is the only command I have written).

It seems like not forking gives the best interactive experience, but I have to reload sbt after each program run, which takes 5-10secs each time - which I would like to not do.

Has anyone had this problem?

(I think the second case may be a problem with readLine() since when I replace it with readInt() it errors with end of input found, even when no data has been entered, but that doesn’t explain why it does this nor the forking issue)

I’m guessing, but does setting connectInput help, as per https://www.scala-sbt.org/1.x/docs/Forking.html ?

Yes, that helps - thanks. I must have had it in a previous config then removed it.

Any idea why non-forking would load libraries on the first run only?