8338281: jshell does not run shutdown hooks
Reviewed-by: asotona
This commit is contained in:
parent
d35ffa4f6a
commit
8c8b5801fd
@ -177,7 +177,7 @@ class ExecutionControlForwarder {
|
|||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
// JShell-core not waiting for a result, ignore
|
// JShell-core not waiting for a result, ignore
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
Object arg = in.readObject();
|
Object arg = in.readObject();
|
||||||
|
@ -49,6 +49,7 @@ import com.sun.jdi.VMDisconnectedException;
|
|||||||
import com.sun.jdi.VirtualMachine;
|
import com.sun.jdi.VirtualMachine;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import jdk.jshell.JShellConsole;
|
import jdk.jshell.JShellConsole;
|
||||||
import jdk.jshell.execution.JdiDefaultExecutionControl.JdiStarter.TargetDescription;
|
import jdk.jshell.execution.JdiDefaultExecutionControl.JdiStarter.TargetDescription;
|
||||||
@ -70,6 +71,8 @@ import jdk.jshell.execution.impl.ConsoleImpl.ConsoleOutputStream;
|
|||||||
*/
|
*/
|
||||||
public class JdiDefaultExecutionControl extends JdiExecutionControl {
|
public class JdiDefaultExecutionControl extends JdiExecutionControl {
|
||||||
|
|
||||||
|
private static final int SHUTDOWN_TIMEOUT = 1; //1 second
|
||||||
|
|
||||||
private VirtualMachine vm;
|
private VirtualMachine vm;
|
||||||
private Process process;
|
private Process process;
|
||||||
private final String remoteAgent;
|
private final String remoteAgent;
|
||||||
@ -267,6 +270,20 @@ public class JdiDefaultExecutionControl extends JdiExecutionControl {
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
super.close();
|
super.close();
|
||||||
|
|
||||||
|
Process remoteProcess;
|
||||||
|
|
||||||
|
synchronized (this) {
|
||||||
|
remoteProcess = this.process;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remoteProcess != null) {
|
||||||
|
try {
|
||||||
|
remoteProcess.waitFor(SHUTDOWN_TIMEOUT, TimeUnit.SECONDS);
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
debug(ex, "waitFor remote");
|
||||||
|
}
|
||||||
|
}
|
||||||
disposeVM();
|
disposeVM();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,11 @@
|
|||||||
* @run testng ShutdownTest
|
* @run testng ShutdownTest
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import jdk.jshell.JShell;
|
import jdk.jshell.JShell;
|
||||||
@ -35,8 +40,9 @@ import jdk.jshell.JShell.Subscription;
|
|||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertFalse;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
|
||||||
@Test
|
|
||||||
public class ShutdownTest extends KullaTesting {
|
public class ShutdownTest extends KullaTesting {
|
||||||
|
|
||||||
int shutdownCount;
|
int shutdownCount;
|
||||||
@ -53,6 +59,7 @@ public class ShutdownTest extends KullaTesting {
|
|||||||
assertEquals(shutdownCount, 1);
|
assertEquals(shutdownCount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testCloseCallback() {
|
public void testCloseCallback() {
|
||||||
shutdownCount = 0;
|
shutdownCount = 0;
|
||||||
getState().onShutdown(this::shutdownCounter);
|
getState().onShutdown(this::shutdownCounter);
|
||||||
@ -60,6 +67,7 @@ public class ShutdownTest extends KullaTesting {
|
|||||||
assertEquals(shutdownCount, 1);
|
assertEquals(shutdownCount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testCloseUnsubscribe() {
|
public void testCloseUnsubscribe() {
|
||||||
shutdownCount = 0;
|
shutdownCount = 0;
|
||||||
Subscription token = getState().onShutdown(this::shutdownCounter);
|
Subscription token = getState().onShutdown(this::shutdownCounter);
|
||||||
@ -68,6 +76,7 @@ public class ShutdownTest extends KullaTesting {
|
|||||||
assertEquals(shutdownCount, 0);
|
assertEquals(shutdownCount, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testTwoShutdownListeners() {
|
public void testTwoShutdownListeners() {
|
||||||
ShutdownListener listener1 = new ShutdownListener();
|
ShutdownListener listener1 = new ShutdownListener();
|
||||||
ShutdownListener listener2 = new ShutdownListener();
|
ShutdownListener listener2 = new ShutdownListener();
|
||||||
@ -118,6 +127,51 @@ public class ShutdownTest extends KullaTesting {
|
|||||||
getState().onShutdown(e -> {});
|
getState().onShutdown(e -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRunShutdownHooks() throws IOException {
|
||||||
|
Path temporary = Paths.get("temp");
|
||||||
|
Files.newOutputStream(temporary).close();
|
||||||
|
assertEval("import java.io.*;");
|
||||||
|
assertEval("import java.nio.file.*;");
|
||||||
|
assertEval("""
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
|
try {
|
||||||
|
Files.delete(Paths.get("$TEMPORARY"));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
//ignored
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
""".replace("$TEMPORARY", temporary.toAbsolutePath()
|
||||||
|
.toString()
|
||||||
|
.replace("\\", "\\\\")));
|
||||||
|
getState().close();
|
||||||
|
assertFalse(Files.exists(temporary));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Method currentTestMethod;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUp(Method testMethod) {
|
||||||
|
currentTestMethod = testMethod;
|
||||||
|
super.setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setUp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp(Consumer<JShell.Builder> bc) {
|
||||||
|
Consumer<JShell.Builder> augmentedBuilder = switch (currentTestMethod.getName()) {
|
||||||
|
case "testRunShutdownHooks" -> builder -> {
|
||||||
|
builder.executionEngine(Presets.TEST_STANDARD_EXECUTION);
|
||||||
|
bc.accept(builder);
|
||||||
|
};
|
||||||
|
default -> bc;
|
||||||
|
};
|
||||||
|
super.setUp(augmentedBuilder);
|
||||||
|
}
|
||||||
|
|
||||||
private static class ShutdownListener implements Consumer<JShell> {
|
private static class ShutdownListener implements Consumer<JShell> {
|
||||||
private int count;
|
private int count;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user