web-dev-qa-db-fra.com

Pourquoi la compilation sbt échoue-t-elle avec StackOverflowError?

Je travaille sur un projet Scala qui existe depuis quelques années mais qui est nouveau pour moi. Ma tâche consiste à le mettre à niveau de Scala 2.9.3 à 2.11.7, ainsi que ses dépendances. J'ai dépassé les erreurs et les avertissements, mais je ne parviens pas à compiler le projet avec succès en SBT. Je reçois toujours un StackOverflowError à peu près au même endroit. Le stacktrace ressemble à ceci, mais les détails varient en fonction du paramètre Xss (actuellement 4M, mais ont essayé jusqu'à 24M):

Java.lang.StackOverflowError
at scala.tools.nsc.transform.Erasure$Eraser.typed1(Erasure.scala:698)
at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5395)
at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedInternal(Typers.scala:5422)
at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5369)
at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5373)
at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:5471)
at scala.tools.nsc.typechecker.Typers$Typer.typedQualifier(Typers.scala:5479)
at scala.tools.nsc.transform.Erasure$Eraser.adaptMember(Erasure.scala:644)
at scala.tools.nsc.transform.Erasure$Eraser.typed1(Erasure.scala:698)
at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5395)
at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedInternal(Typers.scala:5422)

SBT_OPTS ressemble à ceci:

-Xmx2G -Xss4M -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled

Je peux «réussir» le projet dans Intellij, et d'autres peuvent extraire mes modifications de GitHub et compiler le projet dans sbt, de sorte que le problème semble être local pour ma machine (un MacBook Pro quad-core récent avec 16 Go de RAM). D'autres projets Scala/sbt compilent avec succès pour moi sur cette machine.

Voici d'autres détails pertinents:

Scala version: 2.11.7
Java version: Java version "1.8.0_66" (build 1.8.0_66-b17)
sbt version: 0.13.7 (have also tried 0.13.9)

J'ai complètement reconstruit le cache ivy2 et effacé le répertoire lib_managed. La version de scala-compiler.jar est la même que celle utilisée sur au moins une machine capable de "compiler" le code avec succès. J'ai fait une réinstallation propre de sbt (via brew remove sbt, suppression manuelle du répertoire ~/.sbt, puis brew install sbt).

Je n'ai pas essayé d'isoler la ligne de code source en cours de compilation lorsque l'erreur s'est produite. J'ai supposé qu'il serait plus productif de rechercher un problème de configuration ou un conflit de dépendance quelque part. 

Toute suggestion pour un dépannage supplémentaire sera appréciée.

[Ajouté ...] Il peut être utile d’ajouter que, à titre expérimental, j’ai téléchargé le code source du langage Scala à partir de https://github.com/scala/scala et que j’ai eu l’erreur très similaire suivante en essayant de: sbt compile il:

Java.lang.StackOverflowError
at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.outerValue(ExplicitOuter.scala:229)
at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:441)
at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
at scala.reflect.internal.Trees$class.itransform(Trees.scala:1345)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer.transform(TypingTransformers.scala:44)
at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.scala$reflect$internal$Trees$UnderConstructionTransformer$$super$transform(ExplicitOuter.scala:219)
at scala.reflect.internal.Trees$UnderConstructionTransformer$class.transform(Trees.scala:1693)
at scala.tools.nsc.transform.ExplicitOuter$OuterPathTransformer.transform(ExplicitOuter.scala:291)
at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:459)
at scala.tools.nsc.transform.ExplicitOuter$ExplicitOuterTransformer.transform(ExplicitOuter.scala:352)
at scala.reflect.internal.Trees$class.itransform(Trees.scala:1347)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
at scala.reflect.internal.SymbolTable.itransform(SymbolTable.scala:16)
at scala.reflect.api.Trees$Transformer.transform(Trees.scala:2555)

Voici quelque chose d'intéressant. De cet article J'ai découvert le lancement de sbt avec un indicateur -d pour les informations de débogage. Vous avez la sortie suivante:

Kevins-MacBook-Pro:scala kdoherty$ sbt -d
[process_args] Java_version = '1.8.0_66'
# Executing command line:
Java
-Xmx2G
-Xss4M
-XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-Xmx384m
-Xss512k
-XX:+UseCompressedOops
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
-jar
/usr/local/Cellar/sbt/0.13.9/libexec/sbt-launch.jar

Donc, quelque part, mes paramètres SBT_OPTS sont remplacés (par défaut, je suppose). Maintenant, je dois trouver d'où viennent ces défauts.

24
Kevin Doherty

Je l'ai compris. Une fois que j'ai su que l'indicateur -d m'indiquerait les paramètres réellement utilisés par SBT, j'ai constaté que les valeurs de ma variable d'environnement SBT_OPTS étaient gâchées par d'autres paramètres plus bas. D'où venaient ceux-ci? De ma variable env Java_OPTS! J'aurais dû les remarquer plus tôt, mais je sais maintenant que je peux garder ces options Java telles quelles et les écraser eux en ajoutant les paramètres spécifiques à SBT à mon fichier/usr/local/etc/sbtopts, en utilisant le fichier quelque peu maladroit format de 

-J-Xmx2G
-J-Xss2M 

En utilisant les valeurs indiquées, j'ai pu exécuter sbt compile avec succès sur mon projet.

J'espère que quelqu'un trouvera cela utile.

21
Kevin Doherty

J'ai découvert que le paramètre SBT_OPT dans le fichier bin/sbt de mon installation sbt affectait les valeurs de mémoire définies dans mes projets build.sbt

la mise à jour de la valeur -Xss existante dans ce fichier de 1 à 8 Mo a augmenté la taille de la mémoire de la pile Scalac à un point où j'ai arrêté de recevoir des exceptions StackOverflow dans le compilateur sbt-invoked. Cela semblait étrange car l’approche sbt documentée pour définir la taille de la pile dans le compilateur consiste à le faire avec le paramètre -J-Xss.

Sbt ne semble pas vous permettre réellement de définir la mémoire de pile du compilateur. Bien qu'un build.sbt accepte la configuration suivante comme paramètre valide, il ne semble pas appliquer la valeur dans le compilateur:

scalacOptions dans ThisBuild ++ = Seq (-J-Xss8M) 

Je soupçonne que c'est un bug ou une fonctionnalité non implémentée

0
Andrew Norman