-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Implement fallback if class java.security.AccessController
does not exist
#2686
Comments
It's going to be difficult to be sure about workarounds for a missing I'm a bit puzzled about the code in question. Aren't enum constants public? So then we should be able just to use
I am inclined to think that that is going to affect hardly anybody. I'm also not sure we need to be able to call |
I understood JEP 411 as if the idea was to remove
Coincidentally you were the one who suggested using
Unfortunately not when ProGuard or R8 are involved. If I remember correctly, Another option would also be to simply remove the |
I didn't express my point about the JDK very well. What I meant was that if we add a workaround that is supposed to function when there is no Thanks for reminding me of the previous discussion, where indeed I noted that enum constants are public but enums themselves aren't necessarily. Still, the whole thing feels very complicated and I'm not sure it is worthwhile now. I would be somewhat inclined to rip it all out and see if anybody complains. If they do, we can put it back again in another release and perhaps also look at handling a missing |
It seems usage of (Though I am not completely sure if this is a proper @Test
public void testJdkEnum() {
assertThat(gson.toJson(Thread.State.NEW)).isEqualTo("\"NEW\"");
assertThat(gson.fromJson("\"NEW\"", Thread.State.class)).isEqualTo(Thread.State.NEW);
}
@SuppressWarnings("removal") // java.lang.SecurityManager deprecation in Java 17
@Test
public void testJdkEnum_SecurityManager() {
// Skip for newer Java versions where `System.setSecurityManager` is unsupported
assumeTrue(Runtime.version().feature() <= 17);
var gsonProtectionDomain = Gson.class.getProtectionDomain();
var testProtectionDomain = getClass().getProtectionDomain();
assertWithMessage(
"Gson code and test code should have different ProtectionDomain; otherwise test might"
+ " not work properly")
.that(gsonProtectionDomain)
.isNotEqualTo(testProtectionDomain);
Policy originalPolicy = Policy.getPolicy();
SecurityManager originalSecurityManager = System.getSecurityManager();
try {
Policy.setPolicy(
new Policy() {
@Override
public boolean implies(ProtectionDomain domain, Permission permission) {
// Allow removing the SecurityManager again
if (permission instanceof RuntimePermission
&& permission.getName().equals("setSecurityManager")) {
return true;
}
if (domain.equals(gsonProtectionDomain)) {
return true;
}
return originalPolicy.implies(domain, permission);
}
});
System.setSecurityManager(new SecurityManager());
assertThat(gson.toJson(Thread.State.NEW)).isEqualTo("\"NEW\"");
assertThat(gson.fromJson("\"NEW\"", Thread.State.class)).isEqualTo(Thread.State.NEW);
} finally {
System.setSecurityManager(originalSecurityManager);
Policy.setPolicy(originalPolicy);
}
} However, it seems there are a few other places which fail when a custom
So unless my test setup is wrong or flawed this suggests that usage with a |
Yes, the more I think about it, the more I agree with my earlier comment about just ripping out the |
Problem solved by the feature
JEP 411 marked the
SecurityManager
and related classes such asjava.security.AccessController
as 'deprecated for removal' since JDK 17.Currently the Gson code uses
AccessController
:gson/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java
Line 969 in 91d22b3
This could become a problem when a future JDK version actually removes the
SecurityManager
and related classes, and Gson users cannot upgrade then.Side note: Gson's unit test
ReflectionAccessTest.testRestrictiveSecurityManager()
also uses the deprecatedSecurityManager
class, but maybe we should keep this for now to make sure Gson's behavior for JDK versions withSecurityManager
is correct.Once we want to build with JDK versions without
SecurityManager
we can investigate solutions for this, e.g. moving the test into a separate test class which is excluded when building with newer JDK versions.Feature description
We should already consider solutions for the case that
AccessController
does not exist, to avoid any issues if users want to upgrade to future JDK versions.One solution might be to wrap the usage of
AccessController
inside a try-catch which catchesNoClassDefFoundError
and in that case falls back to executing the code to access the fields outside the scope ofAccessController#doPrivileged
. (To be verified that this actually works as desired.)Another alternative might be to refactor the code to first check with
Class#forName
or similar ifAccessController
exists (and remember the result).It might also be good to add a unit test which verifies that the
AccessController#doPrivileged
usage actually has the desired effect. It seems that is currently not covered by any test (?).Then we could be more confident that whatever change we make does not break the code for users who have a restrictive
SecurityManager
on an older JDK.The text was updated successfully, but these errors were encountered: