diff --git a/jdk/make/mapfiles/libjava/mapfile-vers b/jdk/make/mapfiles/libjava/mapfile-vers index 24454049312..8c1172b08b6 100644 --- a/jdk/make/mapfiles/libjava/mapfile-vers +++ b/jdk/make/mapfiles/libjava/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2022, 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 @@ -140,7 +140,6 @@ SUNWprivate_1.1 { Java_java_lang_Double_longBitsToDouble; Java_java_lang_Double_doubleToRawLongBits; Java_java_lang_reflect_Proxy_defineClass0; - Java_java_lang_Shutdown_runAllFinalizers; Java_java_lang_Float_intBitsToFloat; Java_java_lang_Float_floatToRawIntBits; Java_java_lang_StrictMath_IEEEremainder; @@ -278,7 +277,7 @@ SUNWprivate_1.1 { Java_sun_misc_VM_initialize; Java_sun_misc_VMSupport_initAgentProperties; Java_sun_misc_VMSupport_getVMTemporaryDirectory; - + # ZipFile.c needs this one throwFileNotFoundException; # zip_util.c needs this diff --git a/jdk/src/share/classes/java/lang/Runtime.java b/jdk/src/share/classes/java/lang/Runtime.java index a64458e1e39..6819542c6ea 100644 --- a/jdk/src/share/classes/java/lang/Runtime.java +++ b/jdk/src/share/classes/java/lang/Runtime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2022, 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 @@ -67,38 +67,32 @@ private Runtime() {} * serves as a status code; by convention, a nonzero status code indicates * abnormal termination. * - *

The virtual machine's shutdown sequence consists of two phases. In - * the first phase all registered {@link #addShutdownHook shutdown hooks}, - * if any, are started in some unspecified order and allowed to run - * concurrently until they finish. In the second phase all uninvoked - * finalizers are run if {@link #runFinalizersOnExit finalization-on-exit} - * has been enabled. Once this is done the virtual machine {@link #halt - * halts}. - * - *

If this method is invoked after the virtual machine has begun its - * shutdown sequence then if shutdown hooks are being run this method will - * block indefinitely. If shutdown hooks have already been run and on-exit - * finalization has been enabled then this method halts the virtual machine - * with the given status code if the status is nonzero; otherwise, it + *

All registered {@linkplain #addShutdownHook shutdown hooks}, if any, + * are started in some unspecified order and allowed to run concurrently + * until they finish. Once this is done the virtual machine + * {@linkplain #halt halts}. + * + *

If this method is invoked after all shutdown hooks have already + * been run and the status is nonzero then this method halts the + * virtual machine with the given status code. Otherwise, this method * blocks indefinitely. * - *

The {@link System#exit(int) System.exit} method is the - * conventional and convenient means of invoking this method.

+ *

The {@link System#exit(int) System.exit} method is the + * conventional and convenient means of invoking this method. * * @param status * Termination status. By convention, a nonzero status code * indicates abnormal termination. * * @throws SecurityException - * If a security manager is present and its {@link - * SecurityManager#checkExit checkExit} method does not permit + * If a security manager is present and its + * {@link SecurityManager#checkExit checkExit} method does not permit * exiting with the specified status * * @see java.lang.SecurityException * @see java.lang.SecurityManager#checkExit(int) * @see #addShutdownHook * @see #removeShutdownHook - * @see #runFinalizersOnExit * @see #halt(int) */ public void exit(int status) { @@ -118,11 +112,11 @@ public void exit(int status) { *

@@ -131,20 +125,18 @@ public void exit(int status) { * thread. When the virtual machine begins its shutdown sequence it will * start all registered shutdown hooks in some unspecified order and let * them run concurrently. When all the hooks have finished it will then - * run all uninvoked finalizers if finalization-on-exit has been enabled. - * Finally, the virtual machine will halt. Note that daemon threads will - * continue to run during the shutdown sequence, as will non-daemon threads - * if shutdown was initiated by invoking the {@link #exit exit} - * method. + * halt. Note that daemon threads will continue to run during the shutdown + * sequence, as will non-daemon threads if shutdown was initiated by + * invoking the {@link #exit exit} method. * *

Once the shutdown sequence has begun it can be stopped only by - * invoking the {@link #halt halt} method, which forcibly + * invoking the {@link #halt halt} method, which forcibly * terminates the virtual machine. * *

Once the shutdown sequence has begun it is impossible to register a * new shutdown hook or de-register a previously-registered hook. * Attempting either of these operations will cause an - * {@link IllegalStateException} to be thrown. + * {@link IllegalStateException} to be thrown. * *

Shutdown hooks run at a delicate time in the life cycle of a virtual * machine and should therefore be coded defensively. They should, in @@ -156,7 +148,7 @@ public void exit(int status) { * deadlocks. * *

Shutdown hooks should also finish their work quickly. When a - * program invokes {@link #exit exit} the expectation is + * program invokes {@link #exit exit} the expectation is * that the virtual machine will promptly shut down and exit. When the * virtual machine is terminated due to user logoff or system shutdown the * underlying operating system may only allow a fixed amount of time in @@ -165,25 +157,25 @@ public void exit(int status) { * hook. * *

Uncaught exceptions are handled in shutdown hooks just as in any - * other thread, by invoking the {@link ThreadGroup#uncaughtException - * uncaughtException} method of the thread's {@link - * ThreadGroup} object. The default implementation of this method - * prints the exception's stack trace to {@link System#err} and + * other thread, by invoking the + * {@link ThreadGroup#uncaughtException uncaughtException} method of the + * thread's {@link ThreadGroup} object. The default implementation of this + * method prints the exception's stack trace to {@link System#err} and * terminates the thread; it does not cause the virtual machine to exit or * halt. * *

In rare circumstances the virtual machine may abort, that is, * stop running without shutting down cleanly. This occurs when the * virtual machine is terminated externally, for example with the - * SIGKILL signal on Unix or the TerminateProcess call on + * {@code SIGKILL} signal on Unix or the {@code TerminateProcess} call on * Microsoft Windows. The virtual machine may also abort if a native * method goes awry by, for example, corrupting internal data structures or * attempting to access nonexistent memory. If the virtual machine aborts * then no guarantee can be made about whether or not any shutdown hooks - * will be run.

+ * will be run. * * @param hook - * An initialized but unstarted {@link Thread} object + * An initialized but unstarted {@link Thread} object * * @throws IllegalArgumentException * If the specified hook has already been registered, @@ -196,7 +188,7 @@ public void exit(int status) { * * @throws SecurityException * If a security manager is present and it denies - * {@link RuntimePermission}("shutdownHooks") + * {@link RuntimePermission}{@code ("shutdownHooks")} * * @see #removeShutdownHook * @see #halt(int) @@ -244,23 +236,22 @@ public boolean removeShutdownHook(Thread hook) { * method never returns normally. * *

This method should be used with extreme caution. Unlike the - * {@link #exit exit} method, this method does not cause shutdown - * hooks to be started and does not run uninvoked finalizers if - * finalization-on-exit has been enabled. If the shutdown sequence has - * already been initiated then this method does not wait for any running - * shutdown hooks or finalizers to finish their work.

+ * {@link #exit exit} method, this method does not cause shutdown + * hooks to be started. If the shutdown sequence has already been + * initiated then this method does not wait for any running + * shutdown hooks to finish their work. * * @param status - * Termination status. By convention, a nonzero status code - * indicates abnormal termination. If the {@link Runtime#exit - * exit} (equivalently, {@link System#exit(int) - * System.exit}) method has already been invoked then this - * status code will override the status code passed to that method. + * Termination status. By convention, a nonzero status code + * indicates abnormal termination. If the {@link Runtime#exit exit} + * (equivalently, {@link System#exit(int) System.exit}) method + * has already been invoked then this status code + * will override the status code passed to that method. * * @throws SecurityException - * If a security manager is present and its {@link - * SecurityManager#checkExit checkExit} method does not permit - * an exit with the specified status + * If a security manager is present and its + * {@link SecurityManager#checkExit checkExit} method + * does not permit an exit with the specified status * * @see #exit * @see #addShutdownHook @@ -277,42 +268,23 @@ public void halt(int status) { } /** - * Enable or disable finalization on exit; doing so specifies that the - * finalizers of all objects that have finalizers that have not yet been - * automatically invoked are to be run before the Java runtime exits. - * By default, finalization on exit is disabled. - * - *

If there is a security manager, - * its checkExit method is first called - * with 0 as its argument to ensure the exit is allowed. - * This could result in a SecurityException. - * - * @param value true to enable finalization on exit, false to disable - * @deprecated This method is inherently unsafe. It may result in - * finalizers being called on live objects while other threads are - * concurrently manipulating those objects, resulting in erratic - * behavior or deadlock. + * Throws {@code UnsupportedOperationException}. * - * @throws SecurityException - * if a security manager exists and its checkExit - * method doesn't allow the exit. + * @param value ignored * - * @see java.lang.Runtime#exit(int) - * @see java.lang.Runtime#gc() - * @see java.lang.SecurityManager#checkExit(int) - * @since JDK1.1 + * @deprecated This method was originally designed to enable or disable + * running finalizers on exit. Running finalizers on exit was disabled by default. + * If enabled, then the finalizers of all objects whose finalizers had not + * yet been automatically invoked were to be run before the Java runtime exits. + * That behavior is inherently unsafe. It may result in finalizers being called + * on live objects while other threads are concurrently manipulating those objects, + * resulting in erratic behavior or deadlock. + * + * @since JDK1.1 */ @Deprecated public static void runFinalizersOnExit(boolean value) { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - try { - security.checkExit(0); - } catch (SecurityException e) { - throw new SecurityException("runFinalizersOnExit"); - } - } - Shutdown.setRunFinalizersOnExit(value); + throw new UnsupportedOperationException(); } /** diff --git a/jdk/src/share/classes/java/lang/Shutdown.java b/jdk/src/share/classes/java/lang/Shutdown.java index 959493eb902..db97de607d1 100644 --- a/jdk/src/share/classes/java/lang/Shutdown.java +++ b/jdk/src/share/classes/java/lang/Shutdown.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, 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 @@ -25,36 +25,34 @@ package java.lang; - /** * Package-private utility class containing data structures and logic * governing the virtual-machine shutdown sequence. * * @author Mark Reinhold * @since 1.3 + * + * @see java.io.Console + * @see ApplicationShutdownHooks + * @see java.io.DeleteOnExitHook */ class Shutdown { - /* Shutdown state */ - private static final int RUNNING = 0; - private static final int HOOKS = 1; - private static final int FINALIZERS = 2; - private static int state = RUNNING; - - /* Should we run all finalizers upon exit? */ - private static boolean runFinalizersOnExit = false; - // The system shutdown hooks are registered with a predefined slot. // The list of shutdown hooks is as follows: // (0) Console restore hook - // (1) Application hooks + // (1) ApplicationShutdownHooks that invokes all registered application + // shutdown hooks and waits until they finish // (2) DeleteOnExit hook private static final int MAX_SYSTEM_HOOKS = 10; private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS]; // the index of the currently running shutdown hook to the hooks array - private static int currentRunningHook = 0; + private static int currentRunningHook = -1; + + // track whether we have already (commenced) shutdown + private static boolean isShutdown; /* The preceding static fields are protected by this lock */ private static class Lock { }; @@ -63,44 +61,39 @@ private static class Lock { }; /* Lock object for the native halt method */ private static Object haltLock = new Lock(); - /* Invoked by Runtime.runFinalizersOnExit */ - static void setRunFinalizersOnExit(boolean run) { - synchronized (lock) { - runFinalizersOnExit = run; - } - } - - /** - * Add a new shutdown hook. Checks the shutdown state and the hook itself, - * but does not do any security checks. + * Add a new system shutdown hook. Checks the shutdown state and + * the hook itself, but does not do any security checks. * * The registerShutdownInProgress parameter should be false except * registering the DeleteOnExitHook since the first file may * be added to the delete on exit list by the application shutdown * hooks. * - * @params slot the slot in the shutdown hook array, whose element - * will be invoked in order during shutdown - * @params registerShutdownInProgress true to allow the hook - * to be registered even if the shutdown is in progress. - * @params hook the hook to be registered + * @param slot the slot in the shutdown hook array, whose element + * will be invoked in order during shutdown + * @param registerShutdownInProgress true to allow the hook + * to be registered even if the shutdown is in progress. + * @param hook the hook to be registered * - * @throw IllegalStateException - * if registerShutdownInProgress is false and shutdown is in progress; or - * if registerShutdownInProgress is true and the shutdown process - * already passes the given slot + * @throws IllegalStateException + * if registerShutdownInProgress is false and shutdown is in progress; or + * if registerShutdownInProgress is true and the shutdown process + * already passes the given slot */ static void add(int slot, boolean registerShutdownInProgress, Runnable hook) { + if (slot < 0 || slot >= MAX_SYSTEM_HOOKS) { + throw new IllegalArgumentException("Invalid slot: " + slot); + } synchronized (lock) { if (hooks[slot] != null) throw new InternalError("Shutdown hook at slot " + slot + " already registered"); if (!registerShutdownInProgress) { - if (state > RUNNING) + if (currentRunningHook >= 0) throw new IllegalStateException("Shutdown in progress"); } else { - if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook)) + if (isShutdown || slot <= currentRunningHook) throw new IllegalStateException("Shutdown in progress"); } @@ -108,9 +101,23 @@ static void add(int slot, boolean registerShutdownInProgress, Runnable hook) { } } - /* Run all registered shutdown hooks + /* Run all system shutdown hooks. + * + * The system shutdown hooks are run in the thread synchronized on + * Shutdown.class. Other threads calling Runtime::exit, Runtime::halt + * or JNI DestroyJavaVM will block indefinitely. + * + * ApplicationShutdownHooks is registered as one single hook that starts + * all application shutdown hooks and waits until they finish. */ private static void runHooks() { + synchronized (lock) { + /* Guard against the possibility of a daemon thread invoking exit + * after DestroyJavaVM initiates the shutdown sequence + */ + if (isShutdown) return; + } + for (int i=0; i < MAX_SYSTEM_HOOKS; i++) { try { Runnable hook; @@ -121,13 +128,20 @@ private static void runHooks() { hook = hooks[i]; } if (hook != null) hook.run(); - } catch(Throwable t) { + } catch (Throwable t) { if (t instanceof ThreadDeath) { ThreadDeath td = (ThreadDeath)t; throw td; } } } + + // set shutdown state + // Synchronization is for visibility; only one thread + // can ever get here. + synchronized (lock) { + isShutdown = true; + } } /* Notify the VM that it's time to halt. */ @@ -145,75 +159,23 @@ static void halt(int status) { static native void halt0(int status); - /* Wormhole for invoking java.lang.ref.Finalizer.runAllFinalizers */ - private static native void runAllFinalizers(); - - - /* The actual shutdown sequence is defined here. - * - * If it weren't for runFinalizersOnExit, this would be simple -- we'd just - * run the hooks and then halt. Instead we need to keep track of whether - * we're running hooks or finalizers. In the latter case a finalizer could - * invoke exit(1) to cause immediate termination, while in the former case - * any further invocations of exit(n), for any n, simply stall. Note that - * if on-exit finalizers are enabled they're run iff the shutdown is - * initiated by an exit(0); they're never run on exit(n) for n != 0 or in - * response to SIGINT, SIGTERM, etc. - */ - private static void sequence() { - synchronized (lock) { - /* Guard against the possibility of a daemon thread invoking exit - * after DestroyJavaVM initiates the shutdown sequence - */ - if (state != HOOKS) return; - } - runHooks(); - boolean rfoe; - synchronized (lock) { - state = FINALIZERS; - rfoe = runFinalizersOnExit; - } - if (rfoe) runAllFinalizers(); - } - - /* Invoked by Runtime.exit, which does all the security checks. * Also invoked by handlers for system-provided termination events, * which should pass a nonzero status code. */ static void exit(int status) { - boolean runMoreFinalizers = false; synchronized (lock) { - if (status != 0) runFinalizersOnExit = false; - switch (state) { - case RUNNING: /* Initiate shutdown */ - state = HOOKS; - break; - case HOOKS: /* Stall and halt */ - break; - case FINALIZERS: - if (status != 0) { - /* Halt immediately on nonzero status */ - halt(status); - } else { - /* Compatibility with old behavior: - * Run more finalizers and then halt - */ - runMoreFinalizers = runFinalizersOnExit; - } - break; + if (status != 0 && isShutdown) { + /* Halt immediately on nonzero status */ + halt(status); } } - if (runMoreFinalizers) { - runAllFinalizers(); - halt(status); - } synchronized (Shutdown.class) { /* Synchronize on the class object, causing any other thread * that attempts to initiate shutdown to stall indefinitely */ beforeHalt(); - sequence(); + runHooks(); halt(status); } } @@ -224,18 +186,8 @@ static void exit(int status) { * actually halt the VM. */ static void shutdown() { - synchronized (lock) { - switch (state) { - case RUNNING: /* Initiate shutdown */ - state = HOOKS; - break; - case HOOKS: /* Stall and then return */ - case FINALIZERS: - break; - } - } synchronized (Shutdown.class) { - sequence(); + runHooks(); } } diff --git a/jdk/src/share/classes/java/lang/System.java b/jdk/src/share/classes/java/lang/System.java index 0a02f190fa1..5b2b3205578 100644 --- a/jdk/src/share/classes/java/lang/System.java +++ b/jdk/src/share/classes/java/lang/System.java @@ -1018,29 +1018,27 @@ public static void runFinalization() { } /** - * Enable or disable finalization on exit; doing so specifies that the - * finalizers of all objects that have finalizers that have not yet been - * automatically invoked are to be run before the Java runtime exits. - * By default, finalization on exit is disabled. - * - *

If there is a security manager, - * its checkExit method is first called - * with 0 as its argument to ensure the exit is allowed. - * This could result in a SecurityException. - * - * @deprecated This method is inherently unsafe. It may result in - * finalizers being called on live objects while other threads are - * concurrently manipulating those objects, resulting in erratic - * behavior or deadlock. - * @param value indicating enabling or disabling of finalization - * @throws SecurityException - * if a security manager exists and its checkExit - * method doesn't allow the exit. + * Throws {@code UnsupportedOperationException}. * - * @see java.lang.Runtime#exit(int) - * @see java.lang.Runtime#gc() - * @see java.lang.SecurityManager#checkExit(int) - * @since JDK1.1 + *

The call {@code System.runFinalizersOnExit()} is effectively + * equivalent to the call: + *

+     * Runtime.runFinalizersOnExit()
+     * 
+ * + * @param value ignored + * + * @deprecated This method was originally designed to enable or disable + * running finalizers on exit. Running finalizers on exit was disabled + * by default. If enabled, then the finalizers of all objects whose + * finalizers had not yet been automatically invoked were to be run before + * the Java runtime exits. That behavior is inherently unsafe. It may + * result in finalizers being called on live objects while other threads + * are concurrently manipulating those objects, resulting in erratic + * behavior or deadlock. + * + * @see java.lang.Runtime#runFinalizersOnExit(boolean) + * @since JDK1.1 */ @Deprecated public static void runFinalizersOnExit(boolean value) { diff --git a/jdk/src/share/classes/java/lang/ref/Finalizer.java b/jdk/src/share/classes/java/lang/ref/Finalizer.java index 5cc0ac76ae6..87d95fba96b 100644 --- a/jdk/src/share/classes/java/lang/ref/Finalizer.java +++ b/jdk/src/share/classes/java/lang/ref/Finalizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -112,15 +112,12 @@ private void runFinalizer(JavaLangAccess jla) { /* Create a privileged secondary finalizer thread in the system thread group for the given Runnable, and wait for it to complete. - This method is used by both runFinalization and runFinalizersOnExit. - The former method invokes all pending finalizers, while the latter - invokes all uninvoked finalizers if on-exit finalization has been - enabled. + This method is used by runFinalization. - These two methods could have been implemented by offloading their work - to the regular finalizer thread and waiting for that thread to finish. + It could have been implemented by offloading the work to the + regular finalizer thread and waiting for that thread to finish. The advantage of creating a fresh thread, however, is that it insulates - invokers of these methods from a stalled or deadlocked finalizer thread. + invokers of that method from a stalled or deadlocked finalizer thread. */ private static void forkSecondaryFinalizer(final Runnable proc) { AccessController.doPrivileged( @@ -164,31 +161,6 @@ public void run() { }); } - /* Invoked by java.lang.Shutdown */ - static void runAllFinalizers() { - if (!VM.isBooted()) { - return; - } - - forkSecondaryFinalizer(new Runnable() { - private volatile boolean running; - public void run() { - // in case of recursive call to run() - if (running) - return; - final JavaLangAccess jla = SharedSecrets.getJavaLangAccess(); - running = true; - for (;;) { - Finalizer f; - synchronized (lock) { - f = unfinalized; - if (f == null) break; - unfinalized = f.next; - } - f.runFinalizer(jla); - }}}); - } - private static class FinalizerThread extends Thread { private volatile boolean running; FinalizerThread(ThreadGroup g) { diff --git a/jdk/src/share/javavm/export/jvm.h b/jdk/src/share/javavm/export/jvm.h index 6e64cb0d968..0717452c95a 100644 --- a/jdk/src/share/javavm/export/jvm.h +++ b/jdk/src/share/javavm/export/jvm.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2022, 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 @@ -128,9 +128,6 @@ JVM_CopySwapMemory(JNIEnv *env, jobject srcObj, jlong srcOffset, /* * java.lang.Runtime */ -JNIEXPORT void JNICALL -JVM_Exit(jint code); - JNIEXPORT void JNICALL JVM_BeforeHalt(); diff --git a/jdk/src/share/native/java/lang/Shutdown.c b/jdk/src/share/native/java/lang/Shutdown.c index b8f1bd2eaef..134ebbdea9c 100644 --- a/jdk/src/share/native/java/lang/Shutdown.c +++ b/jdk/src/share/native/java/lang/Shutdown.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2022, 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 @@ -40,17 +40,3 @@ Java_java_lang_Shutdown_halt0(JNIEnv *env, jclass ignored, jint code) { JVM_Halt(code); } - - -JNIEXPORT void JNICALL -Java_java_lang_Shutdown_runAllFinalizers(JNIEnv *env, jclass ignored) -{ - jclass cl; - jmethodID mid; - - if ((cl = (*env)->FindClass(env, "java/lang/ref/Finalizer")) - && (mid = (*env)->GetStaticMethodID(env, cl, - "runAllFinalizers", "()V"))) { - (*env)->CallStaticVoidMethod(env, cl, mid); - } -} diff --git a/jdk/test/java/lang/System/finalization/FinExit.java b/jdk/test/java/lang/System/finalization/FinExit.java deleted file mode 100644 index 504035bff3a..00000000000 --- a/jdk/test/java/lang/System/finalization/FinExit.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 1998, 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 4116016 - @summary Ensure that finalizers are not invoked more than once when on-exit - finalization is enabled and a finalizer invokes System.exit after - System.exit has already been invoked - @build FinExit - @run shell FinExit.sh - */ - - -public class FinExit { - - boolean finalized = false; - - public void finalize() { - if (finalized) { - System.out.println("2"); - } else { - finalized = true; - System.out.println("1"); - System.exit(0); - } - } - - public static void main(String[] args) throws Exception { - System.runFinalizersOnExit(true); - Object o = new FinExit(); - System.exit(0); - } - -} diff --git a/jdk/test/java/lang/System/finalization/FinExit.sh b/jdk/test/java/lang/System/finalization/FinExit.sh deleted file mode 100644 index e5eec432094..00000000000 --- a/jdk/test/java/lang/System/finalization/FinExit.sh +++ /dev/null @@ -1,36 +0,0 @@ -#! /bin/sh - -# -# Copyright (c) 1998, 2010, 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. -# - -# - -# We only want the first character, Windows might add CRLF -x=`$TESTJAVA/bin/java ${TESTVMOPTS} -cp "$TESTCLASSES" FinExit | cut -c1` -echo $x -if [ "x$x" != "x1" ]; then - echo On-exit finalizer invoked twice - exit 1 -else - exit 0 -fi diff --git a/jdk/test/java/lang/System/ExitFinalizersAndJIT.java b/jdk/test/java/lang/System/finalization/RunFinalizersOnExit.java similarity index 57% rename from jdk/test/java/lang/System/ExitFinalizersAndJIT.java rename to jdk/test/java/lang/System/finalization/RunFinalizersOnExit.java index 2bea5a63607..0b6408f7602 100644 --- a/jdk/test/java/lang/System/ExitFinalizersAndJIT.java +++ b/jdk/test/java/lang/System/finalization/RunFinalizersOnExit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -21,16 +21,26 @@ * questions. */ -/* @test - @bug 4119554 - @summary runFinalizersOnExit(true) causes JIT to be unloaded and - crashes the VM. Interim fix for 1.2 beta4 -- don't unload - native libraries loaded by system classes. - @run main/othervm ExitFinalizersAndJIT -*/ +/* + * @test + * @bug 8287132 + * @summary Ensure that System.runFinalizersOnExit throws + * UnsupportedOperationException + */ +public class RunFinalizersOnExit { + public static void main(String[] args) { + try { + System.runFinalizersOnExit(true); + throw new Error("UnsupportedOperationException was not thrown"); + } + catch (UnsupportedOperationException expected) { + } -public class ExitFinalizersAndJIT { - public static void main(String[] args) throws Exception { - System.runFinalizersOnExit(true); + try { + System.runFinalizersOnExit(false); + throw new Error("UnsupportedOperationException was not thrown"); + } + catch (UnsupportedOperationException expected) { + } } }