2010-06-30 294 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。

相關問題