Skip to content
Commits on Source (5)
msgpack-java (0.8.19-1) unstable; urgency=medium
* New upstream version 0.8.19
-- Andrius Merkys <merkys@debian.org> Mon, 25 Nov 2019 02:08:10 -0500
msgpack-java (0.8.18-2) unstable; urgency=medium
* Refreshing version number in patches to fix failing build.
......
......@@ -10,7 +10,7 @@ Author: Andrius Merkys <merkys@debian.org>
- <packaging>jar</packaging>
+ <packaging>pom</packaging>
<description>Jackson extension that adds support for MessagePack</description>
<version>0.8.18</version>
<version>0.8.19</version>
<name>jackson-dataformat-msgpack</name>
@@ -77,4 +77,24 @@
<scope>test</scope>
......
......@@ -11,7 +11,7 @@ Author: Andrius Merkys <merkys@debian.org>
+ <artifactId>msgpack-java</artifactId>
+ <packaging>jar</packaging>
+ <description>Jackson extension that adds support for MessagePack</description>
+ <version>0.8.18</version>
+ <version>0.8.19</version>
+ <name>jackson-dataformat-msgpack</name>
+ <organization>
+ <name>MessagePack</name>
......@@ -63,7 +63,7 @@ Author: Andrius Merkys <merkys@debian.org>
+ <dependency>
+ <groupId>org.msgpack</groupId>
+ <artifactId>msgpack-core</artifactId>
+ <version>0.8.18</version>
+ <version>0.8.19</version>
+ </dependency>
+ <dependency>
+ <groupId>com.fasterxml.jackson.core</groupId>
......@@ -94,7 +94,7 @@ Author: Andrius Merkys <merkys@debian.org>
+ <parent>
+ <groupId>org.msgpack</groupId>
+ <artifactId>msgpack-java</artifactId>
+ <version>0.8.18</version>
+ <version>0.8.19</version>
+ </parent>
+ <artifactId>msgpack-core</artifactId>
+ <build>
......@@ -114,7 +114,7 @@ Author: Andrius Merkys <merkys@debian.org>
+ <parent>
+ <groupId>org.msgpack</groupId>
+ <artifactId>msgpack-java</artifactId>
+ <version>0.8.18</version>
+ <version>0.8.19</version>
+ </parent>
+ <artifactId>msgpack-jackson</artifactId>
+ <build>
......
......@@ -19,6 +19,10 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.misc.Unsafe;
/**
* Wraps the difference of access methods to DirectBuffers between Android and others.
......@@ -37,20 +41,24 @@ class DirectBufferAccess
}
static Method mGetAddress;
// For Java <=8, gets a sun.misc.Cleaner
static Method mCleaner;
static Method mClean;
// For Java >=9, invokes a jdk.internal.ref.Cleaner
static Method mInvokeCleaner;
// TODO We should use MethodHandle for efficiency, but it is not available in JDK6
static Constructor byteBufferConstructor;
static Constructor<?> byteBufferConstructor;
static Class<?> directByteBufferClass;
static DirectBufferConstructorType directBufferConstructorType;
static Method memoryBlockWrapFromJni;
static {
try {
final ByteBuffer direct = ByteBuffer.allocateDirect(1);
// Find the hidden constructor for DirectByteBuffer
directByteBufferClass = ClassLoader.getSystemClassLoader().loadClass("java.nio.DirectByteBuffer");
Constructor directByteBufferConstructor = null;
directByteBufferClass = direct.getClass();
Constructor<?> directByteBufferConstructor = null;
DirectBufferConstructorType constructorType = null;
Method mbWrap = null;
try {
......@@ -92,17 +100,139 @@ class DirectBufferAccess
mGetAddress = directByteBufferClass.getDeclaredMethod("address");
mGetAddress.setAccessible(true);
mCleaner = directByteBufferClass.getDeclaredMethod("cleaner");
mCleaner.setAccessible(true);
mClean = mCleaner.getReturnType().getDeclaredMethod("clean");
mClean.setAccessible(true);
if (MessageBuffer.javaVersion <= 8) {
setupCleanerJava6(direct);
}
else {
setupCleanerJava9(direct);
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private static void setupCleanerJava6(final ByteBuffer direct)
{
Object obj;
obj = AccessController.doPrivileged(new PrivilegedAction<Object>()
{
@Override
public Object run()
{
return getCleanerMethod(direct);
}
});
if (obj instanceof Throwable) {
throw new RuntimeException((Throwable) obj);
}
mCleaner = (Method) obj;
obj = AccessController.doPrivileged(new PrivilegedAction<Object>()
{
@Override
public Object run()
{
return getCleanMethod(direct, mCleaner);
}
});
if (obj instanceof Throwable) {
throw new RuntimeException((Throwable) obj);
}
mClean = (Method) obj;
}
private static void setupCleanerJava9(final ByteBuffer direct)
{
Object obj = AccessController.doPrivileged(new PrivilegedAction<Object>()
{
@Override
public Object run()
{
return getInvokeCleanerMethod(direct);
}
});
if (obj instanceof Throwable) {
throw new RuntimeException((Throwable) obj);
}
mInvokeCleaner = (Method) obj;
}
/**
* Checks if we have a usable {@link DirectByteBuffer#cleaner}.
* @param direct a direct buffer
* @return the method or an error
*/
private static Object getCleanerMethod(ByteBuffer direct)
{
try {
Method m = direct.getClass().getDeclaredMethod("cleaner");
m.setAccessible(true);
m.invoke(direct);
return m;
}
catch (NoSuchMethodException e) {
return e;
}
catch (InvocationTargetException e) {
return e;
}
catch (IllegalAccessException e) {
return e;
}
}
/**
* 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
*/
private static Object getCleanMethod(ByteBuffer direct, Method mCleaner)
{
try {
Method m = mCleaner.getReturnType().getDeclaredMethod("clean");
Object c = mCleaner.invoke(direct);
m.setAccessible(true);
m.invoke(c);
return m;
}
catch (NoSuchMethodException e) {
return e;
}
catch (InvocationTargetException e) {
return e;
}
catch (IllegalAccessException e) {
return e;
}
}
/**
* Checks if we have a usable {@link Unsafe#invokeCleaner}.
* @param direct a direct buffer
* @return the method or an error
*/
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);
m.invoke(MessageBuffer.unsafe, direct);
return m;
}
catch (NoSuchMethodException e) {
return e;
}
catch (InvocationTargetException e) {
return e;
}
catch (IllegalAccessException e) {
return e;
}
}
static long getAddress(Object base)
{
try {
......@@ -119,9 +249,14 @@ class DirectBufferAccess
static void clean(Object base)
{
try {
if (MessageBuffer.javaVersion <= 8) {
Object cleaner = mCleaner.invoke(base);
mClean.invoke(cleaner);
}
else {
mInvokeCleaner.invoke(MessageBuffer.unsafe, base);
}
}
catch (Throwable e) {
throw new RuntimeException(e);
}
......
......@@ -47,6 +47,7 @@ public class MessageBuffer
{
static final boolean isUniversalBuffer;
static final Unsafe unsafe;
static final int javaVersion = getJavaVersion();
/**
* Reference to MessageBuffer Constructors
......@@ -69,21 +70,6 @@ public class MessageBuffer
int arrayByteBaseOffset = 16;
try {
// Check java version
String javaVersion = System.getProperty("java.specification.version", "");
int dotPos = javaVersion.indexOf('.');
boolean isJavaAtLeast7 = false;
if (dotPos != -1) {
try {
int major = Integer.parseInt(javaVersion.substring(0, dotPos));
int minor = Integer.parseInt(javaVersion.substring(dotPos + 1));
isJavaAtLeast7 = major > 1 || (major == 1 && minor >= 7);
}
catch (NumberFormatException e) {
e.printStackTrace(System.err);
}
}
boolean hasUnsafe = false;
try {
hasUnsafe = Class.forName("sun.misc.Unsafe") != null;
......@@ -97,12 +83,12 @@ public class MessageBuffer
// Is Google App Engine?
boolean isGAE = System.getProperty("com.google.appengine.runtime.version") != null;
// For Java6, android and JVM that has no Unsafe class, use Universal MessageBuffer
// For Java6, android and JVM that has no Unsafe class, use Universal MessageBuffer (based on ByteBuffer).
useUniversalBuffer =
Boolean.parseBoolean(System.getProperty("msgpack.universal-buffer", "false"))
|| isAndroid
|| isGAE
|| !isJavaAtLeast7
|| javaVersion < 7
|| !hasUnsafe;
if (!useUniversalBuffer) {
......@@ -175,6 +161,31 @@ public class MessageBuffer
}
}
private static int getJavaVersion()
{
String javaVersion = System.getProperty("java.specification.version", "");
int dotPos = javaVersion.indexOf('.');
if (dotPos != -1) {
try {
int major = Integer.parseInt(javaVersion.substring(0, dotPos));
int minor = Integer.parseInt(javaVersion.substring(dotPos + 1));
return major > 1 ? major : minor;
}
catch (NumberFormatException e) {
e.printStackTrace(System.err);
}
}
else {
try {
return Integer.parseInt(javaVersion);
}
catch (NumberFormatException e) {
e.printStackTrace(System.err);
}
}
return 6;
}
/**
* Base object for resolving the relative address of the raw byte array.
* If base == null, the address value is a raw memory address
......@@ -366,7 +377,12 @@ public class MessageBuffer
{
if (bb.isDirect()) {
if (isUniversalBuffer) {
throw new UnsupportedOperationException("Cannot create MessageBuffer from a DirectBuffer on this platform");
// MessageBufferU overrides almost all methods, only field 'size' is used.
this.base = null;
this.address = 0;
this.size = bb.remaining();
this.reference = null;
return;
}
// Direct buffer or off-heap memory
this.base = null;
......
......@@ -258,4 +258,16 @@ public class MessageBufferU
getBytes(0, b, 0, b.length);
return b;
}
@Override
public boolean hasArray()
{
return !wrap.isDirect();
}
@Override
public byte[] array()
{
return hasArray() ? wrap.array() : null;
}
}
......@@ -172,4 +172,10 @@ public class MessagePackFactory
{
return extTypeCustomDesers;
}
@Override
public String getFormatName()
{
return "msgpack";
}
}
version in ThisBuild := "0.8.18"
version in ThisBuild := "0.8.19"