2010-06-30 73 views
2

我试图运行此代码在scala 2.7.3和2.7.7下,每次我得到这个错误。哪里不对?得到NoClassDefFound运行示例代码

import scala.io._ 

def toInt(in: String): Option[Int] = 
    try { 
    Some(Integer.parseInt(in.trim)) 
    } catch { 
    case e: NumberFormatException => None 
    } 

def sum(in: Seq[String]) = { 
    val ints = in.flatMap(s => toInt(s)) 
    ints.foldLeft(0)((a, b) => a + b) 
    } 

println("Enter some numbers and press ctrl-D (Unix/Mac) ctrl-C (Windows)") 
val input = Source.fromInputStream(System.in) 
val lines = input.getLines.collect 
println("Sum "+sum(lines)) 

alt text

回答

4

我试图找出问题,看起来它与您输入数值的方式有关。

例如,下面的代码段按预期方式工作,打印6.

import scala.io._ 

def toInt(in: String): Option[Int] = 
    try { 
    Some(Integer.parseInt(in.trim)) 
    } catch { 
    case e: NumberFormatException => None 
    } 

def sum(in: Seq[String]) = { 
    val ints = in.flatMap(s => toInt(s)) 
    ints.foldLeft(0)((a, b) => a + b) 
} 

println(sum(List("1","2","3"))) 

因此,这个问题必须在某处以跟随线位于。我认为主要的罪魁祸首是Ctrl-C在Windows上实际执行的操作,以及Scala解释器如何运行脚本。你所附加的问题的最后一行是开始点。它暗示在某个地方,批处理作业正在运行,并且Ctrl-C发送了一个信号来终止该批处理作业。这实际上就是scala解释器本身(scala.bat)。因此,当您按Ctrl-C时,而不是仅仅杀死输入流,就发送一个信号来杀死运行程序的整个批处理作业!

所以这个错误与这个动作有关。我看过scala如何运行你的脚本。似乎在%TEMP%中创建了一个名为scalascriptXXXXXXXXXXXXXXXXXXX的文件夹(其中XX ...表示19个伪随机数字),其中放置了所需的所有编译的东西。在那里,创建了一个名为Main$$anon$1$$anonfun$1.class的文件 - 这表示传递给flatMap函数的匿名函数。看起来这个文件是与程序运行并行创建的。因此,如果你在有机会编译这个程序之前杀死你的进程,你将会得到ClassNotFoundException

现在,很奇怪的是,您一直在运行脚本时会收到此错误。我设法偶尔获得它。总是,只要我按下Ctrl-C,我会得到Terminate batch job (Y/N)?提示。有时候会伴随着一个例外。有时候不是。我认为这又与创建Main$$anon$1$$anonfun$1.class有关。如果我等一会儿,我也不例外。如果我在开始后立即按下Ctrl-C,我会得到异常。

经过相当多的运行后,我设法得到一个完整的堆栈跟踪(我认为......因为Ctrl-C也停止堆栈跟踪被转储),指向主要罪魁祸首 - 一个FileNotFoundException

scala sum.scala 
Enter some numbers and press ctrl-D (Unix/Mac) ctrl-C (Windows) 
1 
2 
3 
4 
java.lang.NoClassDefFoundError: Main$$anon$1$$anonfun$1 
     at Main$$anon$1.sum((virtual file):15) 
     at Main$$anon$1.<init>((virtual file):25) 
     at Main$.main((virtual file):4) 
     at Main.main((virtual file)) 
     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.ScriptRunner$.scala$tools$nsc$ScriptRunner$$runCompiled(ScriptRunner.scala:381) 
     at scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:414) 
     at scala.tools.nsc.ScriptRunner$$anonfun$runScript$1.apply(ScriptRunner.scala:413) 
     at scala.tools.nsc.ScriptRunner$.withCompiledScript(ScriptRunner.scala:351) 
     at scala.tools.nsc.ScriptRunner$.runScript(ScriptRunner.scala:413) 
     at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:168) 
     at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala) 
Caused by: java.lang.ClassNotFoundException: Main$$anon$1$$anonfun$1 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:197) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:188) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:307) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:252) 
     at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320) 
     ... 18 more 
Caused by: java.io.FileNotFoundException: C:\Users\****\AppData\Local\Temp\scalascript5827128241389779296\Main$$anon$1$$anonfun$1.class (T 
he system cannot find the file specified) 
     at java.io.FileInputStream.open(Native Method) 
     at java.io.FileInputStream.<init>(FileInputStream.java:106) 
     at sun.misc.URLClassPath$FileLoader$1.getInputStream(URLClassPath.java:1001) 
     at sun.misc.Resource.cachedInputStream(Resource.java:59) 
     at sun.misc.Resource.getByteBuffer(Resource.java:154) 
     at java.net.URLClassLoader.defineClass(URLClassLoader.java:249) 
     at java.net.URLClassLoader.access$000(URLClassLoader.java:56) 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:195) 
     ... 23 more 
Terminate batch job (Y/N)? y 

因此,我会建议使用更好的方法来输入您的值。也许试试Console.in.readLine?并在获得非数字行时停止。或者,如果您确实想要指示流结束,请尝试使用Ctrl-Z(Ctrl-C是杀死进程信号)。

scala sum.scala 
Enter some numbers and press ctrl-D (Unix/Mac) ctrl-C (Windows) 
1 
3 
44 
5 
6 
^Z 
Sum 59 

- Flaviu Cipcigan

1

上阶2.8.0.RC6以下工作:


import scala.io._ 

def toInt(in: String): Option[Int] = 

try { 
    Some(Integer.parseInt(in.trim)) 
} catch { case e: NumberFormatException => None} 

def sum(in: Iterator[String]) = { 
    in.toList.flatMap(s => toInt(s)).foldLeft(0)((a, b) => a + b) 
} 

println("Enter some numbers and press ctrl-D (Unix/Mac) ctrl-C (Windows)") 
val input = Source.fromInputStream(System.in) 
val lines = input.getLines 
println("Sum "+sum(lines)) 


scala sum.scala 
Enter some numbers and press ctrl-D (Unix/Mac) ctrl-C (Windows) 
4 
3 
5 
Sum 12 

因此,也许这是升级的好主意。

+0

嗯,我已经试过你的代码,但我得到了同样的麻烦:(与2.8.0 RC6 – Overdose 2010-06-30 11:25:54

+0

你运行的* nix然后,按Ctrl-d确实?指示输入结束,程序应按预期运行:) – 2010-06-30 12:21:13

0

如果Arjanmanages to compile and execute your code,那么它必须是:

  • Scala和/或scalac不引用斯卡拉你认为
  • 一个旧的.class为这是由你的classpath
拿起sum.scala

确保scalacscala参考,并尝试删除以前生成的任何.class。