Summary
-------
Deprecate the Security Manager for removal.
Problem
-------
The Security Manager dates from Java 1.0. It has not been the primary means of securing client-side Java code for many years, and it has rarely been used to secure server-side code. To move Java forward, we intend to deprecate the Security Manager for removal in concert with the legacy Applet API ([JEP 398][jep398]).
See [JEP 411][jep411] for more rationale.
[jep398]: https://openjdk.java.net/jeps/398
[jep411]: https://openjdk.java.net/jeps/411
Solution
--------
The solution involves three main changes:
**1. Deprecate, for removal, most Security Manager related classes and methods.**
The Security Manager consists of `java.lang.SecurityManager` and a number of closely related APIs in java.lang and java.security. We will terminally deprecate the following eight classes and two methods by annotating them with @Deprecated(forRemoval=true):
- `java.lang.SecurityManager` ��� The primary API for the Security Manager.
- `java.lang.System::{setSecurityManager, getSecurityManager}` ��� Methods for setting and getting the Security Manager.
- `java.security.{Policy, PolicySpi, Policy.Parameters}` ��� The primary APIs for policy, which are used to determine if code running under the Security Manager has been granted permission to perform specific privileged operations.
- `java.security.{AccessController, AccessControlContext, AccessControlException, DomainCombiner}` ��� The primary APIs for the access controller, which is the default implementation to which the Security Manager delegates permission checks. These APIs do not have value without the Security Manager, since certain operations will not work without both a policy implementation and access-control context support in the VM.
We will also terminally deprecate the following two classes and eight methods which depend strongly on the Security Manager:
- `java.lang.Thread::checkAccess`, `java.lang.ThreadGroup::checkAccess`, and `java.util.logging.LogManager::checkAccess` ��� These three methods are anomalous because they allow ordinary Java code to check whether it would be trusted to perform certain operations without actually performing them. They serve no purpose without the Security Manager.
- `java.util.concurrent.Executors::{privilegedCallable, privilegedCallableUsingCurrentClassLoader, privilegedThreadFactory}` ��� These utility methods are only useful when the Security Manager is enabled.
- `java.rmi.RMISecurityManager` ��� RMI's Security Manager class. This class is obsolete and was deprecated in Java 8.
- `javax.security.auth.SubjectDomainCombiner` and `javax.security.auth.Subject::{doAsPrivileged, getSubject}` ��� APIs for user-based authorization that are dependent on Security Manager APIs such as `AccessControlContext` and `DomainCombiner`.
See the attached `specdiff.03.zip` for details.
**2. Issue a warning at startup or run time if a security manager is enabled on the command-line or installed dynamically.**
If the Java runtime is started with `java -Djava.security.manager` or `java -Djava.security.manager=...` (where `...` is `""` or `default` or the class name of a custom Security Manager implementation), then a warning message is issued at startup.
This warning will explain that the Security Manager is deprecated and will be removed in a future release. This warning, unlike compile-time deprecation warnings, cannot be suppressed.
If the Java runtime is started without setting the system property `java.security.manager`, or started with `java -Djava.security.manager=allow`, then no warning message is issued at startup. However, if Java code installs a Security Manager dynamically by calling the deprecated method `System::setSecurityManager`, then a warning message is issued during run time.
This warning will explain that `System::setSecurityManager` is deprecated and will be removed in a future release. This warning, unlike compile-time deprecation warnings, cannot be suppressed.
If the Java runtime is started with `java -Djava.security.manager=disallow`, then no warning message is issued at startup. However, the deprecated method `System::setSecurityManager` will throw an `UnsupportedOperationException`. This behavior is unchanged from Java 16.
Specification
-------------
See the attachments `specdiff.03.zip` and `webrev.03.zip` for details.