You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gradle运行含java.io.Console终端API应用异常,如何让Gradle不干扰终端访问?

解决方案

这个问题本质是Gradle默认会对JavaExec任务的输入输出流做包装,用来实现自身的日志、进度条等功能,导致你的应用拿不到真实的终端句柄。下面给你几个可行的解决办法:

1. 用Gradle 7.0+的terminal属性(最推荐)

从Gradle 7.0开始,JavaExec任务新增了terminal属性,只要把它设置为TerminalMode.ATTACHED,就能让应用直接附加到当前终端,跳过Gradle的流包装。

如果是Kotlin DSL,配置如下:

// 针对所有JavaExec任务
tasks.withType<JavaExec> {
    terminal = TerminalMode.ATTACHED
}

// 或者只针对run任务
private val run: JavaExec by tasks
run.apply {
    terminal = TerminalMode.ATTACHED
}

如果是Groovy DSL:

tasks.withType(JavaExec) {
    terminal = TerminalMode.ATTACHED
}

这个配置会让Gradle把真实的终端输入、输出、错误流直接传递给你的应用,System.console()就能正常拿到实例,终端操作也能正常工作。

2. 配合application插件的配置

如果你用了Gradle的application插件,也可以直接在application扩展里配置run任务的终端模式:

Kotlin DSL:

application {
    run {
        terminal = TerminalMode.ATTACHED
    }
}

Groovy DSL:

application {
    run {
        terminal = TerminalMode.ATTACHED
    }
}

3. 旧版Gradle的替代方案(Gradle <7.0)

如果你的Gradle版本低于7.0,没有terminal属性,可以通过execSpec强制使用系统原生的流,同时添加JVM参数确保Console可用:

Kotlin DSL:

tasks.withType<JavaExec> {
    execSpec {
        standardInput = System.`in`
        standardOutput = System.out
        errorOutput = System.err
        isRedirectErrorStream = false
    }
    // 添加JVM参数,确保Java能识别到终端
    jvmArgs("-Djava.awt.headless=false")
}

不过这个方案在复杂场景下可能不如TerminalMode.ATTACHED稳定,建议尽量升级到Gradle 7+版本。

验证效果

配置完成后,再运行gradle run(可以加--console=plain避免Gradle自身的输出干扰),你的应用应该就能正常识别终端了:System.console()不再返回null,加粗、彩色文本能正常显示,交互式提示也能正常工作。


内容的提问来源于stack exchange,提问作者Андрей Щеглов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:43:29