2

私は最近Scalaを使い始めました。mediciの処理パイプラインを記述するために使用できるDSLをその中に記述しました。私のDSLでは、アンカーを示すためにシンボルを使用しました。アンカーは、パイプラインにフォーク(または必要に応じてティー)を配置するために使用できます。正しく実行される小さなサンプルプログラムを次に示します。

object Test extends PipelineBuilder {
    connector("TCP") / Map("tcpProtocol" -> new DirectProtocol())
    "tcp://localhost:4858" --> "ByteToStringProcessor" --> Symbol("hello")
    "stdio://in?promptMessage=enter name:%20" --> Symbol("hello")
    Symbol("hello") --> "SayHello" / Map("prefix" -> "\n\t")  --> "stdio://out"
}

何らかの理由で、プログラムでシンボルリテラルを使用すると、実行時にNoSuchMethod例外が発生します。

java.lang.NoSuchMethodError: scala.Symbol.intern()Lscala/Symbol;
        at gov.pnnl.mif.scaladsl.Test$.<init>(Test.scala:7)
        at gov.pnnl.mif.scaladsl.Test$.<clinit>(Test.scala)
        at gov.pnnl.mif.scaladsl.Test.main(Test.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at scala.tools.nsc.ObjectRunner$$anonfun$run$1.apply(ObjectRunner.scala:75)
        at scala.tools.nsc.ObjectRunner$.withContextClassLoader(ObjectRunner.scala:49)
        at scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:74)
        at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:154)
        at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

これは、シンボルの使用方法に関係なく発生します。具体的には、パイプラインと簡単なprintln('foo)ステートメントでシンボルを使用してみました。

質問:シンボルリテラルの単なる存在がNoSuchMethodErrorを引き起こす可能性があるのは何ですか?私のDSLでは、次のように、シンボルをAnchorクラスのインスタンスに変換する暗黙の関数を使用しています。

    implicit def makeAnchor(a: Symbol):Anchor = anchor(a)

悲しいことに、Scalaについての私の理解は十分に弱いので、なぜそれが私のNoSuchMethodErrorを引き起こしているのか考えることができません。

4

2 に答える 2

4

最も可能性の高い説明は、実行時にクラスパスにあるものとは異なるバージョンの Scala でコンパイルしていることです。

Scala のランタイム バージョンの確認

以下を main() メソッドに追加します。

println(classOf[scala.Symbol].getProtectionDomain.getCodeSource)

これにより、Scala ライブラリをどこからロードしているかがわかります。たとえば、次のようになります。

(ファイル:/Users/jason/usr/scala-2.8.0.RC2/lib/scala-library.jar )

Scala のコンパイル時のバージョンを確認する

どのようにscalacを呼び出しているのかわかりません。コマンドラインからだと仮定して、 を実行しscalac -versionます。

于 2010-05-25T06:21:06.303 に答える
1

少なくとも 2.7.1 ソースから (http://scala-tools.org/scaladocs/scala-library/2.7.1/Symbol.scala.html ) Symbol にインターン メソッドがあるように見えませんか?

于 2010-05-19T07:13:12.537 に答える