Just cast Cleaner to Runnable in Java9+ to prevent IllegalAccessException
Motivation: When try to call Cleaner.run() via reflection on Java9 you may see an IllegalAccessException. Modifications: Just cast the Cleaner to Runnable to prevent IllegalAccessException to be raised. Result: Free direct buffers also work on Java9+ as expected.
This commit is contained in:
parent
cb5f71782e
commit
be77dfb1ca
@ -32,6 +32,8 @@ import java.nio.ByteBuffer;
|
|||||||
final class Cleaner0 {
|
final class Cleaner0 {
|
||||||
private static final long CLEANER_FIELD_OFFSET;
|
private static final long CLEANER_FIELD_OFFSET;
|
||||||
private static final Method CLEAN_METHOD;
|
private static final Method CLEAN_METHOD;
|
||||||
|
private static final boolean CLEANER_IS_RUNNABLE;
|
||||||
|
|
||||||
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Cleaner0.class);
|
private static final InternalLogger logger = InternalLoggerFactory.getInstance(Cleaner0.class);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -39,6 +41,7 @@ final class Cleaner0 {
|
|||||||
Field cleanerField;
|
Field cleanerField;
|
||||||
long fieldOffset = -1;
|
long fieldOffset = -1;
|
||||||
Method clean = null;
|
Method clean = null;
|
||||||
|
boolean cleanerIsRunnable = false;
|
||||||
if (PlatformDependent0.hasUnsafe()) {
|
if (PlatformDependent0.hasUnsafe()) {
|
||||||
try {
|
try {
|
||||||
cleanerField = direct.getClass().getDeclaredField("cleaner");
|
cleanerField = direct.getClass().getDeclaredField("cleaner");
|
||||||
@ -48,20 +51,23 @@ final class Cleaner0 {
|
|||||||
try {
|
try {
|
||||||
// Cleaner implements Runnable from JDK9 onwards.
|
// Cleaner implements Runnable from JDK9 onwards.
|
||||||
Runnable runnable = (Runnable) cleaner;
|
Runnable runnable = (Runnable) cleaner;
|
||||||
clean = Runnable.class.getDeclaredMethod("run");
|
runnable.run();
|
||||||
|
cleanerIsRunnable = true;
|
||||||
} catch (ClassCastException ignored) {
|
} catch (ClassCastException ignored) {
|
||||||
clean = cleaner.getClass().getDeclaredMethod("clean");
|
clean = cleaner.getClass().getDeclaredMethod("clean");
|
||||||
}
|
|
||||||
clean.invoke(cleaner);
|
clean.invoke(cleaner);
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
// We don't have ByteBuffer.cleaner().
|
// We don't have ByteBuffer.cleaner().
|
||||||
fieldOffset = -1;
|
fieldOffset = -1;
|
||||||
clean = null;
|
clean = null;
|
||||||
|
cleanerIsRunnable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
logger.debug("java.nio.ByteBuffer.cleaner(): {}", fieldOffset != -1? "available" : "unavailable");
|
logger.debug("java.nio.ByteBuffer.cleaner(): {}", fieldOffset != -1? "available" : "unavailable");
|
||||||
CLEANER_FIELD_OFFSET = fieldOffset;
|
CLEANER_FIELD_OFFSET = fieldOffset;
|
||||||
CLEAN_METHOD = clean;
|
CLEAN_METHOD = clean;
|
||||||
|
CLEANER_IS_RUNNABLE = cleanerIsRunnable;
|
||||||
|
|
||||||
// free buffer if possible
|
// free buffer if possible
|
||||||
freeDirectBuffer(direct);
|
freeDirectBuffer(direct);
|
||||||
@ -71,12 +77,17 @@ final class Cleaner0 {
|
|||||||
if (CLEANER_FIELD_OFFSET == -1 || !buffer.isDirect()) {
|
if (CLEANER_FIELD_OFFSET == -1 || !buffer.isDirect()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
assert CLEAN_METHOD != null : "CLEANER_FIELD_OFFSET != -1 implies CLEAN_METHOD != null";
|
assert CLEAN_METHOD != null || CLEANER_IS_RUNNABLE:
|
||||||
|
"CLEANER_FIELD_OFFSET != -1 implies CLEAN_METHOD != null or CLEANER_IS_RUNNABLE == true";
|
||||||
try {
|
try {
|
||||||
Object cleaner = PlatformDependent0.getObject(buffer, CLEANER_FIELD_OFFSET);
|
Object cleaner = PlatformDependent0.getObject(buffer, CLEANER_FIELD_OFFSET);
|
||||||
if (cleaner != null) {
|
if (cleaner != null) {
|
||||||
|
if (CLEANER_IS_RUNNABLE) {
|
||||||
|
((Runnable) cleaner).run();
|
||||||
|
} else {
|
||||||
CLEAN_METHOD.invoke(cleaner);
|
CLEAN_METHOD.invoke(cleaner);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
// Nothing we can do here.
|
// Nothing we can do here.
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user