-
Notifications
You must be signed in to change notification settings - Fork 8.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HADOOP-19212. Avoid Subject.getSubject method on newer JVMs #7081
base: trunk
Are you sure you want to change the base?
Conversation
In Java 23, Subject.getSubject requires setting the system property java.security.manager to allow, else it will throw an exception. More detail is available in the release notes: https://jdk.java.net/23/release-notes This is in support of the eventual removal of the security manager, at which point, Subject.getSubject will be removed. Since this project supports older Java releases, and the API which one must migrate to was only introduced in Java 18, I hid the implementations behind a runtime version check. I verified against several local Java versions that the correct classes are loaded (and more importantly, that the incorrect classes are _not_ loaded). The outright removal of the security manager, and by extension the Subject.getSubject method would be a particularly large problem if we do not address this, which was my motivation here. Some manual testing on Java 11, 17, and 23: ``` » java --version openjdk 11.0.23 2024-04-16 LTS » java -cp hadoop-auth-3.5.0-SNAPSHOT.jar org.apache.hadoop.util.subject.SubjectAdapter Current subject is null » java --version openjdk 17.0.5 2022-10-18 LTS » java -cp hadoop-auth-3.5.0-SNAPSHOT.jar org.apache.hadoop.util.subject.SubjectAdapter Current subject is null » java --version openjdk 23 2024-09-17 » java -cp hadoop-auth-3.5.0-SNAPSHOT.jar org.apache.hadoop.util.subject.SubjectAdapter Current subject is null ``` As desired, the class containing the old implementation does not get loaded on a new JVM: ``` » java --version openjdk 23 2024-09-17 » java -verbose:class -cp hadoop-auth-3.5.0-SNAPSHOT.jar org.apache.hadoop.util.subject.SubjectAdapter | \grep -i subject | grep "class,load" | awk '{print $2}' org.apache.hadoop.util.subject.SubjectAdapter org.apache.hadoop.util.subject.HiddenGetSubject javax.security.auth.Subject org.apache.hadoop.util.subject.GetSubjectNg ``` And the inverse is true for an older JVM: ``` » java --version openjdk 17.0.5 2022-10-18 LTS » java -verbose:class -cp hadoop-auth-3.5.0-SNAPSHOT.jar org.apache.hadoop.util.subject.SubjectAdapter | \grep -i subject | grep "class,load" | awk '{print $2}' org.apache.hadoop.util.subject.SubjectAdapter org.apache.hadoop.util.subject.HiddenGetSubject javax.security.auth.Subject org.apache.hadoop.util.subject.ClassicGetSubject javax.security.auth.Subject$1 ```
🎊 +1 overall
This message was automatically generated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense to me. There's a checkstyle warning but glad it's not a big change.
Are you finding other issues with JDK23? I know it's just come out this month.
I am happy to report no other issues. This Subject usage in hadoop-common impacts a great many projects, so |
Ok sounds like we should get it backported to 3.4.x and 3.3.x too. |
@steveloughran PR for HADOOP-19212. I updated the title to reflect the duplicate change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is great! we'd been warned about this but nobody had written the code.
I've made some comments. Can you also change the title to that of the previous JIRA on this. Thanks
|
||
GetSubjectNg() { | ||
try { | ||
currentMethod = Subject.class.getMethod("current"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use DynMethods
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class, and all classes added in this PR, are in the hadoop-auth module because Subject.getSubject is used in both hadoop-auth (KerberosAuthenticator) and hadoop-common (UserGroupInformation). hadoop-common depends on hadoop-auth, so that seemed like a reasonable fit.
DynMethods, however, resides in hadoop-common, and thus it cannot be used in hadoop-auth.
How would you like me to proceed?
static { | ||
int version = 0; | ||
try { | ||
version = Integer.parseInt(System.getProperty("java.specification.version")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use Shell.isJavaVersionAtLeast(18)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My comment about dependencies applies to Shell as well. Let me know how you'd like to proceed with this one as well.
...-common-project/hadoop-auth/src/main/java/org/apache/hadoop/util/subject/SubjectAdapter.java
Outdated
Show resolved
Hide resolved
...-common-project/hadoop-auth/src/main/java/org/apache/hadoop/util/subject/SubjectAdapter.java
Outdated
Show resolved
Hide resolved
...op-common-project/hadoop-auth/src/main/java/org/apache/hadoop/util/subject/GetSubjectNg.java
Outdated
Show resolved
Hide resolved
@steveloughran thank you for the review. I have pushed a second commit that addresses feedback marked with 👍. The title of this PR was updated to include "HADOOP-19212." as a prefix. I am happy to rebase/squash once review is complete, if squashing is necessary. Due to dependencies, I cannot use |
...ommon-project/hadoop-auth/src/main/java/org/apache/hadoop/util/subject/HiddenGetSubject.java
Outdated
Show resolved
Hide resolved
🎊 +1 overall
This message was automatically generated. |
🎊 +1 overall
This message was automatically generated. |
...-common-project/hadoop-auth/src/main/java/org/apache/hadoop/util/subject/SubjectAdapter.java
Outdated
Show resolved
Hide resolved
...mon-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm except for 2 minor issues.
JEP 486: Permanently Disable the Security Manager is on the JDK's technical roadmap. As part of the changes (PR in review) will be for Subject.current to throw unconditionally, meaning the workaround to allow a SecurityManager will no longer work. So the timing of the PR here is good. |
💔 -1 overall
This message was automatically generated. |
I am not sure I have the permissions to retrigger the failing checks. Ultimate failure was on the remote side:
This java code compiles just fine:
|
// how getSubject operates depends on the JVM calling it. | ||
// asserting that it does not throw is a valid test, especially on Java 18 and above | ||
// prior to Java 18, this method is just a simple wrapper | ||
assertDoesNotThrow(() -> SubjectAdapter.getSubject()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use our LambdaTestUtils.intercept() here as it fails better, can validates the type and message
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment in #7081 (comment) applies here as well.
/** | ||
* Indirectly calls Subject.current(), which exists in Java 18 and above only | ||
*/ | ||
class SubjectAdapterJava18AndAbove implements HiddenSubjectAdapter { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use our new DynMethods classes, (which we copied from parquet and which is also found in iceberg). It fails better and as it is so common it's good to get familiar with it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@steveloughran my comment from here still applies. #7081 (comment)
In Java 23, Subject.getSubject requires setting the system property java.security.manager to allow, else it will throw an exception. More detail is available in the release notes: https://jdk.java.net/23/release-notes
This is in support of the eventual removal of the security manager, at which point, Subject.getSubject will be removed. Since this project supports older Java releases, and the API which one must migrate to was only introduced in Java 18, I hid the implementations behind a runtime version check. I verified against several local Java versions that the correct classes are loaded (and more importantly, that the incorrect classes are not loaded). The outright removal of the security manager, and by extension the Subject.getSubject method would be a particularly large problem if we do not address this, which was my motivation here.
Some manual testing on Java 11, 17, and 23:
As desired, the class containing the old implementation does not get loaded on a new JVM:
And the inverse is true for an older JVM:
Description of PR
How was this patch tested?
For code changes:
LICENSE
,LICENSE-binary
,NOTICE-binary
files?