类路径的问题在斯卡拉国米preTER结合实例时 [英] Classpath issue when binding an instance in a Scala Interpreter

查看:213
本文介绍了类路径的问题在斯卡拉国米preTER结合实例时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经张贴在斯卡拉郎论坛这个问题,但不幸的是我没有得到任何答复。
第二次机会?

I already posted this question in scala lang forum but unfortunately I did not get any answer. Second chance ?

我试图嵌入一个跨preTER的评估阶段进入这个跨preTER。我想国米preTER内的自定义类的实例绑定。总结起来,将是这样的:

I try to embed an interpreter an evaluate a scala snippet into this interpreter. I would like to bind an instance of a custom class within the interpreter. To sum up that would look like:

import scala.tools.nsc._
import scala.tools.nsc.interpreter._

class C {
  def sayHello(s:String) = "hello "+s
}

object Main extends App {

 val c= new C

 val s = new Settings
 s.usejavacp.value=true

 val i = new IMain(s)
 i.bind("myC",c)
 i.bind("world","the world")

 val script = "println(myC.sayHello(world))"
 i.eval(script)   

}

当我运行Eclipse(开普勒)这里面片段 - OpenJDK6 / 7的作品为 - BSD操作系统斯卡拉-2.11.0-M4 - 斯卡拉 - compiler.jar路径正常工作
如果我尝试运行REPL一个scalac file.scala内或直接用同样的code,那么斯卡拉-cp。主要出现以下错误

When I run this snippet inside Eclipse (Kepler) - OpenJDK6/7 works for both - BSD OS Scala-2.11.0-M4 - scala-compiler.jar in the path it works fine If I try to run the same code inside the repl or directly with a scalac file.scala then scala -cp . Main I get the following error

    error: not found value myC
    javax.script.ScriptException: compile-time error
    at scala.tools.nsc.interpreter.IMain.compile(IMain.scala:575)
    at scala.tools.nsc.interpreter.IMain.eval(IMain.scala:997)
    at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)

我能够使它在另一个操作系统(Win7的)工作,但通过添加s.bootclasspath =路径/要/我的/班

I was able to make it work under another OS (Win7) but by adding s.bootclasspath="path/to/my/classes"

我怀疑一些类路径的问题。

I suspect some classpath issue

后来我能够使其通过Java调用这种方式取代了Scala的命令行调用运行:
java命令$ CLASSPATH主要含CLASSPATH斯卡拉库,它的工作原理

Later I was able to make it run by replacing the scala command line call by a java call this way: java -cp $CLASSPATH Main with CLASSPATH containing scala libraries it works

我看着斯卡拉命令,它是像它在追加以不同的方式在java路径的Scala库。

I looked at scala command and it is like it appends scala libraries in the java path in a different way.

有没有人有什么建议吗?

Does anyone has any advice ?

感谢

根据以下意见补充:

Scalac不输出任何误差
事实上,如果我运行:

Scalac does not output any error In fact if I run:

  java -cp .:$SCALA_PATH/lib/scala-library.jar:$SCALA_PATH/lib/scala-compiler.jar:$SCALA_PATH/lib/scala-reflect.jar Main

或建议斯卡拉-nobootcp它的工作原理(感谢您的宝贵意见)
否则,如果我让斯卡拉使用bootcp启动的线是以下之一,它失败

or as suggested scala -nobootcp it works (Thanks for the valuable advice) Otherwise if I let scala use the bootcp the started line is the following one and it fails

  java -Xbootclasspath/a:/usr/home/pcohen/Dev/Scala/scala-2.11.0-M4/lib/akka-actors.jar[...] -classpath "" [...]

在斯卡拉jar文件附加到引导类路径,它就像我的绑定失败。我不能够清楚地了解为什么这个启动类路径差异会影响我的课。

When the scala jars are appended to the bootclasspath, it is like my binding is failing. I am not able to clearly understand why this bootclasspath difference affects my classes.

推荐答案

我不知道这是否有资格作为建议,但你是否知道:

I don't know if this qualifies as advice, but are you aware:

scala> class C { def sayHello(s: String) = s"hello, $s" }
defined class C

scala> $intp.bind("world","the world")
world: String = the world
res0: scala.tools.nsc.interpreter.IR.Result = Success

scala> val c = new C
c: C = C@19878659

scala> $intp interpret "c sayHello world"
res2: String = hello, the world
res1: scala.tools.nsc.interpreter.IR.Result = Success

使用单独的编译,你的榜样与斯卡拉-nobootcp my.Main

With separate compilation, your example works with scala -nobootcp my.Main.

您可以看到更多的与 -Dscala.repl.debug = TRUE 。您将看到错误从回归绑定(每个人的检查结果值,对吧?的println(i.bind(MYC,C))引起

You can see more with -Dscala.repl.debug=true. You'll see the Error return from the bind (everyone checks result values, right? println(i.bind("myC",c))) caused by:

java.lang.ClassCastException:intpbind.C不能转换为intpbind.C

和包装code,它正在尝试它。

and the wrapper code that is attempting it.

更多的话:

您说,这就像我的绑定失败,但正如我上面显示,这正是绑定失败。

You said, "it is like my binding is failing," but as I showed above, it's exactly that the binding fails.

原因是,当你说绑定,你真正的意思是,自动生成有点code的,就好像我写斯卡拉> VAL MYC = C 。哦,编译它,然后让​​ MYC 可由REPL会话的其余部分得到进口的象征。

The reason is that when you say "bind", you really mean, "Autogenerate a bit of code just as if I'd written, scala> val myC = c." Oh, and compile it, and then make myC a symbol that can get imported by the rest of the REPL session.

当您编译code。与引导类路径上的REPL,引导类路径必须是能够看到你的类 C 。 (它也必须是你的应用程序类加载器加载主类一加载的同一类;凭借代表团通常是真实的)

When you compile that code with the REPL on the boot class path, the boot class path must be able to see your class C. (It must also be the same class loaded by your application class loader, the one that loads your main class; that is usually true by virtue of delegation.)

所以,这个作品:

scalac -d /tmp/out mytest.scala
scala -J-Xbootclasspath/a:/tmp/out mytest.Test

您可以细微差别,通过只把你的一些类的引导类路径,或者,这是更可能的,你会做,我建议,并采取关闭阶引导类路径。

You could nuance that by putting only some of your classes on the boot class path, or, which is more likely, you'll do as I suggested and take scala off the boot class path.

我还没有研究这一点,但你可以谷歌的人使用嵌入在托管环境中的REPL它真的很重要,你住在什么样的类加载器类似的问题。

I haven't researched this, but you could google for people with similar problems using the REPL embedded in managed environments where it really matters what class loader you reside in.

奖金实用程序:

package scala {
  package object foo {
    def show(cl: ClassLoader): String = scala.reflect.runtime.ReflectionUtils.show(cl)
  }
}

使用Scala的,私营公用事业只是倾倒您感兴趣的类装载器:

to use a scala-private utility for just dumping your class loader of interest:

  import scala.foo._
  Console println show(getClass.getClassLoader)

这篇关于类路径的问题在斯卡拉国米preTER结合实例时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆