Gradle Kotlin DSL配置为何无法在Java项目中启用System.in?
Gradle环境下Java Scanner抛出NoSuchElementException的解决办法
问题重现
运行使用Scanner读取控制台输入的Java程序时,抛出如下异常:
Exception in thread "main" java.util.NoSuchElementException: No line found at java.base/java.util.Scanner.nextLine(Scanner.java:1651) at App.main(App.java:11)
尝试改用BufferedReader、调整代码逻辑均无效,无论是VSCode Gradle扩展还是Windows命令行执行gradle run都出现相同问题。相关代码与配置如下:
代码
import java.util.Scanner; public class App { public static void main(String[] args) { // creates an object of Scanner Scanner input = new Scanner(System.in); System.out.print("Enter your name: "); // takes input from the keyboard String name = input.nextLine(); // prints the name System.out.println("My name is " + name); } }
原build.gradle.kts配置
/* * This file was generated by the Gradle 'init' task. * * This generated file contains a sample Java application project to get you started. * For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.2.1/userguide/building_java_projects.html in the Gradle documentation. */ repositories { // Use Maven Central for resolving dependencies. mavenCentral() } dependencies { // Use JUnit Jupiter for testing. testImplementation("org.junit.jupiter:junit-jupiter:5.9.2") testRuntimeOnly("org.junit.platform:junit-platform-launcher") // This dependency is used by the application. implementation("com.google.guava:guava:31.1-jre") } // Apply a specific Java toolchain to ease working on different environments. java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } } application { // Define the main class for the application. mainClass.set("project.App") } tasks.named<Test>("test") { // Use JUnit Platform for unit tests. useJUnitPlatform() } plugins { application } tasks.named<JavaExec>("run") { standardInput = System.`in` }
核心原因
Gradle的run任务默认未将终端的标准输入(System.in)传递给Java程序,且原配置中plugins块位置靠后,导致显式配置的标准输入关联逻辑未生效。
解决方案
1. 调整Gradle配置文件结构
将plugins块移至build.gradle.kts最顶部,确保application插件先加载,后续的run任务配置才能生效:
plugins { application } /* 原注释和其他配置保持不变 */ repositories { mavenCentral() } dependencies { testImplementation("org.junit.jupiter:junit-jupiter:5.9.2") testRuntimeOnly("org.junit.platform:junit-platform-launcher") implementation("com.google.guava:guava:31.1-jre") } java { toolchain { languageVersion.set(JavaLanguageVersion.of(17)) } } application { mainClass.set("project.App") } tasks.named<Test>("test") { useJUnitPlatform() } tasks.named<JavaExec>("run") { standardInput = System.`in` }
2. 确认包结构与主类配置匹配
若mainClass.set("project.App"),则App.java必须放在src/main/java/project/目录下,保证Gradle能正确定位主类。
3. 使用交互式终端运行
- 在VSCode中,打开集成终端直接执行
gradle run,而非通过扩展的"Run"按钮; - 命令行可添加参数确保输出正常:
gradle run --console=plain
4. 代码中添加输入校验(可选)
为避免异常,可在读取前检查输入是否存在:
import java.util.Scanner; public class App { public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("Enter your name: "); if (input.hasNextLine()) { String name = input.nextLine(); System.out.println("My name is " + name); } else { System.out.println("未获取到输入"); } input.close(); } }
内容的提问来源于stack exchange,提问作者Confused
相关产品推荐
相关产品推荐

