Подтвердить что ты не робот

Почему компиляция sbt завершается неудачно с StackOverflowError?

Я работаю над проектом Scala, который существует уже несколько лет, но является для меня новым. Моя задача - обновить его с Scala 2.9.3 до 2.11.7 вместе с его зависимостями. Я прошел мимо ошибок и предупреждений, но не могу заставить проект успешно скомпилироваться в SBT. Я всегда получаю StackOverflowError практически в одном и том же месте. Трассировка стека выглядит следующим образом, но детали меняются в зависимости от настройки Xss (в настоящее время 4M, но пробовали до 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 выглядит так:

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

Я могу "сделать" проект успешно в Intellij, а другие могут вытащить мои изменения из GitHub и скомпилировать проект в sbt, поэтому проблема кажется локальной для моей машины (недавний четырехъядерный Macbook Pro с 16 ГБ ОЗУ). Другие проекты Scala/sbt успешно компилируются для меня на этой машине.

Вот другие соответствующие детали:

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)

Я полностью перестроил кеш ivy2 и очистил каталог lib_managed. Версия scala-compiler.jar такая же, как и используется по крайней мере на одной машине, которая может успешно 'sbt compile' код. Я сделал чистую переустановку sbt (через brew remove sbt, вручную удалил каталог ~/.sbt, затем brew install sbt).

Я не пытался изолировать строку скомпилированного исходного кода при возникновении ошибки. Я предположил, что было бы более продуктивным искать проблему конфигурации или конфликт зависимостей где-нибудь.

Будем благодарны за любые предложения по дальнейшему устранению неполадок.

[Добавлено...] Может быть полезно добавить, что в качестве эксперимента я скачал исходный код языка Scala с https://github.com/scala/scala и получил следующую очень похожую ошибку, пытаясь sbt compile его с помощью sbt compile:

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)

Вот кое-что интересное. Из этого поста я узнал о запуске sbt с флагом -d для отладочной информации. Получил следующий вывод:

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

Так что где-то мои настройки SBT_OPTS переопределяются (по умолчанию, я думаю). Теперь мне нужно выяснить, откуда берутся эти настройки по умолчанию.

4b9b3361

Ответ 1

Я понял это. Как только я знал, что флаг -d скажет мне, какие настройки SBT фактически использует, я увидел, что значения в моей переменной среды SBT_OPTS были сбиты другими более низкими настройками. Откуда они пришли? Из моей переменной JAVA_OPTS env! Я должен был заметить их раньше, но теперь я знаю, что могу сохранить эти параметры Java такими, какие они есть, и переопределить их, добавив специальные параметры SBT в файл /usr/local/etc/sbtopts, используя несколько неудобный формат

-J-Xmx2G
-J-Xss2M 

Используя показанные значения, я смог успешно запустить sbt compile в моем проекте.

Я надеюсь, что кто-то найдет это полезным.

Ответ 2

Добавьте в конец /usr/local/etc/sbtopts

-J-Xmx4G 
-J-Xss4M

Все готово.

Ответ 3

Я обнаружил, что настройка SBT_OPT в файле bin/sbt моей установки sbt влияет на значения памяти, установленные в моих проектах build.sbt

Обновление существующего значения -Xss в этом файле с 1M до 8M увеличило объем памяти стека Scalac до такой степени, что я перестал получать исключения StackOverflow в вызываемом sbt компиляторе. Это казалось странным, потому что документированный подход sbt к настройке размера стека в компиляторе заключается в том, чтобы сделать это с параметром -J -Xss.

Sbt, похоже, фактически не позволяет вам устанавливать память стека компилятора. Хотя build.sbt принимает следующую конфигурацию в качестве допустимого параметра, он, похоже, не применяет значение в компиляторе:

scalacOptions в ThisBuild ++ = Seq (-J -Xss 8M)

Я подозреваю, что это ошибка или не реализованная функциональность

Ответ 4

Я не смог заставить это работать через предоставленные ответы. build.sbt настройки и sbtopts файл и не удалось решить эту ошибку для меня. Мне нужно было запустить sbt с флагом -mem, например:

sbt -mem 2048 compile

и теперь мои проекты построены. Если вы используете IntelliJ, вы также можете перейти на

Preferences > Build, Execution, Deployment > Build Tools > sbt 

и установите Maximum heap size, MB на любой целевой объект, который вам нужен.

Ответ 5

Я только добавил -Xss в мои свойства Intellij sbt, и проблема решена.

Intellij SBT свойства