naoki86star

インターネットの片隅でなにかしら書いてみる

stackoverflow on sbt compile

sbtにおいてscala 2.12.4を使う限り .javaと.scalaソースを同一ディレクトリに配置してコンパイルするとstackoverflowする場合(環境)があるのを知っている。

普通、 .javaと.scala混合ソースではディレクトリ単位でsrc/main/scala/... src/main/java/...とかのように分かれるのが今時の標準と思う。

本件の場合、
project/src/package-name/file1.java
project/src/package-name/file2.scala
のように配置してあってbuild.sbtで
scalaSource = src
のように宣言していると、一緒にコンパイルしてくれるのだが、一部の環境*1でcompile時に、正確にはコンパイル実行後に.classを書き出すときにエラーになる。

この件のようなsbtでstackoverflow?の原因を探る検索解では、sbtのヒープ設定の仕方が紹介されるのがほとんどである。

自分の本ケースの場合を最小限構成にしてみると、わずかに2ファイルでもstackoverflowが起きる。
こんなファイル構成で(Hello world程度のサンプル)

$ ls -lR src
src:
total 4
drwxrwxr-x 2 nao nao 4096 Mar 19 16:09 package

src/package:
total 8
-rw-rw-r-- 1 nao nao  58 Mar 19 16:07 file1.scala
-rw-rw-r-- 1 nao nao 108 Mar 19 16:09 file2.java

こんな build.sbtで

name := "stackoverflow-example"
scalaVersion := "2.12.4"
run / baseDirectory := file(".")
Compile / scalaSource := baseDirectory.value / "src"

コンパイルすると、

sbt:stackoverflow-example> compile
[info] compiling 1 Scala source and 1 Java source to /home/nao/stackoverflow-example/target/scala-2.12/classes ...
[error] ## Exception when compiling 2 sources to /home/nao/stackoverflow-example/target/scala-2.12/classes
[error] java.lang.StackOverflowError
[error] xsbt.ExtractUsedNames$ExtractUsedNamesTraverser.handleClassicTreeNode(ExtractUsedNames.scala:280)
[error] xsbt.ExtractUsedNames$ExtractUsedNamesTraverser.traverse(ExtractUsedNames.scala:170)
[error] xsbt.ExtractUsedNames$ExtractUsedNamesTraverser.$anonfun$handleClassicTreeNode$3(ExtractUsedNames.scala:294)
[error] xsbt.ExtractUsedNames$ExtractUsedNamesTraverser.$anonfun$handleClassicTreeNode$3$adapted(ExtractUsedNames.scala:294)
[error] xsbt.Compat$OriginalTreeTraverser$Reflective$.traverseOriginal(Compat.scala:50)
[error] xsbt.Compat.processOriginalTreeAttachment(Compat.scala:25)
...
...

回避するために、scala 2.12.17にしてみる。すると今のところ・今手持ちで確認できるすべての環境で通っている。

これの境界のscalaバージョンは調べてない。

普通は、標準ディレクトリ構成にする、ってのが正解。お年を召された御子息のお守りは大変である。*2
そもそもscala 3の時代ですけど。。。

*1:ubuntu 22 with jdk8, ubuntu 22 with jdk17 比較的新しいOS環境な傾向

*2:2.12.17にするだけでもすべてを見通してやるのは手間になるところが多い