Support JDK17 by xerial · Pull Request #660 · msgpack/msgpack-java

Expand Up @@ -18,19 +18,22 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.Buffer; import java.nio.ByteBuffer; import java.security.AccessController; import java.security.PrivilegedAction;
import sun.misc.Unsafe; import sun.nio.ch.DirectBuffer;
/** * Wraps the difference of access methods to DirectBuffers between Android and others. */ class DirectBufferAccess { private DirectBufferAccess() {} { }
enum DirectBufferConstructorType { Expand All @@ -40,7 +43,6 @@ enum DirectBufferConstructorType ARGS_MB_INT_INT }
static Method mGetAddress; // For Java <=8, gets a sun.misc.Cleaner static Method mCleaner; static Method mClean; Expand Down Expand Up @@ -95,10 +97,19 @@ enum DirectBufferConstructorType if (byteBufferConstructor == null) { throw new RuntimeException("Constructor of DirectByteBuffer is not found"); } byteBufferConstructor.setAccessible(true);
mGetAddress = directByteBufferClass.getDeclaredMethod("address"); mGetAddress.setAccessible(true); try { byteBufferConstructor.setAccessible(true); } catch (RuntimeException e) { // This is a Java9+ exception, so we need to detect it without importing it for Java8 support if ("java.lang.reflect.InaccessibleObjectException".equals(e.getClass().getName())) { byteBufferConstructor = null; } else { throw e; } }
if (MessageBuffer.javaVersion <= 8) { setupCleanerJava6(direct); Expand Down Expand Up @@ -160,6 +171,7 @@ public Object run()
/** * Checks if we have a usable {@link DirectByteBuffer#cleaner}. * * @param direct a direct buffer * @return the method or an error */ Expand All @@ -184,6 +196,7 @@ private static Object getCleanerMethod(ByteBuffer direct)
/** * Checks if we have a usable {@link sun.misc.Cleaner#clean}. * * @param direct a direct buffer * @param mCleaner the {@link DirectByteBuffer#cleaner} method * @return the method or null Expand All @@ -210,6 +223,7 @@ private static Object getCleanMethod(ByteBuffer direct, Method mCleaner)
/** * Checks if we have a usable {@link Unsafe#invokeCleaner}. * * @param direct a direct buffer * @return the method or an error */ Expand All @@ -218,7 +232,7 @@ private static Object getInvokeCleanerMethod(ByteBuffer direct) try { // See https://bugs.openjdk.java.net/browse/JDK-8171377 Method m = MessageBuffer.unsafe.getClass().getDeclaredMethod( "invokeCleaner", ByteBuffer.class); "invokeCleaner", ByteBuffer.class); m.invoke(MessageBuffer.unsafe, direct); return m; } Expand All @@ -233,17 +247,9 @@ private static Object getInvokeCleanerMethod(ByteBuffer direct) } }
static long getAddress(Object base) static long getAddress(Buffer buffer) { try { return (Long) mGetAddress.invoke(base); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } return ((DirectBuffer) buffer).address(); }
static void clean(Object base) Expand All @@ -253,7 +259,7 @@ static void clean(Object base) Object cleaner = mCleaner.invoke(base); mClean.invoke(cleaner); } else { else { mInvokeCleaner.invoke(MessageBuffer.unsafe, base); } } Expand All @@ -269,6 +275,10 @@ static boolean isDirectByteBufferInstance(Object s)
static ByteBuffer newByteBuffer(long address, int index, int length, ByteBuffer reference) { if (byteBufferConstructor == null) { throw new IllegalStateException("Can't create a new DirectByteBuffer. In JDK17+, two JVM options needs to be set: " + "--add-opens=java.base/java.nio=ALL-UNNAMED and --add-opens=java.base/sun.nio.ch=ALL-UNNAMED"); } try { switch (directBufferConstructorType) { case ARGS_LONG_INT_REF: Expand Down