827e5e3226
8225052: javax.lang.model support for records 8225053: Preview APIs support for records 8225055: Javadoc for records 8226314: com.sun.source support for records 8227113: Specification for java.lang.Record 8233526: JVM support for records Implement records in the compiler and the JVM, including serialization, reflection and APIs support Co-authored-by: Brian Goetz <brian.goetz@oracle.com> Co-authored-by: Maurizio Cimadamore <maurizio.cimadamore@oracle.com> Co-authored-by: Harold Seigel <harold.seigel@oracle.com> Co-authored-by: Joe Darcy <joe.darcy@oracle.com> Co-authored-by: Jonathan Gibbons <jonathan.gibbons@oracle.com> Co-authored-by: Chris Hegarty <chris.hegarty@oracle.com> Co-authored-by: Jan Lahoda <jan.lahoda@oracle.com> Reviewed-by: mcimadamore, briangoetz, alanb, darcy, chegar, jrose, jlahoda, coleenp, dholmes, lfoltan, mchung, sadayapalam, hannesw, sspitsyn
214 lines
6.3 KiB
Java
214 lines
6.3 KiB
Java
/*
|
|
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 4227137
|
|
* @summary Basic functional test for virtual-machine shutdown hooks
|
|
* @modules java.desktop
|
|
* @library /test/lib
|
|
* @build jdk.test.lib.process.*
|
|
* @run testng Basic
|
|
*/
|
|
|
|
import java.lang.reflect.Method;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.io.PrintStream;
|
|
import java.io.FileOutputStream;
|
|
import java.awt.Frame;
|
|
import java.awt.TextArea;
|
|
import java.awt.event.WindowEvent;
|
|
import java.awt.event.WindowAdapter;
|
|
|
|
import org.testng.annotations.DataProvider;
|
|
import org.testng.annotations.Test;
|
|
import jdk.test.lib.process.ProcessTools;
|
|
|
|
public class Basic {
|
|
|
|
static Runtime rt = Runtime.getRuntime();
|
|
static PrintStream out = System.out;
|
|
|
|
// Expect that no finalizer is invoked at exit
|
|
@DataProvider(name = "testcase")
|
|
public Object[][] getTestCase() {
|
|
return new Object[][] {
|
|
{ "fallThrough", 0, "h1", "" },
|
|
{ "exit0", 0, "h1", "" },
|
|
{ "exit0NoHook", 0, "", "" },
|
|
{ "exit1", 1, "h1", "" },
|
|
{ "exit1NoHook", 1, "", "" },
|
|
{ "halt", 0, "", "" },
|
|
{ "haltNoHook", 0, "", "" },
|
|
{ "haltInHook", 0, "h1", "" },
|
|
{ "addLate", 0, "h1",
|
|
"Caught as expected: java.lang.IllegalStateException: Shutdown in progress" },
|
|
{ "removeLate", 0, "h2",
|
|
"Caught as expected: java.lang.IllegalStateException: Shutdown in progress" }
|
|
};
|
|
}
|
|
|
|
@Test(dataProvider = "testcase")
|
|
public void test(String testcase, int exitValue, String hook, String finalizer)
|
|
throws Exception {
|
|
System.out.println("Test " + testcase);
|
|
ProcessTools.executeTestJava("Basic", testcase)
|
|
.shouldHaveExitValue(exitValue)
|
|
.stdoutShouldMatch(
|
|
hook + (hook.isEmpty() ? "" : System.lineSeparator()) + finalizer);
|
|
System.out.println("Passed");
|
|
}
|
|
|
|
public static class Fin {
|
|
String name;
|
|
|
|
public Fin(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
public void go() { }
|
|
|
|
protected void finalize() {
|
|
out.println(name);
|
|
go();
|
|
}
|
|
}
|
|
|
|
|
|
public static class Hook extends Thread {
|
|
String name;
|
|
|
|
public Hook(String name) {
|
|
this.name = name;
|
|
}
|
|
|
|
public void go() { }
|
|
|
|
public void run() {
|
|
out.println(name);
|
|
go();
|
|
}
|
|
}
|
|
|
|
public static void fallThrough() throws Exception {
|
|
rt.addShutdownHook(new Hook("h1"));
|
|
Fin f = new Fin("f1");
|
|
}
|
|
|
|
public static void exit0() throws Exception {
|
|
rt.addShutdownHook(new Hook("h1"));
|
|
Fin f = new Fin("f1");
|
|
rt.exit(0);
|
|
}
|
|
|
|
public static void exit0NoHook() throws Exception {
|
|
Fin f = new Fin("f1");
|
|
rt.exit(0);
|
|
}
|
|
|
|
/* Finalizer should not run */
|
|
public static void exit1() throws Exception {
|
|
rt.addShutdownHook(new Hook("h1"));
|
|
Fin f = new Fin("f1");
|
|
rt.exit(1);
|
|
}
|
|
|
|
public static void exit1NoHook() throws Exception {
|
|
Fin f = new Fin("f1");
|
|
rt.exit(1);
|
|
}
|
|
|
|
public static void halt() throws Exception {
|
|
rt.addShutdownHook(new Hook("h1") {
|
|
public void go() { rt.halt(1); }});
|
|
Fin f = new Fin("f1") { public void go() { rt.halt(1); }};
|
|
rt.halt(0);
|
|
}
|
|
|
|
public static void haltNoHook() throws Exception {
|
|
Fin f = new Fin("f1") { public void go() { rt.halt(1); }};
|
|
rt.halt(0);
|
|
}
|
|
|
|
public static void haltInHook() throws Exception {
|
|
rt.addShutdownHook(new Hook("h1") {
|
|
public void go() { rt.halt(0); }});
|
|
Fin f = new Fin("f1");
|
|
rt.exit(1);
|
|
}
|
|
|
|
public static void addLate() throws Exception {
|
|
rt.addShutdownHook(new Hook("h1") {
|
|
public void go() {
|
|
try {
|
|
rt.addShutdownHook(new Hook("h2"));
|
|
} catch (IllegalStateException x) {
|
|
out.println("Caught as expected: " + x);
|
|
rt.halt(0);
|
|
}
|
|
}});
|
|
rt.exit(1);
|
|
}
|
|
|
|
public static void removeLate() throws Exception {
|
|
final Hook h1 = new Hook("h1");
|
|
rt.addShutdownHook(new Hook("h2") {
|
|
public void go() {
|
|
try {
|
|
rt.removeShutdownHook(h1);
|
|
} catch (IllegalStateException x) {
|
|
out.println("Caught as expected: " + x);
|
|
rt.halt(0);
|
|
}
|
|
}});
|
|
rt.exit(1);
|
|
}
|
|
|
|
/* For INT, HUP, TERM */
|
|
public static void stall() throws Exception {
|
|
Fin f = new Fin("f1");
|
|
rt.addShutdownHook(new Hook("h1"));
|
|
out.print("Type ^C now: ");
|
|
out.flush();
|
|
Thread.sleep(100000);
|
|
}
|
|
|
|
|
|
public static void main(String[] args) throws Throwable {
|
|
Method m = Basic.class.getMethod(args[0], new Class[] { });
|
|
String log = null;
|
|
try {
|
|
log = System.getProperty("log");
|
|
} catch (SecurityException x) { }
|
|
if (log != null) {
|
|
out = new PrintStream(new FileOutputStream(log), true);
|
|
}
|
|
try {
|
|
m.invoke(null, new Object[] { });
|
|
} catch (InvocationTargetException x) {
|
|
throw x.getTargetException();
|
|
}
|
|
}
|
|
|
|
}
|