2010-11-08 59 views
8

如在Scala邮件列表中的this thread中所述,我如何创建一个嵌入式Scala REPL,它继承父程序的类路径?假设父级Scala程序使用scala -cp <classpath> ...启动;可以将<classpath>作为字符串访问并用于初始化嵌入式REPL? (该的Java类路径,通过System.getProperty("java.class.path")可用,似乎从Scala的类路径有所不同。)嵌入式Scala REPL继承父类路径

或者,也许嵌入式斯卡拉REPL可以继承或从父进程构建其类加载器(迈克尔Dürig的ScalaDays 2010的谈话可能有关)。这是推荐的方法吗?

+0

我从来没有听说过斯卡拉翻译。我在哪里可以得到它? – ziggystar 2011-06-26 19:20:06

+0

解释器我的意思是Scala REPL。它带有Scala编译器。这是从命令行执行'scala'可执行文件时得到的结果。这个问题是关于在正在运行的Scala程序中嵌入REPL的。 – 2011-06-27 04:20:42

+0

我编辑了你的答案,以反映你的意思是REPL。 – ziggystar 2011-06-27 07:10:31

回答

6

我试图做同样的事情,我只是找到了一种方法我出由Googling

lazy val urls = java.lang.Thread.currentThread.getContextClassLoader match { 
    case cl: java.net.URLClassLoader => cl.getURLs.toList 
    case _ => error("classloader is not a URLClassLoader") 
} 
lazy val classpath = urls map {_.toString} 

上面的代码可以让你在当前上下文类路径。

settings.classpath.value = classpath.distinct.mkString(java.io.File.pathSeparator) 

把它放到你的settings.classpath中,你应该能够启动调度或任何你需要的库。

+0

谢谢,这很有用。我已经解决的解决方法是使用Java类路径环境变量(即'$ CLASSPATH')而不是Scala类路径。 Java类路径由嵌入式解释器继承,然后使用“usejavacp”选项。 – 2011-06-26 21:52:10

2

设置usejavacp属性为true:

val settings = new scala.tools.nsc.Settings 
settings.usejavacp.value = true 
+0

这种技术似乎没有将_Scala_类路径添加到新创建的解释器中。如'scala.tools.nsc.StandardScalaSettings.scala'中所记录,此选项仅包含classpath解析中的'java.class.path'。 – 2010-11-08 21:41:49

+0

查看https://lampsvn.epfl.ch/trac/scala/wiki/Classpath和http://lampsvn.epfl.ch/svn-repos/scala/scala-msil/trunk/上的相关源代码src/compiler/scala/tools/util/PathResolver.scala 这些描述当前的类路径处理相当详细。 – michid 2010-11-09 09:19:15

+0

我不确定如何使用此信息。有没有办法在当前执行的程序中访问scala.tools.util.PathResolver的实例?如果是这样,我可以重用它的设置对象为我创建的嵌入式解释器。 – 2010-11-10 20:57:50

1

似乎没有要访问“Scala的类路径”从运行的Scala程序中(与一个简单的方法,在“Java类路径”是通过java.class.path系统属性可用)。人们想要访问例如在scala.tools.PathResolver的情况下的字段Calculated.userClasspath,但后者似乎不可访问。也许最简单的解决方法是修改scala启动脚本以将-classpath参数字符串存储在环境变量中。

假设所需的Scala类路径可以被确定,它可以通过被传递到嵌入的Scala解释: settings.classpath.value = ...

更新:虽然Scala的类路径串可以不从Scala的运行时直接实现,@ Eugene指出,它可以从上下文类加载器中提取。谢谢。