2015-12-16 164 views
20

我正在开发一个已经存在了几年但对我而言是新生的Scala项目。我的任务是将其从Scala 2.9.3升级到2.11.7及其依赖项。我已经过去了错误和警告,但是我无法让项目在SBT中成功编译。我总是在几乎相同的地方得到一个StackOverflowError。堆栈跟踪看起来是这样,但具体细节与XSS设置不同(目前4M,而是试图为24M高):为什么sbt编译失败与StackOverflowError?

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编译项目,所以这个问题似乎局限于我的机器(最近有16GB RAM的四核MacBook Pro)。其他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(通过brew remove sbt,手动删除〜/ .sbt目录,然后brew install sbt)。

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

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

[添加...]这可能是有益的补充,作为一个实验,我从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) 

这是一件有趣的事情。从this post我发现有关启动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被覆盖(由违约,我猜)。现在我需要找到那些默认值来自哪里。

+0

当你说你有相同版本的scala编译器。jar作为另一台可以编译的计算机,你的意思是'scalac -version'在两台计算机上都返回相同的结果,或者两台计算机都有.sbt构建文件中定义的2.11.7? – childofsoong

+0

@soong:都在build.sbt文件中指定了2.11.7。 –

+0

@KevinDoherty你碰巧知道在其他计算机上安装的java版本,以及它的所有JVM设置是什么? – childofsoong

回答

16

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

-J-Xmx2G 
-J-Xss2M 

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

我希望有人认为这有用。

+0

如果我运行:sbt -Pyarn -pHadoop 2.7程序集-J-Xss2M我得到: Java HotSpot(TM)客户机VM警告:忽略选项MaxPermSize = 256m;在8.0中删除支持wa - 任何想法? – cs0815

+0

升级并警告消失。 –

相关问题