Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add workaround for Java17
  • Loading branch information
xerial committed Jun 28, 2022
commit 3dc7e9dde81824d58e9aff3bafa68ed8c93e1370
7 changes: 7 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ lazy val msgpackCore = Project(id = "msgpack-core", base = file("msgpack-core"))
"org.msgpack.value.impl"
),
testFrameworks += new TestFramework("wvlet.airspec.Framework"),
Test / javaOptions ++= Seq(
// --add-opens is not available in JDK8
"-XX:+IgnoreUnrecognizedVMOptions",
"--add-opens=java.base/java.nio=ALL-UNNAMED",
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
),
Test / fork := true,
libraryDependencies ++= Seq(
// msgpack-core should have no external dependencies
junitInterface,
Expand Down
Original file line number Diff line number Diff line change
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 Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import java.nio.ByteBuffer
class DirectBufferAccessTest extends AirSpec {

test("instantiate DirectBufferAccess") {
val arr = Array[Byte](0)
val bb = ByteBuffer.wrap(arr)
val bb = ByteBuffer.allocateDirect(1)
val addr = DirectBufferAccess.getAddress(bb)

}
}