2015-07-22 1 views
8

Ich mache einige Bildverarbeitung für einen Job und schrieb Dinge mit Im4Java. Um einige Unit-Fälle zu schreiben, habe ich beschlossen, ein lokales Bild als Byte-Array im Code zu speichern. Ich packte ein einfaches TestbildWarum unterbricht ein Aufruf eines großen Array-Konstruktors den Scala-Compiler?

Example Image Pulled from Wikipedia

Und dann wie in den Byte-Array konvertiert es so:

import java.nio.file.{Paths, Files} 
import java.nio.charset.StandardCharsets 
val stuff =scala.io.Source.fromFile(fileName)(scala.io.Codec.ISO8859).map(_.toByte).toArray 
Files.write(Paths.get("tmp.txt"), stuff.mkString(",").getBytes(StandardCharsets.UTF_8)) 

Und dann diese Bytes in einen Array[Byte] setzen anwenden Konstruktor:

class testCase() { 
    val smallFile = Array[Byte](-1,-40,-1, …) // 9816 arguments to the constructor passed here 
} 

Als ich versuchte, dies zu kompilieren (siehe die vollständige Scala-Datei in this gist), war ich überrascht zu sehen, dass es den Compiler t zu brechen Yper! Ich erhalte die folgende Stacktrace (Ich habe es ein bisschen gekürzt):

[error] uncaught exception during compilation: java.lang.StackOverflowError 
java.lang.StackOverflowError 
at scala.reflect.internal.Symbols$Symbol.info(Symbols.scala:1241) 
at scala.reflect.internal.Symbols$Symbol.baseTypeSeqLength$1(Symbols.scala:1628) 
at scala.reflect.internal.Symbols$Symbol.isLess(Symbols.scala:1631) 
at scala.reflect.internal.Types$Type.baseTypeIndex(Types.scala:992) 
at scala.reflect.internal.Types$CompoundType.baseType(Types.scala:1655) 
at scala.reflect.internal.Types$ClassTypeRef$class.baseType(Types.scala:2186) 
at scala.reflect.internal.Types$TypeRef$$anon$6.baseType(Types.scala:2544) 
at scala.reflect.internal.Types$class.firstTry$1(Types.scala:6064) 
at scala.reflect.internal.Types$class.isSubType2(Types.scala:6228) 
at scala.reflect.internal.Types$class.isSubType(Types.scala:5837) 
at scala.reflect.internal.SymbolTable.isSubType(SymbolTable.scala:13) 
at scala.reflect.internal.Types$class.fourthTry$1(Types.scala:6223) 
at scala.reflect.internal.Types$class.thirdTryRef$1(Types.scala:6123) 
at scala.reflect.internal.Types$class.thirdTry$1(Types.scala:6145) 
at scala.reflect.internal.Types$class.secondTry$1(Types.scala:6109) 
at scala.reflect.internal.Types$class.firstTry$1(Types.scala:6070) 
at scala.reflect.internal.Types$class.isSubType2(Types.scala:6228) 
at scala.reflect.internal.Types$class.isSubType(Types.scala:5837) 
at scala.reflect.internal.SymbolTable.isSubType(SymbolTable.scala:13) 
at scala.reflect.internal.Types$Type.$less$colon$less(Types.scala:872) 
at scala.tools.nsc.typechecker.Typers$Typer.adapt(Typers.scala:1091) 
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5660) 
at scala.tools.nsc.typechecker.Typers$Typer.typedArg(Typers.scala:3042) 
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3069) 
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071) 
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071) 
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071) 
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071) 
at scala.tools.nsc.typechecker.Typers$Typer.loop$1(Typers.scala:3071) 
(etc as this is where the stackoverflow happens) 

ich die Scala 2.10.5 Compiler und Java unter Verwendung jdk1.7.0_79

Ich bin wahrscheinlich nur nicht benutzen wollen ein kleineres Bild oder etwas, um mein Problem zu beheben, aber ich würde gerne wissen, warum der Compiler dies tut und ob es behoben werden kann?

+1

Normalerweise kann das Image selbst nicht das Problem sein, da der Compiler es zur Kompilierzeit nicht wissen wird. – Clashsoft

+0

Ich bezweifle, dass es etwas mit dem tatsächlichen Bild zu tun hat, da ein Fehler während der Kompilierzeit ausgelöst wird. Können Sie die vollständige Version des Codes bereitstellen (es ist unklar, wie 'fileName',' Files' und 'Paths' definiert sind)? –

+0

@ om-nom-nom Siehe die in der Frage verknüpfte Gist-Datei. – EdgeCaseBerg

Antwort

6

Nun habe ich versucht, das Problem und neueren scalac (2.11.7) hat eine bessere Fehlermeldung zu reproduzieren (hoffen, dass es das Problem aufräumt):

» scalac Arrays.scala 
Arrays.scala:1: error: Could not write class testCase because it exceeds JVM code size limits. Method <init>'s code too large! 
class testCase() { 
    ^
one error found 

So wie es aussieht, so wie @Marius noted in comments, Sie 'trifft 64K Bytecode pro Methode "Grenze von JVM auferlegt.

+0

Es sieht also wie eine Antwort aus, wie groß alles sein kann, hängt von diesen JVM-Einstellungen ab?Welche aussehen wie einige der Grenzen sind Referenz in dieser Frage: http://stackoverflow.com/questions/17422480/maximum-size-of-a-method-in-java-7-and-8 – EdgeCaseBerg

+0

Danke @ Om-nom -nom dies beantwortet die Frage, aber für die Klarheit einer Antwort für alle anderen, die darauf stoßen, könnten Sie Ihre Antwort bearbeiten, um explizit anzugeben, dass es eine JVM-Code-Größenbeschränkung sowie den Fehler vom Compiler zeigt? – EdgeCaseBerg

+0

Ähnliche Benutzererfahrung https://issues.scala-lang.org/browse/SI-9389 –