From 7afd9570c522fad998d2eb056fde172e894cb7c4 Mon Sep 17 00:00:00 2001 From: Achal Talati Date: Fri, 31 Oct 2025 11:47:10 +0530 Subject: [PATCH] Fixed notebook issue when scanner input stream closes itself on no input from the user --- .../nbcode/java/notebook/CustomInputStream.java | 12 +++++++++--- .../nbcode/java/notebook/CustomInputStreamTest.java | 7 ++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/nbcode/notebooks/src/org/netbeans/modules/nbcode/java/notebook/CustomInputStream.java b/nbcode/notebooks/src/org/netbeans/modules/nbcode/java/notebook/CustomInputStream.java index 031f5f01..0d5ffd55 100644 --- a/nbcode/notebooks/src/org/netbeans/modules/nbcode/java/notebook/CustomInputStream.java +++ b/nbcode/notebooks/src/org/netbeans/modules/nbcode/java/notebook/CustomInputStream.java @@ -16,6 +16,7 @@ package org.netbeans.modules.nbcode.java.notebook; import java.io.ByteArrayInputStream; +import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; @@ -53,14 +54,16 @@ public synchronized int read(byte[] b, int off, int len) throws IOException { NbCodeLanguageClient client = this.client.get(); if (client == null) { LOG.log(Level.WARNING, "client is null"); - return -1; + throw new EOFException("User input dismissed"); } CompletableFuture future = client.showInputBox(new ShowInputBoxParams(USER_PROMPT_REQUEST, "", true)); String userInput = future.get(); if (userInput == null) { LOG.log(Level.WARNING, "User input is null"); - return -1; + // Workaround: jshell closes the input stream when -1 is returned and provides no way to reset it. + // This hack bypasses that behavior to prevent the stream from being closed. + throw new EOFException("User input dismissed"); } byte[] inputBytes = (userInput + System.lineSeparator()).getBytes(StandardCharsets.UTF_8); @@ -80,6 +83,9 @@ public synchronized int read(byte[] b, int off, int len) throws IOException { public int read() throws IOException { byte[] oneByte = new byte[1]; int n = read(oneByte, 0, 1); - return (n == -1) ? -1 : oneByte[0] & 0xFF; + if (n == -1) { + throw new EOFException("User input dismissed"); + } + return oneByte[0] & 0xFF; } } diff --git a/nbcode/notebooks/test/unit/src/org/netbeans/modules/nbcode/java/notebook/CustomInputStreamTest.java b/nbcode/notebooks/test/unit/src/org/netbeans/modules/nbcode/java/notebook/CustomInputStreamTest.java index 23b391d6..b081c07c 100644 --- a/nbcode/notebooks/test/unit/src/org/netbeans/modules/nbcode/java/notebook/CustomInputStreamTest.java +++ b/nbcode/notebooks/test/unit/src/org/netbeans/modules/nbcode/java/notebook/CustomInputStreamTest.java @@ -1,10 +1,11 @@ package org.netbeans.modules.nbcode.java.notebook; +import java.io.EOFException; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -33,10 +34,10 @@ public void tearDown() { @Test public void testReadNoClient() throws IOException { inputStream = new CustomInputStream(null); - assertEquals(-1, inputStream.read()); + Assert.assertThrows(EOFException.class, ()-> inputStream.read()); byte[] buffer = new byte[10]; - assertEquals(-1, inputStream.read(buffer, 0, 10)); + Assert.assertThrows(EOFException.class, ()-> inputStream.read(buffer, 0, 10)); } @Test