diff --git a/build.mill b/build.mill index 1af20417066..cf3f4daf0a4 100644 --- a/build.mill +++ b/build.mill @@ -387,6 +387,14 @@ trait MillJavaModule extends JavaModule { Deps.jline, Deps.jna ) + + def javadocOptions = super.javadocOptions() ++ Seq( + // Disable warnings for missing documentation comments or tags (for example, + // a missing comment or class, or a missing @return tag or similar tag on a method). + // We have many methods without JavaDoc comments, so those warnings are useless + // and significantly clutter the output. + "-Xdoclint:all,-missing" + ) } trait MillPublishJavaModule extends MillJavaModule with PublishModule { diff --git a/main/client/src/mill/main/client/ServerLauncher.java b/main/client/src/mill/main/client/ServerLauncher.java index 5590cc3e712..cc22b9b5688 100644 --- a/main/client/src/mill/main/client/ServerLauncher.java +++ b/main/client/src/mill/main/client/ServerLauncher.java @@ -118,7 +118,7 @@ public Result acquireLocksAndRun(String outDir) throws Exception { int run(Path serverDir, boolean setJnaNoSys, Locks locks) throws Exception { try (OutputStream f = Files.newOutputStream(serverDir.resolve(ServerFiles.runArgs))) { - f.write(System.console() != null ? 1 : 0); + f.write(Util.hasConsole() ? 1 : 0); Util.writeString(f, BuildInfo.millVersion); Util.writeArgs(args, f); Util.writeMap(env, f); diff --git a/main/client/src/mill/main/client/Util.java b/main/client/src/mill/main/client/Util.java index fd6ececad09..c65c5fda938 100644 --- a/main/client/src/mill/main/client/Util.java +++ b/main/client/src/mill/main/client/Util.java @@ -1,10 +1,13 @@ package mill.main.client; +import java.io.Console; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.math.BigInteger; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -38,6 +41,31 @@ public static final int ExitServerCodeWhenVersionMismatch() { !System.getProperty("java.specification.version").startsWith("1."); private static Charset utf8 = Charset.forName("UTF-8"); + /** + * Determines if we have an interactive console attached to the application. + *
+ * Before JDK 22 we could use System.console() != null
to do that check.
+ * However, with JDK >= 22 it no longer works because System.console()
+ * always returns a console instance even for redirected streams. Instead,
+ * JDK >= 22 introduced the method `Console.isTerminal`.
+ * See: JLine As The Default Console Provider (JDK-8308591)
+ *
+ * This method takes into account these differences and is compatible with + * both JDK versions before 22 and later. + */ + public static boolean hasConsole() { + Console console = System.console(); + + if (console != null) { + try { + Method method = console.getClass().getMethod("isTerminal"); + return (Boolean) method.invoke(console); + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException ignored) { + return true; + } + } else return false; + } + public static String[] parseArgs(InputStream argStream) throws IOException { int argsLength = readInt(argStream); String[] args = new String[argsLength]; diff --git a/main/util/src/mill/util/Util.scala b/main/util/src/mill/util/Util.scala index 9b7cdc60e7d..b9a89af75ee 100644 --- a/main/util/src/mill/util/Util.scala +++ b/main/util/src/mill/util/Util.scala @@ -8,7 +8,7 @@ import mill.api.{BuildInfo, Ctx, IO, PathRef, Result} object Util { - def isInteractive(): Boolean = System.console() != null + def isInteractive(): Boolean = mill.main.client.Util.hasConsole() val newLine: String = System.lineSeparator() diff --git a/runner/client/src/mill/runner/client/MillProcessLauncher.java b/runner/client/src/mill/runner/client/MillProcessLauncher.java index 0b862e0ee49..544cce8b495 100644 --- a/runner/client/src/mill/runner/client/MillProcessLauncher.java +++ b/runner/client/src/mill/runner/client/MillProcessLauncher.java @@ -218,7 +218,7 @@ static void writeTerminalDims(boolean tputExists, Path serverDir) throws Excepti String str; try { - if (java.lang.System.console() == null) str = "0 0"; + if (!Util.hasConsole()) str = "0 0"; else { if (!tputExists) { // Hardcoded size of a quarter screen terminal on 13" windows laptop diff --git a/runner/src/mill/runner/MillMain.scala b/runner/src/mill/runner/MillMain.scala index fa553492d85..7cc01375bd5 100644 --- a/runner/src/mill/runner/MillMain.scala +++ b/runner/src/mill/runner/MillMain.scala @@ -10,7 +10,7 @@ import mill.java9rtexport.Export import mill.api.{MillException, SystemStreams, WorkspaceRoot, internal} import mill.bsp.{BspContext, BspServerResult} import mill.main.BuildInfo -import mill.main.client.{OutFiles, ServerFiles} +import mill.main.client.{OutFiles, ServerFiles, Util} import mill.main.client.lock.Lock import mill.util.{Colors, PrintLogger, PromptLogger} @@ -68,7 +68,7 @@ object MillMain { (initialSystemStreams, Seq(), None) } - if (Properties.isWin && System.console() != null) + if (Properties.isWin && Util.hasConsole()) io.github.alexarchambault.windowsansi.WindowsAnsi.setup() val (result, _) =