CleanerJava9 should be able to do its job even with a SecurityManager installed. (#8204)
Motivation: CleanerJava9 currently fails whever a SecurityManager is installed. We should make use of AccessController.doPrivileged(...) so the user can give it the correct rights. Modifications: Use doPrivileged(...) when needed. Result: Fixes https://github.com/netty/netty/issues/8201.
This commit is contained in:
parent
338ef96931
commit
8679c5ef43
@ -21,6 +21,8 @@ import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* Provide a way to clean a ByteBuffer on Java9+.
|
||||
@ -34,20 +36,26 @@ final class CleanerJava9 implements Cleaner {
|
||||
final Method method;
|
||||
final Throwable error;
|
||||
if (PlatformDependent0.hasUnsafe()) {
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(1);
|
||||
Object maybeInvokeMethod;
|
||||
try {
|
||||
// See https://bugs.openjdk.java.net/browse/JDK-8171377
|
||||
Method m = PlatformDependent0.UNSAFE.getClass().getDeclaredMethod("invokeCleaner", ByteBuffer.class);
|
||||
m.invoke(PlatformDependent0.UNSAFE, buffer);
|
||||
maybeInvokeMethod = m;
|
||||
} catch (NoSuchMethodException e) {
|
||||
maybeInvokeMethod = e;
|
||||
} catch (InvocationTargetException e) {
|
||||
maybeInvokeMethod = e;
|
||||
} catch (IllegalAccessException e) {
|
||||
maybeInvokeMethod = e;
|
||||
}
|
||||
final ByteBuffer buffer = ByteBuffer.allocateDirect(1);
|
||||
Object maybeInvokeMethod = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
// See https://bugs.openjdk.java.net/browse/JDK-8171377
|
||||
Method m = PlatformDependent0.UNSAFE.getClass().getDeclaredMethod(
|
||||
"invokeCleaner", ByteBuffer.class);
|
||||
m.invoke(PlatformDependent0.UNSAFE, buffer);
|
||||
return m;
|
||||
} catch (NoSuchMethodException e) {
|
||||
return e;
|
||||
} catch (InvocationTargetException e) {
|
||||
return e;
|
||||
} catch (IllegalAccessException e) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (maybeInvokeMethod instanceof Throwable) {
|
||||
method = null;
|
||||
error = (Throwable) maybeInvokeMethod;
|
||||
@ -73,10 +81,35 @@ final class CleanerJava9 implements Cleaner {
|
||||
|
||||
@Override
|
||||
public void freeDirectBuffer(ByteBuffer buffer) {
|
||||
try {
|
||||
INVOKE_CLEANER.invoke(PlatformDependent0.UNSAFE, buffer);
|
||||
} catch (Throwable cause) {
|
||||
PlatformDependent0.throwException(cause);
|
||||
// Try to minimize overhead when there is no SecurityManager present.
|
||||
// See https://bugs.openjdk.java.net/browse/JDK-8191053.
|
||||
if (System.getSecurityManager() == null) {
|
||||
try {
|
||||
INVOKE_CLEANER.invoke(PlatformDependent0.UNSAFE, buffer);
|
||||
} catch (Throwable cause) {
|
||||
PlatformDependent0.throwException(cause);
|
||||
}
|
||||
} else {
|
||||
freeDirectBufferPrivileged(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
private static void freeDirectBufferPrivileged(final ByteBuffer buffer) {
|
||||
Exception error = AccessController.doPrivileged(new PrivilegedAction<Exception>() {
|
||||
@Override
|
||||
public Exception run() {
|
||||
try {
|
||||
INVOKE_CLEANER.invoke(PlatformDependent0.UNSAFE, buffer);
|
||||
} catch (InvocationTargetException e) {
|
||||
return e;
|
||||
} catch (IllegalAccessException e) {
|
||||
return e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (error != null) {
|
||||
PlatformDependent0.throwException(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user