static

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;
    }
  }