SubjectInheritingThread (Apache Hadoop Common 3.5.0 API)
Description: declaration: package: org.apache.hadoop.util.concurrent, class: SubjectInheritingThread

Package org.apache.hadoop.util.concurrent

# Class SubjectInheritingThread

java.lang.Object
java.lang.Thread
org.apache.hadoop.util.concurrent.SubjectInheritingThread

All Implemented Interfaces:
  `Runnable`

Direct Known Subclasses:
  `DelegationTokenRenewer`, `GcTimeMonitor`

public class SubjectInheritingThread extends Thread
Helper class to restore Subject propagation behavior of threads after the JEP411/JEP486 changes.

Java propagates the current Subject to any new Threads in all version up to Java 21. In Java 22-23 the Subject is only propagated if the SecurityManager is enabled, while in Java 24+ it is never propagated.

Hadoop security heavily relies on the original behavior, as Subject is at the core of JAAS. This class wraps thread. It overrides start() and saves the Subject of the current thread, and wraps the payload in a Subject.doAs()/callAs() call to restore it in the newly created Thread.

When specifying a Runnable, this class is used in exactly the same way as Thread.

`run()` cannot be directly overridden, as that would also override the subject restoration logic. SubjectInheritingThread provides a `work()` method instead, which is wrapped and invoked by its own final `run()` method.

- ## Nested Class Summary

  ## Nested classes/interfaces inherited from class java.lang.Thread

  `Thread.State, Thread.UncaughtExceptionHandler`

- ## Field Summary

  ### Fields inherited from class java.lang.Thread

  `MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `SubjectInheritingThread()`
  Behaves similarly to `Thread()` constructor, but the code to run must be specified by overriding the `work()` instead of the {link #run()} method.
  `SubjectInheritingThread(Runnable target)`
  Behaves similarly to `Thread(Runnable)` constructor.
  `SubjectInheritingThread(Runnable target, String name)`
  Behaves similarly to `Thread(Runnable, String)` constructor.
  `SubjectInheritingThread(String name)`
  Behaves similarly to `Thread(String)` constructor.
  `SubjectInheritingThread(ThreadGroup group, Runnable target)`
  Behaves similarly to `Thread(ThreadGroup, Runnable)` constructor.
  `SubjectInheritingThread(ThreadGroup group, Runnable target, String name)`
  Behaves similarly to `Thread(ThreadGroup, Runnable, String)` constructor.
  `SubjectInheritingThread(ThreadGroup group, String name)`
  Behaves similarly to `Thread(ThreadGroup, String)` constructor.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `final void`
  `run()`
  This cannot be overridden in this class.
  `final void`
  `start()`
  Behaves similarly to pre-Java 22 `Thread.start()`.
  `void`
  `work()`
  This is the equivalent of `Thread.run()`.

  ### Methods inherited from class java.lang.Thread

  `activeCount, checkAccess, clone, countStackFrames, currentThread, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, onSpinWait, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, stop, suspend, toString, yield`

  ### Methods inherited from class java.lang.Object

  `equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Constructor Details

  - ### SubjectInheritingThread

    public SubjectInheritingThread()
    Behaves similarly to `Thread()` constructor, but the code to run must be specified by overriding the `work()` instead of the {link #run()} method.

  - ### SubjectInheritingThread

    public SubjectInheritingThread(Runnable target)
    Behaves similarly to `Thread(Runnable)` constructor.
    Parameters:
      `target` - the object whose `run` method is invoked when this thread is started. If `null`, this classes `run` method does nothing.

  - ### SubjectInheritingThread

    public SubjectInheritingThread(ThreadGroup group, Runnable target)
    Behaves similarly to `Thread(ThreadGroup, Runnable)` constructor.
    Parameters:
      `group` - the thread group. If `null` and there is a security manager, the group is determined by SecurityManager.getThreadGroup(). If there is not a security manager or `SecurityManager.getThreadGroup()` returns `null`, the group is set to the current thread's thread group.
      `target` - the object whose `run` method is invoked when this thread is started. If `null`, this thread's run method is invoked.
    Throws:
      `SecurityException` - if the current thread cannot create a thread in the specified thread group

  - ### SubjectInheritingThread

    public SubjectInheritingThread(Runnable target, String name)
    Behaves similarly to `Thread(Runnable, String)` constructor.
    Parameters:
      `target` - the object whose `run` method is invoked when this thread is started. If `null`, this thread's run method is invoked.
      `name` - the name of the new thread
    Throws:
      `SecurityException` - if the current thread cannot create a thread in the specified thread group

  - ### SubjectInheritingThread

    public SubjectInheritingThread(String name)
    Behaves similarly to `Thread(String)` constructor.
    Parameters:
      `name` - the name of the new thread

  - ### SubjectInheritingThread

    public SubjectInheritingThread(ThreadGroup group, String name)
    Behaves similarly to `Thread(ThreadGroup, String)` constructor.
    Parameters:
      `group` - the thread group. If `null` and there is a security manager, the group is determined by SecurityManager.getThreadGroup(). If there is not a security manager or `SecurityManager.getThreadGroup()` returns `null`, the group is set to the current thread's thread group.
      `name` - the name of the new thread

  - ### SubjectInheritingThread

    public SubjectInheritingThread(ThreadGroup group, Runnable target, String name)
    Behaves similarly to `Thread(ThreadGroup, Runnable, String)` constructor.
    Parameters:
      `group` - the thread group. If `null` and there is a security manager, the group is determined by SecurityManager.getThreadGroup(). If there is not a security manager or `SecurityManager.getThreadGroup()` returns `null`, the group is set to the current thread's thread group.
      `target` - the object whose `run` method is invoked when this thread is started. If `null`, this thread's run method is invoked.
      `name` - the name of the new thread
    Throws:
      `SecurityException` - if the current thread cannot create a thread in the specified thread group or cannot override the context class loader methods.

- ## Method Details

  - ### start

    public final void start()
    Behaves similarly to pre-Java 22 `Thread.start()`. It saves the current Subject before starting the new thread, which is then used as the Subject for the Runnable or the overridden work() method.
    Overrides:
      `start` in class `Thread`

  - ### work

    public void work()
    This is the equivalent of `Thread.run()`. Override this instead of `run()` Subject will be propagated like in pre-Java 22 Thread.

  - ### run

    public final void run()
    This cannot be overridden in this class. Override the `work()` method instead which behaves like pre-Java 22 `Thread.run()`
    Specified by:
      `run` in interface `Runnable`
    Overrides:
      `run` in class `Thread`