New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scala ClassLoader breaks nio FileSystemProvider API #10247

Open
scabug opened this Issue Mar 23, 2017 · 12 comments

Comments

Projects
None yet
5 participants
@scabug
Copy link

scabug commented Mar 23, 2017

java.nio.file.spi.FileSystemProvider loads implementations using ClassLoader.getSystemClassLoader().

However, Scala uses a system ClassLoader that doesn't search among JARs on the classpath, resulting in it being impossible to use custom FileSystemProvider implementations.

As an example, try running the google-cloud-nio example; here is a gist showing shell cmds and output.

When the same example JAR is run with java -cp … and scala -cp …, the former finds the custom FileSystemProvider (gs scheme) but the latter doesn't.

I'm currently planning to use this workaround to call FileSystemProvider.loadInstalledProviders while the system classloader is temporarily overwritten to Thread.currentThread().getContextClassLoader, which properly finds FileSystemProvider implementations in user-supplied JARs.

This SO provides basically the same analysis and diagnosis.

@scabug

This comment has been minimized.

Copy link
Author

scabug commented Mar 23, 2017

Imported From: https://issues.scala-lang.org/browse/SI-10247?orig=1
Reporter: Ryan Williams (rdub)
Affected Versions: 2.11.8, 2.12.1

@scabug scabug added the repl label Apr 7, 2017

@som-snytt

This comment has been minimized.

Copy link

som-snytt commented Apr 7, 2017

Using scala -toolcp path makes your app jar available to the system class loader.

Or, use the API where you can provide the class loader to find providers which are not "installed."

This example shows loading a test provider from a build dir.

$ skala -toolcp ~/bin
Welcome to Scala 2.12.2 (OpenJDK 64-Bit Server VM 1.8.0_112)

scala> import java.nio.file.spi.FileSystemProvider
import java.nio.file.spi.FileSystemProvider

scala> FileSystemProvider.installedProviders
res0: java.util.List[java.nio.file.spi.FileSystemProvider] = [sun.nio.fs.LinuxFileSystemProvider@12abdfb, com.acme.FlakeyFileSystemProvider@b0e5507, com.acme.FlakeyTPDFileSystemProvider@6bbe50c9, com.sun.nio.zipfs.ZipFileSystemProvider@3c46dcbe]

scala> :quit

Or specifying loader:

$ skala -cp ~/bin
Welcome to Scala 2.12.2 (OpenJDK 64-Bit Server VM 1.8.0_112)

scala> import java.net.URI
import java.net.URI

scala> val uri = URI.create("tpd:///?count=10000")
uri: java.net.URI = tpd:///?count=10000

scala> import collection.JavaConverters._
import collection.JavaConverters._

scala> val em = Map.empty[String, AnyRef].asJava
em: java.util.Map[String,AnyRef] = {}

scala> import java.nio.file.FileSystems
import java.nio.file.FileSystems

scala> FileSystems.
getDefault   getFileSystem   newFileSystem

scala> FileSystems.newFileSystem(uri, em, $intp.classLoader)
res1: java.nio.file.FileSystem = com.acme.FlakeyFileSystemProvider$FlakeyFileSystem@2553dcc0

@ryan-williams

This comment has been minimized.

Copy link

ryan-williams commented Apr 19, 2017

Thanks for these workarounds, @som-snytt!

Unfortunately I'm not sure that either one works very well for me:

  • I'm running Spark apps and afaik there's no way to pass -toolcp through to Spark in all the places where that would need to happen; even if it were possible, it will surely add some tooling headaches as I'd need to either specify my JAR twice on the cmdline, add a layer of scripting to remove that, break existing scripts around launching Spark apps, etc.
  • The FileSystems.newFileSystem is really good to know about, but I'd have to do it every time I create a Path, or more likely wrap all Paths.creates in a try that falls back to creating the filesystem (maybe caching them per-uri-scheme, since they don't get reused otherwise?).

Can we also have some conversation about why Scala doesn't have this Just Work? I assume there is no Good Reason for it, but rather that it's an unfortunate side-effect of something well under the hood of what most Scala users know or care to know about… is there any hope of "fixing" this?

@som-snytt

This comment has been minimized.

Copy link

som-snytt commented Apr 20, 2017

That's a good question. Maybe there's a good reason for Spark to update its script. You can "install" Scala in the ext/lib directory of your Java installation, along with your jars, IIRC. It's been a long time since I resorted to that.

@ryan-williams

This comment has been minimized.

Copy link

ryan-williams commented Apr 20, 2017

That's a good question. Maybe there's a good reason for Spark to update its script.

Not sure I follow; is using -toolcp better than -cp in general, or would Spark and downstream libraries be using -toolcp just to work around this issue with the Scala classloader?

I assume the latter, which seems like a non-starter to me, at least until we get a straight answer about why Scala is doing this and what fixing the problem at its source would entail.

You can "install" Scala in the ext/lib directory of your Java installation, along with your jars, IIRC.

Sorry, I'm missing what this is supposed to solve or why.

Per the above, I'd like to discuss why Scala is doing this and what it would take to fix it, though I appreciate the thorough exploration of the space of possible work-arounds 😎.

@som-snytt

This comment has been minimized.

Copy link

som-snytt commented Apr 20, 2017

You can drop your filesystem.jar in ext/lib and it will be visible to the system class loader. I think that's what "installed" means. But I don't think you're interested in doing that.

I just spent some time refreshing my understanding: basically, you're saying that invoking the runner script with scala -classpath my.jar:. MyMain should put my.jar on the java classpath. Right now, the arguments to java are switched around, so the command is java MainGenericRunner -classpath my.jar:..

Just guessing, but that might be because the same script is used for both scala and scalac.

Here's an issue: lampepfl/dotty#44

In 2.13, they want more flexible module handling, and also use the Java 9 modules, so now might be a good time to start or join a conversation on their discussion site, or mention it on gitter. In fact, I'll go mention it now.

To reiterate, this isn't an issue with ScalaClassLoader, just with the scala script that assembles the java command that runs your program.

The confusing options are -nobootcp and -Dscala.usejavacp=false. Only -toolcp gets your jar on the system class path, i.e., java's -classpath.

You could also consider using -Djava.system.class.loader but again, if you're not able to set -toolcp then that is out of scope for you. I do suspect that the alternative API, where you supply the classloader, is the most correct and robust.

@SethTisue

This comment has been minimized.

Copy link
Member

SethTisue commented Feb 7, 2018

@som-snytt should this issue be closed? the combination of "out of scope" yet remaining open is confusing

@som-snytt

This comment has been minimized.

Copy link

som-snytt commented Feb 7, 2018

@SethTisue I always confuse "out of scope" with "out of rope."

I'll try to confirm that I said something correct in the thread and whether the request that it just work can be met. The class loader fix happened since then.

@ryan-williams

This comment has been minimized.

Copy link

ryan-williams commented Feb 8, 2018

As an update, I've been using a wrapper around nio.Path that hooks into Path construction, checks whether some FileSystem/classpath-munging has occurred to work around this issue, and does the FileSystem/classpath-munging if not (involving reflection to modify private java stdlib global vars 😔); relevant docs.

That got me unblocked, but I don't think a world where [everyone who wants to use JSR203 libraries from Scala] has to [use my library or roll their own similar library] is desirable.

I'm also a little confused that this hasn't come up more widely / there aren't others mentioning that they've run into this; I thought folks I work with in the ADAM universe (cf. linked issue above) would have, but perhaps they and everyone else primarily use the analogous HDFS FileSystem APIs (that JSR203 was meant to mimic/replace, IIUC)?

Anyway, I'll defer to y'all about what level of fixing, further documenting recommended workarounds, #wontfix'ing, etc. is the right outcome here, thanks.

@gourlaysama

This comment has been minimized.

Copy link
Member

gourlaysama commented Feb 8, 2018

I think this is more of a Spark problem (and/or bad design in the JDK):

I'm also a little confused that this hasn't come up more widely / there aren't others mentioning that they've run into this

I suppose it is because people don't use the scala launcher script in production. You end up packaging your app/service/whatever, and what you use to do that (sbt-native-packager for example) generates a launcher script for your thing that looks like:

java [-Xms, -Xmx, ...] -cp [~full classpath, including scala & your fs~] YourMainClass

And that will make everything work just fine. I don't want the scala script on my server anyway, it comes with the compiler, repl, ... and those don't belong there.

(As for the dev experience, in sbt you need to enable forking when running/testing, and then everything works the same. It is annoying that it doesn't Just Work™ in the REPL though.)

I have no idea how Spark does all this, or if they allow users to easily inject stuff onto the classpath of Spark itself, but that's what you would need.

@som-snytt

This comment has been minimized.

Copy link

som-snytt commented Feb 8, 2018

I do use REPL scripting on my server, so it should just work. Right now it looks pretty broken. With the need for Java 9 support, it's a good time to revisit what does it think it's doing?

Here's the REPL class loader, which is more precise than -Ylog-classpath.

It wasn't intended to put ./"" on the class path; maybe that suffered in a refactor. There's still a comment in the script about the perils of quoting or losing quotes. And one effect of the war to keep dot off the class path is specifying an empty path.

I did a quick munge of the script that just puts the Scala user -classpath on the Java -classpath. The present use case for service loading just works. Maybe another use case breaks?

I don't know that there is any benefit in the current set-up, where a special class loader takes over. The runner code can still use a ScalaClassLoader that delegates to the app class loader without any loss of ergonomics.

# scala -usebootcp -cp lib/gcs-nio.jar

$ SCALA_RUNNER_DEBUG=true $SCALA_HOME/bin/scala -usebootcp -Dscala.usejavacp=true -cp lib/gcs-nio.jar
saved stty:
4500:5:bf:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

/usr/lib/jvm/jdk1.8.0/bin/java
-Xmx256M
-Xms32M
-Dscala.usejavacp=true
-Xbootclasspath/a:/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar:/home/amarki/scala-2.12.4/lib/scala-compiler.jar:/home/amarki/scala-2.12.4/lib/scala-library.jar:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar:/home/amarki/scala-2.12.4/lib/scala-reflect.jar:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar
-classpath
""
-Dscala.boot.class.path=/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar:/home/amarki/scala-2.12.4/lib/scala-compiler.jar:/home/amarki/scala-2.12.4/lib/scala-library.jar:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar:/home/amarki/scala-2.12.4/lib/scala-reflect.jar:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar
-Dscala.home=/home/amarki/scala-2.12.4
-Denv.emacs=
scala.tools.nsc.MainGenericRunner
-Dscala.usejavacp=true
-cp
lib/gcs-nio.jar

# show(getClass.getClassLoader)

scala.tools.nsc.interpreter.IMain$TranslatingClassLoader@5bb3131b of type class scala.tools.nsc.interpreter.IMain$TranslatingClassLoader with classpath [(memory)] and

parent being scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@69b1e8f8 of type class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader with classpath

[file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/resources.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jsse.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jce.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/charsets.jar,file:/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar,file:/home/amarki/scala-2.12.4/lib/scala-compiler.jar,file:/home/amarki/scala-2.12.4/lib/scala-library.jar,file:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar,file:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar,file:/home/amarki/scala-2.12.4/lib/scala-reflect.jar,file:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar,file:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/dnsns.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/nashorn.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/zipfs.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/icedtea-sound.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunjce_provider.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/localedata.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunpkcs11.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunec.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/cldrdata.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/jaccess.jar,file:/home/amarki/snips/lib/gcs-nio.jar]

and parent being sun.misc.Launcher$AppClassLoader@ed17bee of type class sun.misc.Launcher$AppClassLoader with classpath

[file:/home/amarki/snips/%22%22]

and parent being sun.misc.Launcher$ExtClassLoader@77468bd9 of type class sun.misc.Launcher$ExtClassLoader with classpath

[file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/dnsns.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/nashorn.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/zipfs.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/icedtea-sound.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunjce_provider.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/localedata.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunpkcs11.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunec.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/cldrdata.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/jaccess.jar]

and parent being primordial classloader with boot classpath

[/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/resources.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jsse.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jce.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/charsets.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jfr.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/classes:/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar:/home/amarki/scala-2.12.4/lib/scala-compiler.jar:/home/amarki/scala-2.12.4/lib/scala-library.jar:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar:/home/amarki/scala-2.12.4/lib/scala-reflect.jar:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar]

with -nobootcp

# scala -nobootcp -cp lib/gcs-nio.jar

$ SCALA_RUNNER_DEBUG=true $SCALA_HOME/bin/scala -nobootcp -Dscala.usejavacp=true -cp lib/gcs-nio.jar
saved stty:
4500:5:bf:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

/usr/lib/jvm/jdk1.8.0/bin/java
-Xmx256M
-Xms32M
-Dscala.usejavacp=true
-classpath
/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar:/home/amarki/scala-2.12.4/lib/scala-compiler.jar:/home/amarki/scala-2.12.4/lib/scala-library.jar:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar:/home/amarki/scala-2.12.4/lib/scala-reflect.jar:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar
-Dscala.home=/home/amarki/scala-2.12.4
-Denv.emacs=
scala.tools.nsc.MainGenericRunner
-Dscala.usejavacp=true
-cp
lib/gcs-nio.jar

# show(getClass.getClassLoader)

scala.tools.nsc.interpreter.IMain$TranslatingClassLoader@67b355c8 of type class scala.tools.nsc.interpreter.IMain$TranslatingClassLoader with classpath [(memory)]

and parent being scala.reflect.internal.util.ScalaClassLoader$URLClassLoader@598778cc of type class scala.reflect.internal.util.ScalaClassLoader$URLClassLoader with classpath

[file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/resources.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jsse.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jce.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/charsets.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/dnsns.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/nashorn.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/zipfs.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/icedtea-sound.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunjce_provider.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/localedata.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunpkcs11.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunec.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/cldrdata.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/jaccess.jar,file:/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar,file:/home/amarki/scala-2.12.4/lib/scala-compiler.jar,file:/home/amarki/scala-2.12.4/lib/scala-library.jar,file:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar,file:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar,file:/home/amarki/scala-2.12.4/lib/scala-reflect.jar,file:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar,file:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar,file:/home/amarki/snips/lib/gcs-nio.jar]

and parent being sun.misc.Launcher$AppClassLoader@74a14482 of type class sun.misc.Launcher$AppClassLoader with classpath

[file:/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar,file:/home/amarki/scala-2.12.4/lib/scala-compiler.jar,file:/home/amarki/scala-2.12.4/lib/scala-library.jar,file:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar,file:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar,file:/home/amarki/scala-2.12.4/lib/scala-reflect.jar,file:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar,file:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar]

and parent being sun.misc.Launcher$ExtClassLoader@5524cca1 of type class sun.misc.Launcher$ExtClassLoader with classpath

[file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/dnsns.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/nashorn.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/zipfs.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/icedtea-sound.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunjce_provider.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/localedata.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunpkcs11.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/sunec.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/cldrdata.jar,file:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext/jaccess.jar]

and parent being primordial classloader with boot classpath

[/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/resources.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jsse.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jce.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/charsets.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jfr.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/classes]

Modified:

$ SCALA_RUNNER_DEBUG=true $SCALA_HOME/bin/scala -usebootcp -classpath lib/gcs-nio.jar saved stty:
4500:5:bf:8a3b:3:1c:7f:15:4:0:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

/usr/lib/jvm/jdk1.8.0/bin/java
-Xmx256M
-Xms32M
-Xbootclasspath/a:/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar:/home/amarki/scala-2.12.4/lib/scala-compiler.jar:/home/amarki/scala-2.12.4/lib/scala-library.jar:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar:/home/amarki/scala-2.12.4/lib/scala-reflect.jar:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar
-classpath
lib/gcs-nio.jar
-Dscala.boot.class.path=/home/amarki/scala-2.12.4/lib/jline-2.14.5.jar:/home/amarki/scala-2.12.4/lib/scala-compiler.jar:/home/amarki/scala-2.12.4/lib/scala-library.jar:/home/amarki/scala-2.12.4/lib/scalap-2.12.4.jar:/home/amarki/scala-2.12.4/lib/scala-parser-combinators_2.12-1.0.6.jar:/home/amarki/scala-2.12.4/lib/scala-reflect.jar:/home/amarki/scala-2.12.4/lib/scala-swing_2.12-2.0.0.jar:/home/amarki/scala-2.12.4/lib/scala-xml_2.12-1.0.6.jar
-Dscala.home=/home/amarki/scala-2.12.4
-Dscala.usejavacp=true
-Denv.emacs=
scala.tools.nsc.MainGenericRunner

Welcome to Scala 2.12.4 (OpenJDK 64-Bit Server VM, Java 1.8.0_151).
Type in expressions for evaluation. Or try :help.

scala> java.nio.file.spi.FileSystemProvider.installedProviders
res0: java.util.List[java.nio.file.spi.FileSystemProvider] = [sun.nio.fs.LinuxFileSystemProvider@31c628e7, com.sun.nio.zipfs.ZipFileSystemProvider@3240b2a4, CloudStorageFileSystemProvider{storage=com.google.cloud.storage.StorageImpl@120d3fd}]
@som-snytt

This comment has been minimized.

Copy link

som-snytt commented Feb 8, 2018

I haven't looked at whether sbt supports forking when running the console. Hopefully any wrinkle could be ironed out. Similarly, folks did work for Spark to support adding jars to the compiler class path, so this is a natural use case. Maybe some future REPL will support that in a natural way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment