Using a Scala symbol literal results in NoSuchMethod
Asked Answered
T

2

2

I have recently begun using Scala. I've written a DSL in it which can be used to describe a processing pipeline in medici. In my DSL, I've made use of symbols to signify an anchor, which can be used to put a fork (or a tee, if you prefer) in the pipeline. Here's a small sample program that runs correctly:

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"
}

For some reason, when I use a symbol literal in my program, I get a NoSuchMethod exception at runtime:

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)

This happens regardless of how the symbol is used. Specifically, I've tried using the symbol in the pipeline, and in a simple println('foo) statement.

The question: What could possibly cause a symbol literal's mere existence to cause a NoSuchMethodError? In my DSL I am using an implicit function which converts symbols to instances of the Anchor class, like so:

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

Sadly, my understanding of Scala is weak enough that I can't think of why that might be causing my NoSuchMethodError.

Tedmann answered 19/5, 2010 at 5:30 Comment(2)
What's that --> operator take as an argument?Courbevoie
It's a method on a Node class that takes another Node as an argument. It ends up calling the outer class's connectNodes(a:Node, b:Node):Node method. Anchor extends Node.Tedmann
R
4

The most likely explanation is that you are compiling with a different version of Scala than you have on the classpath at runtime.

Checking the run-time version of Scala

Add the following to your main() method:

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

This will tell you where you are loading the Scala library from, for example:

(file:/Users/jason/usr/scala-2.8.0.RC2/lib/scala-library.jar )

Checking the compile-time version of Scala

I don't know how you are invoking scalac. Assuming it's from the command line, run scalac -version.

Robbi answered 25/5, 2010 at 6:21 Comment(5)
I'm actually using maven to do the compile. I'll try this and comment again with results.Tedmann
Use mvn -Dmaven.scala.displayCmd=true compile to display the scalac command line.Robbi
I gave it a try, and the only 2 versions of scala I have on my system cause exactly the same error message. Unless you can explain that, I think we can rule out scala versions being the problem.Tedmann
Ahh, I didn't see your other comment before I posted that. Using that command, it looks like maven has provided a completely different scala version I couldn't find by hand: 2.6. So the question now becomes: how do I tell maven to use scala 2.7?Tedmann
Ahh, I found it in my pom. I must have copied that straight out of an older example, I was requiring 2.6, and maven faithfully fetched it. Looks like I'm good to go. Thanks very much!Tedmann
A
1

Could you possibly have multiple versions of Scala installed, as from the 2.7.1 source at least (http://scala-tools.org/scaladocs/scala-library/2.7.1/Symbol.scala.html) it doesn't look like Symbol has an intern method?

Angers answered 19/5, 2010 at 7:13 Comment(3)
I also couldn't find an intern method on the symbol. I do have scala 2.7.5 and 2.7.7 installed, but as far as I can tell it's only using 2.7.7.Tedmann
In that case it'd be good to know what code the stack trace refers to as at gov.pnnl.mif.scaladsl.Test$.<init>(Test.scala:7). Assuming it's the code you were referring to, is it possible to post it here?Angers
Effectively, it's this: "tcp://localhost:4858" --> "ByteToStringProcessor" --> 'hello. The only difference between the program that works and the program that doesn't is Symbol("hello") vs 'hello.Tedmann

© 2022 - 2024 — McMap. All rights reserved.