2015-07-22 14 views
8

Zajmuję się przetwarzaniem obrazów do pracy i pisałem scenki z Im4Java. Aby napisać kilka przypadków jednostkowych, postanowiłem po prostu zapisać obraz lokalny jako tablicę bajtów w kodzie. Złapałam prosty test zdjęcieDlaczego duże wywołanie konstruktora tablicowego powoduje przerwanie kompilatora Scala?

Example Image Pulled from Wikipedia

A potem przekształcono go do tablicy bajtów tak:

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)) 

a następnie umieścić te bajty do w Array[Byte] zastosować Konstruktor:

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

Kiedy próbowałem skompilować to (zobacz pełny plik scala w this gist) byłem zaskoczony, widząc, że złamał kompilator t yper! Pojawia się następujący stacktrace (mam obcięty to trochę):

[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) 

Używam Scala 2.10.5 kompilator i Java jdk1.7.0_79

jestem prawdopodobnie będzie po prostu użyć mniejszy obraz lub coś, co naprawia mój problem, ale chciałbym wiedzieć, dlaczego robi to kompilator i czy można go naprawić?

+1

Zwykle sam obraz nie może stanowić problemu, ponieważ kompilator nie będzie o nim wiedział podczas kompilacji. – Clashsoft

+0

Wątpię, aby miało to coś wspólnego z rzeczywistym obrazem, ponieważ błąd został zgłoszony podczas kompilacji. Czy możesz podać pełną wersję kodu (nie jest jasne, jak zdefiniowane są 'fileName',' Files' i 'Paths')? –

+0

@ om-nom-nom zobacz plik główny połączony z pytaniem. – EdgeCaseBerg

Odpowiedz

6

Dobrze starałem się odtworzyć problemu i nowsze scalac (2.11.7) ma lepszy komunikat o błędzie (mam nadzieję, że czyści się problem):

» 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 

więc wygląda na to, podobnie jak @Marius noted in comments, ty "trafienie na" 64K kod bajtowy na metodę "narzuconego przez JVM.

+0

Wygląda więc na to, że odpowiedź na pytanie, jak duże może być wszystko, zależy od ustawień JVM?Które wyglądają jak niektóre z limitów są odniesieniami w tym pytaniu: http://stackoverflow.com/questions/17422480/maximum-size-of-a-method-in-java-7-and-8 – EdgeCaseBerg

+0

Dzięki @ om-nom -Niedzie to odpowiada na pytanie, ale dla jasności odpowiedzi dla każdego, kto do tego prowadzi, czy mógłbyś edytować swoją odpowiedź, aby wyraźnie stwierdzić, że jest to limit rozmiaru kodu JVM, jak również pokazujący błąd z kompilatora? – EdgeCaseBerg

+0

Podobna wrażenia użytkownika https://issues.scala-lang.org/browse/SI-9389 –

Powiązane problemy