diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 187c97a6ad3..3c293770003 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -316,7 +316,6 @@ module java.base { exports sun.reflect.misc to java.desktop, java.management, - java.rmi, java.sql.rowset; exports sun.security.internal.interfaces to jdk.crypto.cryptoki; @@ -329,7 +328,6 @@ module java.base { exports sun.security.pkcs to jdk.jartool; exports sun.security.provider to - java.rmi, java.security.jgss, jdk.crypto.cryptoki, jdk.security.auth; @@ -344,7 +342,6 @@ module java.base { jdk.jartool; exports sun.security.util to java.naming, - java.rmi, java.security.jgss, java.security.sasl, java.smartcardio, diff --git a/src/java.rmi/share/classes/sun/rmi/runtime/NewThreadAction.java b/src/java.rmi/share/classes/sun/rmi/runtime/NewThreadAction.java deleted file mode 100644 index f9be382d0fc..00000000000 --- a/src/java.rmi/share/classes/sun/rmi/runtime/NewThreadAction.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2000, 2024, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ - -package sun.rmi.runtime; - -/** - * A utility class for creating threads. The constructors take a - * variety of parameters to configure the thread. The run() method - * creates and sets up the thread and returns it, but does not - * start it. - * - * All constructors allow the choice of the Runnable for the new - * thread to execute, the name of the new thread (which will be - * prefixed with "RMI "), and whether or not it will be a daemon - * thread. - * - * The new thread may be created in the system thread group (the root - * of the thread group tree) or an internally created non-system - * thread group, as specified at construction of this class. - * - * The new thread will have the system class loader as its initial - * context class loader (that is, its context class loader will NOT be - * inherited from the current thread). - * - * @author Peter Jones - **/ -public final class NewThreadAction { - - /** cached reference to the system (root) thread group */ - static final ThreadGroup systemThreadGroup; - static { - ThreadGroup group = Thread.currentThread().getThreadGroup(); - ThreadGroup parent; - while ((parent = group.getParent()) != null) { - group = parent; - } - systemThreadGroup = group; - } - - - /** - * Special child of the system thread group for running tasks that - * may execute user code. The need for a separate thread group may - * be a vestige of it having had a different security policy from - * the system thread group, so this might no longer be necessary. - */ - static final ThreadGroup userThreadGroup = new ThreadGroup(systemThreadGroup, "RMI Runtime"); - - private final ThreadGroup group; - private final Runnable runnable; - private final String name; - private final boolean daemon; - - NewThreadAction(ThreadGroup group, Runnable runnable, - String name, boolean daemon) - { - this.group = group; - this.runnable = runnable; - this.name = name; - this.daemon = daemon; - } - - /** - * Creates an action that will create a new thread in the - * system thread group. - * - * @param runnable the Runnable for the new thread to execute - * - * @param name the name of the new thread - * - * @param daemon if true, new thread will be a daemon thread; - * if false, new thread will not be a daemon thread - */ - public NewThreadAction(Runnable runnable, String name, boolean daemon) { - this(systemThreadGroup, runnable, name, daemon); - } - - /** - * Creates an action that will create a new thread. - * - * @param runnable the Runnable for the new thread to execute - * - * @param name the name of the new thread - * - * @param daemon if true, new thread will be a daemon thread; - * if false, new thread will not be a daemon thread - * - * @param user if true, thread will be created in a non-system - * thread group; if false, thread will be created in the system - * thread group - */ - public NewThreadAction(Runnable runnable, String name, boolean daemon, - boolean user) - { - this(user ? userThreadGroup : systemThreadGroup, - runnable, name, daemon); - } - - public Thread run() { - Thread t = new Thread(group, runnable, "RMI " + name); - t.setContextClassLoader(ClassLoader.getSystemClassLoader()); - t.setDaemon(daemon); - return t; - } -} diff --git a/src/java.rmi/share/classes/sun/rmi/runtime/RuntimeUtil.java b/src/java.rmi/share/classes/sun/rmi/runtime/RuntimeUtil.java index 4be706e57bb..84bd3371408 100644 --- a/src/java.rmi/share/classes/sun/rmi/runtime/RuntimeUtil.java +++ b/src/java.rmi/share/classes/sun/rmi/runtime/RuntimeUtil.java @@ -36,10 +36,46 @@ import java.util.logging.Level; * There is a single instance of this class, which can be obtained * with a getInstance() call. * + * This class also contains a couple static methods for creating + * threads. The methods allow the choice of the Runnable for the + * new thread to execute, the name of the new thread (which will + * be prefixed with "RMI "), and whether or not it will be a daemon + * thread. + * + * The new thread may be created in the system thread group (the root + * of the thread group tree) or an internally created non-system + * thread group (the "user" thread group). + * + * The new thread will have the system class loader as its initial + * context class loader (that is, its context class loader will NOT be + * inherited from the current thread). + * * @author Peter Jones **/ public final class RuntimeUtil { + /** + * Cached reference to the system (root) thread group. + */ + private static final ThreadGroup systemThreadGroup; + static { + ThreadGroup group = Thread.currentThread().getThreadGroup(); + ThreadGroup parent; + while ((parent = group.getParent()) != null) { + group = parent; + } + systemThreadGroup = group; + } + + /** + * Special child of the system thread group for running tasks that + * may execute user code. The need for a separate thread group may + * be a vestige of it having had a different security policy from + * the system thread group, so this might no longer be necessary. + */ + private static final ThreadGroup userThreadGroup = + new ThreadGroup(systemThreadGroup, "RMI Runtime"); + /** runtime package log */ private static final Log runtimeLog = Log.getLog("sun.rmi.runtime", null, false); @@ -54,6 +90,14 @@ public final class RuntimeUtil { /** thread pool for scheduling delayed tasks */ private final ScheduledThreadPoolExecutor scheduler; + /** + * Creates the single instance of RuntimeUtil. Note that this is called + * from a static initializer, and it has a ThreadFactory that calls + * static methods on this class, possibly from other threads. This + * should be ok, as the ScheduledThreadPoolExecutor constructor + * returns immediately without blocking on the creation of threads + * by the factory. + */ private RuntimeUtil() { scheduler = new ScheduledThreadPoolExecutor( schedulerThreads, @@ -61,9 +105,10 @@ public final class RuntimeUtil { private final AtomicInteger count = new AtomicInteger(); public Thread newThread(Runnable runnable) { try { - return new NewThreadAction(runnable, + return newSystemThread( + runnable, "Scheduler(" + count.getAndIncrement() + ")", - true).run(); + true); } catch (Throwable t) { runtimeLog.log(Level.WARNING, "scheduler thread factory throws", t); @@ -93,4 +138,48 @@ public final class RuntimeUtil { public ScheduledThreadPoolExecutor getScheduler() { return scheduler; } + + // Thread creation methods. + + /** + * Internal method to create a new thread with the given settings. + * + * @param group the thread group, should be systemThreadGroup or userThreadGroup + * @param runnable the thread's task + * @param name the thread's name, which will be prefixed with "RMI " + * @param daemon whether the thread should be a daemon + * @return the newly created thread + */ + private static Thread newThread(ThreadGroup group, Runnable runnable, String name, boolean daemon) { + Thread t = new Thread(group, runnable, "RMI " + name); + t.setContextClassLoader(ClassLoader.getSystemClassLoader()); + t.setDaemon(daemon); + return t; + } + + /** + * Creates and returns, but does not start, a new thread with the given settings. + * The thread will be in the system ("root") thread group. + * + * @param runnable the thread's task + * @param name the thread's name, which will be prefixed with "RMI " + * @param daemon whether the thread should be a daemon + * @return the newly created thread + */ + public static Thread newSystemThread(Runnable runnable, String name, boolean daemon) { + return newThread(systemThreadGroup, runnable, name, daemon); + } + + /** + * Creates and returns, but does not start, a new thread with the given settings. + * The thread will be in the RMI user thread group. + * + * @param runnable the thread's task + * @param name the thread's name, which will be prefixed with "RMI " + * @param daemon whether the thread should be a daemon + * @return the newly created thread + */ + public static Thread newUserThread(Runnable runnable, String name, boolean daemon) { + return newThread(userThreadGroup, runnable, name, daemon); + } } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java b/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java index 6bf0248f529..2fe59ccad66 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java @@ -41,7 +41,7 @@ import java.rmi.dgc.VMID; import java.rmi.server.ObjID; import sun.rmi.runtime.Log; -import sun.rmi.runtime.NewThreadAction; +import sun.rmi.runtime.RuntimeUtil; import sun.rmi.server.UnicastRef; import sun.rmi.server.Util; @@ -237,8 +237,7 @@ final class DGCClient { throw new Error("internal error creating DGC stub"); } renewCleanThread = - new NewThreadAction(new RenewCleanThread(), - "RenewClean-" + endpoint, true).run(); + RuntimeUtil.newSystemThread(new RenewCleanThread(), "RenewClean-" + endpoint, true); renewCleanThread.start(); } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java b/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java index dd1fcaddeab..ab79714f4a2 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java @@ -33,7 +33,7 @@ import java.rmi.server.ObjID; import java.util.HashMap; import java.util.Map; import sun.rmi.runtime.Log; -import sun.rmi.runtime.NewThreadAction; +import sun.rmi.runtime.RuntimeUtil; /** * Object table shared by all implementors of the Transport interface. @@ -271,7 +271,7 @@ public final class ObjectTable { keepAliveCount++; if (reaper == null) { - reaper = new NewThreadAction(new Reaper(), "Reaper", false).run(); + reaper = RuntimeUtil.newSystemThread(new Reaper(), "Reaper", false); reaper.start(); } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/Target.java b/src/java.rmi/share/classes/sun/rmi/transport/Target.java index 3ea404698f2..0729d40b129 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/Target.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/Target.java @@ -31,7 +31,7 @@ import java.rmi.server.ObjID; import java.rmi.server.Unreferenced; import java.util.*; import sun.rmi.runtime.Log; -import sun.rmi.runtime.NewThreadAction; +import sun.rmi.runtime.RuntimeUtil; import sun.rmi.server.Dispatcher; /** @@ -312,10 +312,10 @@ public final class Target { */ Remote obj = getImpl(); if (obj instanceof Unreferenced unrefObj) { - new NewThreadAction(() -> { + RuntimeUtil.newUserThread(() -> { Thread.currentThread().setContextClassLoader(ccl); unrefObj.unreferenced(); - }, "Unreferenced-" + nextThreadNum++, false, true).run().start(); + }, "Unreferenced-" + nextThreadNum++, false).start(); // REMIND: access to nextThreadNum not synchronized; you care? } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java index 91ef41d3e49..9099a167d5d 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java @@ -37,7 +37,6 @@ import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import sun.rmi.runtime.Log; -import sun.rmi.runtime.NewThreadAction; import sun.rmi.runtime.RuntimeUtil; import sun.rmi.transport.Channel; import sun.rmi.transport.Connection; @@ -401,9 +400,9 @@ class ConnectionAcceptor implements Runnable { * Start a new thread to accept connections. */ public void startNewAcceptor() { - Thread t = new NewThreadAction(ConnectionAcceptor.this, - "TCPChannel Accept-" + ++ threadNum, - true).run(); + Thread t = RuntimeUtil.newSystemThread(ConnectionAcceptor.this, + "TCPChannel Accept-" + ++ threadNum, + true); t.start(); } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java index 4eb1a35a95e..b0bfa03e130 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java @@ -45,7 +45,7 @@ import java.util.LinkedList; import java.util.Map; import java.util.Set; import sun.rmi.runtime.Log; -import sun.rmi.runtime.NewThreadAction; +import sun.rmi.runtime.RuntimeUtil; import sun.rmi.transport.Channel; import sun.rmi.transport.Endpoint; import sun.rmi.transport.Target; @@ -752,7 +752,7 @@ public class TCPEndpoint implements Endpoint { private void getFQDN() { /* FQDN finder will run in RMI threadgroup. */ - Thread t = new NewThreadAction(FQDN.this, "FQDN Finder", true).run(); + Thread t = RuntimeUtil.newSystemThread(FQDN.this, "FQDN Finder", true); t.start(); } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java index 9695fcac274..1a4a00f072d 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java @@ -60,7 +60,7 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import sun.rmi.runtime.Log; -import sun.rmi.runtime.NewThreadAction; +import sun.rmi.runtime.RuntimeUtil; import sun.rmi.transport.Connection; import sun.rmi.transport.DGCAckHandler; import sun.rmi.transport.Endpoint; @@ -98,8 +98,7 @@ public class TCPTransport extends Transport { new SynchronousQueue(), new ThreadFactory() { public Thread newThread(Runnable runnable) { - return new NewThreadAction( - runnable, "TCP Connection(idle)", true, true).run(); + return RuntimeUtil.newUserThread(runnable, "TCP Connection(idle)", true); } }); @@ -303,8 +302,8 @@ public class TCPTransport extends Transport { * "port in use" will cause export to hang if an * RMIFailureHandler is not installed. */ - Thread t = new NewThreadAction(new AcceptLoop(server), - "TCP Accept-" + port, true).run(); + Thread t = RuntimeUtil.newSystemThread( + new AcceptLoop(server), "TCP Accept-" + port, true); t.start(); } catch (java.net.BindException e) { throw new ExportException("Port already in use: " + port, e);