in memory/memory-core/src/main/java/org/apache/arrow/memory/util/MemoryUtil.java [53:150]
static {
try {
// try to get the unsafe object
final Object maybeUnsafe =
AccessController.doPrivileged(
new PrivilegedAction<Object>() {
@Override
@SuppressWarnings({"nullness:argument", "nullness:return"})
// incompatible argument for parameter obj of Field.get
// incompatible types in return
public Object run() {
try {
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
return unsafeField.get(null);
} catch (Throwable e) {
return e;
}
}
});
if (maybeUnsafe instanceof Throwable) {
throw (Throwable) maybeUnsafe;
}
UNSAFE = (Unsafe) maybeUnsafe;
// get the offset of the data inside a byte array object
BYTE_ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
// get the offset of the address field in a java.nio.Buffer object
Field addressField = java.nio.Buffer.class.getDeclaredField("address");
addressField.setAccessible(true);
BYTE_BUFFER_ADDRESS_OFFSET = UNSAFE.objectFieldOffset(addressField);
Constructor<?> directBufferConstructor;
long address = -1;
final ByteBuffer direct = ByteBuffer.allocateDirect(1);
try {
final Object maybeDirectBufferConstructor =
AccessController.doPrivileged(
new PrivilegedAction<Object>() {
@Override
public Object run() {
try {
final Constructor<?> constructor =
(majorVersion >= 21)
? direct.getClass().getDeclaredConstructor(long.class, long.class)
: direct.getClass().getDeclaredConstructor(long.class, int.class);
constructor.setAccessible(true);
logger.debug("Constructor for direct buffer found and made accessible");
return constructor;
} catch (NoSuchMethodException e) {
logger.debug("Cannot get constructor for direct buffer allocation", e);
return e;
} catch (SecurityException e) {
logger.debug("Cannot get constructor for direct buffer allocation", e);
return e;
}
}
});
if (maybeDirectBufferConstructor instanceof Constructor<?>) {
address = UNSAFE.allocateMemory(1);
// try to use the constructor now
try {
((Constructor<?>) maybeDirectBufferConstructor).newInstance(address, 1);
directBufferConstructor = (Constructor<?>) maybeDirectBufferConstructor;
logger.debug("direct buffer constructor: available");
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
logger.warn("unable to instantiate a direct buffer via constructor", e);
directBufferConstructor = null;
}
} else {
logger.debug(
"direct buffer constructor: unavailable", (Throwable) maybeDirectBufferConstructor);
directBufferConstructor = null;
}
} finally {
if (address != -1) {
UNSAFE.freeMemory(address);
}
}
DIRECT_BUFFER_CONSTRUCTOR = directBufferConstructor;
} catch (Throwable e) {
// This exception will get swallowed, but it's necessary for the static analysis that ensures
// the static fields above get initialized
final RuntimeException failure =
new RuntimeException(
"Failed to initialize MemoryUtil. You must start Java with "
+ "`--add-opens=java.base/java.nio=org.apache.arrow.memory.core,ALL-UNNAMED` "
+ "(See https://arrow.apache.org/docs/java/install.html)",
e);
failure.printStackTrace();
throw failure;
}
}