sbt icon indicating copy to clipboard operation
sbt copied to clipboard

`run` task does not support `JEP 512: Compact Source Files and Instance Main Methods`

Open xuwei-k opened this issue 2 years ago • 16 comments

https://openjdk.org/jeps/445

Step

https://github.com/xuwei-k/sbt-JEP-445/commit/e2e6293aa4bc84a3ab506b67328786f88e011a7b

install JDK 21

A.java

void main() {
  System.out.println("hello");
}

build.sbt

javacOptions ++= Seq(
  "-Xlint:preview",
  "--enable-preview",
  "--release",
  scala.util.Properties.javaSpecVersion
)

run / fork := true

run / javaOptions ++= Seq("--enable-preview")

scalaVersion := "3.3.1"

project/build.properties

sbt.version=1.9.6

sbt -J--enable-preview run

[error] java.lang.RuntimeException: No main class detected.
[error] 	at scala.sys.package$.error(package.scala:30)

expect

print hello

xuwei-k avatar Sep 21 '23 12:09 xuwei-k

I think we use Zinc to detect main. Does JEP 445 generate A.class? If so what information can we get out of that using Zinc?

eed3si9n avatar Sep 21 '23 17:09 eed3si9n

I've never liked that Scala tools are fussy about main.

$ scala hello-instance.scala
hello-instance.scala:11: warning: not a valid main method for Main,
  because main methods must have the exact signature `(Array[String]): Unit`, though Scala runners will forgive a non-Unit result.
  To define an entry point, please define the main method as:
    def main(args: Array[String]): Unit

  def main(args: Array[String]): Int = { println("hi!"); 42 }
      ^
hi!

It requires the args and will not inspect a class for an instance method.

som-snytt avatar Sep 21 '23 18:09 som-snytt

@som-snytt per https://openjdk.org/jeps/445#A-flexible-launch-protocol, JDK 21 relaxes the main constraints in three different ways:

  1. doesn't have to be public
  2. doesn't need Array[String] parameter
  3. doesn't have to be static method

This is serious relaxation, but it doesn't mention anything about being able to return Int, which I'd argue is a good thing because otherwise the user might expect that 42 would be the exit code

eed3si9n avatar Sep 21 '23 21:09 eed3si9n

To a potential contributor:

Relevant code in Zinc is here: https://github.com/sbt/zinc/blob/a09cfdfc572a362d9deccc07256a4dffec5f27f9/internal/compiler-bridge/src/main/scala/xsbt/ExtractAPI.scala#L773-L775

    if (sym.isStatic && defType == DefinitionType.Module && definitions.hasJavaMainMethod(sym)) {
      _mainClasses += name
    }

It might be tricky to implement https://openjdk.org/jeps/445#A-flexible-launch-protocol because it's worded like

  • If a launched class contains no static main method with a String[] parameter but does contain a static main method with no parameters, then invoke that method.

eed3si9n avatar Sep 21 '23 21:09 eed3si9n

https://github.com/scala/scala/blob/2.13.x/src/sbt-bridge/scala/tools/xsbt/ExtractAPI.scala#L777

I don't know if the target audience of beginners have expectations, but I would like any non-Unit result to be printed, please.

Also if I'm running under sbt or REPL, don't exit the JVM.

som-snytt avatar Sep 22 '23 00:09 som-snytt

  • reported another issue https://github.com/scala/bug/issues/12878

xuwei-k avatar Sep 22 '23 01:09 xuwei-k

Also note that you can supply mainClass manually.

Compile / run / mainClass := Some("A")

and that would work:

$ sbt -J--enable-preview run
[info] welcome to sbt 1.9.6 (Azul Systems, Inc. Java 21)
[info] loading global plugins from /Users/xxx/.sbt/1.0/plugins
[info] loading project definition from /private/tmp/jdk21/project
[info] loading settings for project jdk21 from build.sbt ...
[info] set current project to jdk21 (in build file:/private/tmp/jdk21/)
[info] running (fork) A
[info] hello

so maybe we can say that sbt works as expected, and the perk of using genuine Scala is you get automatic main detection.

eed3si9n avatar Sep 23 '23 06:09 eed3si9n

To a potential contributor: relevant code in Zinc is here:

another Relevant code

https://github.com/sbt/sbt/blob/586e0a752cd5d0f0335deaa910c4355e0e0a0e56/run/src/main/scala/sbt/Run.scala#L160-L171

xuwei-k avatar Jun 12 '24 01:06 xuwei-k