scala 为什么 sbt 编译失败并出现 StackOverflowError?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34318705/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 07:52:24  来源:igfitidea点击:

Why does sbt compile fail with StackOverflowError?

scalasbt

提问by Kevin Doherty

I am working on a Scala project that has been in existence for a few years but is new to me. My task is to upgrade it from Scala 2.9.3 to 2.11.7, along with its dependencies. I have gotten past the errors and warnings, but I cannot get the project to compile successfully in SBT. I always get a StackOverflowError in pretty much the same place. The stacktrace looks like this, but details vary with the Xss setting (currently 4M, but have tried as high as 24M):

我正在从事一个 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(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(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(Typers.scala:5395)
at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedInternal(Typers.scala:5422)

SBT_OPTS looks like this:

SBT_OPTS 看起来像这样:

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

I can 'make' the project successfully in Intellij, and others can pull my changes from GitHub and compile the project in sbt, so the issue seems to be local to my machine (a recent quad-core Macbook Pro with 16GB RAM). Other Scala/sbt projects compile successfully for me on this machine.

我可以在 Intellij 中成功“制作”项目,其他人可以从 GitHub 中提取我的更改并在 sbt 中编译项目,因此问题似乎出在我的机器上(最近的四核 Macbook Pro,具有 16GB RAM)。其他 Scala/sbt 项目在这台机器上为我成功编译。

Here are other relevant details:

以下是其他相关细节:

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)

I have completely rebuilt the ivy2 cache and cleared the lib_managed directory. The version of the scala-compiler.jar is the same as is used on at least one machine that can 'sbt compile' the code successfully. I did a clean reinstall of sbt (via brew remove sbt, manual removal of ~/.sbt directory, then brew install sbt).

我已经完全重建了 ivy2 缓存并清除了 lib_managed 目录。scala-compiler.jar 的版本与至少一台可以成功“sbt 编译”代码的机器上使用的版本相同。我重新安装了 sbt(通过brew remove sbt手动删除 ~/.sbt 目录,然后brew install sbt)。

I have not tried to isolate the line of source code being compiled when the error occurs. I have assumed it would be more productive to look for a configuration issue or dependency conflict somewhere.

我没有尝试隔离发生错误时正在编译的源代码行。我认为在某处寻找配置问题或依赖冲突会更有效率。

Any suggestions for further troubleshooting will be appreciated.

任何有关进一步故障排除的建议将不胜感激。

[Added...] It may be helpful to add that, as an experiment, I downloaded the Scala language source code from https://github.com/scala/scalaand got the following very similar error trying to sbt compileit:

[已添加...] 补充一点可能会有所帮助,作为一项实验,我从https://github.com/scala/scala下载了 Scala 语言源代码,并在尝试时遇到了以下非常相似的错误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)

Here is something interesting. From this postI found out about launching sbt with a -d flag for debugging info. Got the following output:

这里有一些有趣的事情。从这篇文章中,我发现了使用 -d 标志启动 sbt 以获取调试信息。得到以下输出:

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

So somewhere my SBT_OPTS settings are being overridden (by defaults, I guess). Now I need to find where those defaults are coming from.

所以某处我的 SBT_OPTS 设置被覆盖(默认情况下,我猜)。现在我需要找到这些默认值的来源。

回答by Kevin Doherty

I figured it out. Once I knew that the -d flag would tell me what settings SBT was actually using, I saw that the values in my SBT_OPTS environment variable were being clobbered by other, lower settings. Where were those coming from? From my JAVA_OPTS env variable! I should have noticed them sooner, but now I know I can keep those Java options as they are and override themby adding the SBT-specific settings to my /usr/local/etc/sbtopts file, using the somewhat awkward format of

我想到了。一旦我知道 -d 标志会告诉我 SBT 实际使用的设置,我看到我的 SBT_OPTS 环境变量中的值被其他较低的设置破坏了。那些是从哪里来的?来自我的 JAVA_OPTS 环境变量!我应该早点注意到它们,但现在我知道我可以保留这些 Java 选项,并通过将特定于 SBT 的设置添加到我的 /usr/local/etc/sbtopts 文件中来覆盖它们,使用有点尴尬的格式

-J-Xmx2G
-J-Xss2M 

Using the values shown I was able to run sbt compilesuccessfully on my project.

使用显示的值,我能够sbt compile在我的项目上成功运行。

I hope someone finds this useful.

我希望有人觉得这很有用。

回答by Ajit Surendran

Add to the bottom of /usr/local/etc/sbtopts

添加到/usr/local/etc/sbtopts的底部

-J-Xmx4G 
-J-Xss4M

All set.

可以了,好了。

回答by Pradyumna_Kumar

I just added -Xss in my Intellij sbt properties and the issue is resolved.

我刚刚在 Intellij sbt 属性中添加了 -Xss,问题就解决了。

Intellij SBT properties

Intellij SBT 属性

回答by Robbie Milejczak

I was unable to get this to work via the provided answers. build.sbtsettings and the sbtoptsfile both failed to solve this error for me. What I had to do was run sbtwith the -memflag, for example:

我无法通过提供的答案使其发挥作用。build.sbt设置和sbtopts文件都未能为我解决这个错误。我必须做的是sbt使用-mem标志运行,例如:

sbt -mem 2048 compile

and now my projects built. If using IntelliJ you can also go to

现在我的项目建成了。如果使用 IntelliJ 你也可以去

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

and set Maximum heap size, MBto whatever target you need.

并设置Maximum heap size, MB为您需要的任何目标。

回答by bluenote10

Relevant parts from the output of sbt -h:

输出的相关部分sbt -h

  # jvm options and output control
  JAVA_OPTS          environment variable, if unset uses ""
  .jvmopts           if this file exists in the current directory, its contents
                     are appended to JAVA_OPTS
  SBT_OPTS           environment variable, if unset uses ""
  .sbtopts           if this file exists in the current directory, its contents
                     are prepended to the runner args

Thus, in my case I solved the problem by creating a file .sbtoptswith content

因此,在我的情况下,我通过创建一个.sbtopts包含内容的文件解决了这个问题

-J-Xmx4G 
-J-Xss4M

in the project directory.

在项目目录中。

Note: Running sbt -dshows what settings have been used, for instance:

注意:运行sbt -d显示已使用的设置,例如:

$ sbt -d
[addSbt] arg = '-debug'
[process_args] java_version = '8'
# Executing command line:
java
-Xms1024m
-XX:ReservedCodeCacheSize=128m
-XX:MaxMetaspaceSize=256m
-Xmx2G
-Xss2M
-jar
/path/to/sbt-launch.jar
-debug

回答by Andrew Norman

I discovered the SBT_OPT setting in the bin/sbt file of my sbt install was affecting the memory values set in my projects build.sbt

我发现我的 sbt 安装的 bin/sbt 文件中的 SBT_OPT 设置影响了我的项目 build.sbt 中设置的内存值

updating the existing -Xss value in this file from 1M to 8M raised the memory size of the Scalac stack to a point I stopped getting StackOverflow exceptions in the sbt-invoked compiler. This seemed odd because the sbt documented approach to setting stack size in the compiler is to do this is with the -J-Xss setting.

将此文件中现有的 -Xss 值从 1M 更新到 8M 将 Scalac 堆栈的内存大小提高到我停止在 sbt 调用的编译器中获取 StackOverflow 异常的程度。这看起来很奇怪,因为 sbt 记录的在编译器中设置堆栈大小的方法是使用 -J-Xss 设置来做到这一点。

Sbt doesn't seem to actually enable you to set the compiler's stack memory. While a build.sbt accepts the following configuration as a valid setting, it doesn't seem to apply the value in the compiler:

Sbt 似乎实际上并没有使您能够设置编译器的堆栈内存。虽然 build.sbt 接受以下配置作为有效设置,但它似乎并未在编译器中应用该值:

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

ThisBuild ++= Seq(-J-Xss8M) 中的 scalacOptions

I suspect that is a bug or non-implemented functionality

我怀疑这是一个错误或未实现的功能