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) { *
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: + *
+ * + * @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) { + } } }+ * Runtime.runFinalizersOnExit() + *