Skip to content

[2.x] Support JDK 25 JEP-512/JEP-445 Main class - #1601

Merged
eed3si9n merged 1 commit into
sbt:developfrom
eed3si9n:wip/jdk25-main
Sep 27, 2025
Merged

[2.x] Support JDK 25 JEP-512/JEP-445 Main class#1601
eed3si9n merged 1 commit into
sbt:developfrom
eed3si9n:wip/jdk25-main

Conversation

@eed3si9n

Copy link
Copy Markdown
Member

Ref sbt/sbt#7384

Problem

sbt currently does not support JDK 25 Main class. JDK 25 supports:

  1. non-public main method
  2. doesn't need Array[String] arg
  3. doesn't have to be a static method

Solution

This fixes the Main class detection for the reference compiler bridge, which is used for Scala 2.10 - 2.12, and Scala 2.13 until 2.13.11. (Luckily, 2.13.11 is compatible with JDK 25, so we can use that to test 2.13)

@lrytz

lrytz commented Sep 26, 2025

Copy link
Copy Markdown
Contributor

I copied your patch to the bridge in scala/scala (2.13.x) and tried a local build. It works when setting fork := true (which seems to be the default on sbt 2.0.0-M4). Without forking I get

sbt:sbtproj> run
[info] running Test
[error] java.lang.NoSuchMethodException: Test.main([Ljava.lang.String;)
[error] 	at java.base/java.lang.Class.getMethod(Class.java:2166)
[error] stack trace is suppressed; run last Compile / run for the full output
[error] (Compile / run) java.lang.NoSuchMethodException: Test.main([Ljava.lang.String;)
[error] Total time: 0 s, completed 26 Sept 2025, 07:51:29

As mentioned by @xuwei-k, that's probably here:

https://github.com/sbt/sbt/blob/d44b2c87209364e699cce883a4891f48b25c436f/run/src/main/scala/sbt/Run.scala#L167-L169

For main methods written in Java, sbt 1.11.6 finds public static void main(String... args), but not when removing either public or static or the argument. Is that implemented here?

if (
c.getMethods.exists(meth =>
meth.getName == "main" &&
Modifier.isStatic(meth.getModifiers) &&
meth.getParameterTypes.length == 1 &&
meth.getParameterTypes.head == classOf[Array[String]] &&
meth.getReturnType == java.lang.Void.TYPE
)
) {
cmap.mainClasses += name

@eed3si9n

Copy link
Copy Markdown
Member Author

Yea, for in-process run emulation, we need to change sbt itself.

} catch {
case _: Throwable => 0
}
private[this] def isJava25Plus: Boolean = javaVersion >= 25

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used scala.util.Properties.isJavaAtLeast(25) on scala/scala, but here it's probably safer not to rely on old (2.11) library code.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I consolidated the pre / post 25 checks a bit in scala/scala#11137

Comment thread internal/compiler-bridge/src/main/scala/xsbt/ExtractAPI.scala Outdated
@lrytz

lrytz commented Sep 26, 2025

Copy link
Copy Markdown
Contributor

I also updated https://github.com/sbt/zinc/tree/develop/zinc/src/sbt-test/apiinfo/main-discovery in scala/scala#11137, that should apply here as well.

**Problem**
sbt currently does not support JDK 25 Main class. JDK 25 supports:
1. non-public main method
2. doesn't need Array[String] arg
3. doesn't have to be a static method

**Solution**
This fixes the Main class detection for the reference compiler bridge,
which is used for Scala 2.10 - 2.12, and Scala 2.13 until 2.13.11.
Luckily, 2.13.11 is compatible with JDK 25.

Co-authored-by: Lukas Rytz <lukas.rytz@gmail.com>
@eed3si9n

Copy link
Copy Markdown
Member Author

Thanks! I've incorporated the scripted test change here.

@eed3si9n
eed3si9n merged commit d79c92d into sbt:develop Sep 27, 2025
9 checks passed
@eed3si9n
eed3si9n deleted the wip/jdk25-main branch September 27, 2025 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants