From 3b43c9e03af933c4fcd2c14d67354b747c44dd88 Mon Sep 17 00:00:00 2001
From: David Li
Date: Wed, 7 Sep 2022 13:45:11 -0400
Subject: [PATCH] ARROW-17604: [Docs][Java] Make it more obvious that
--add-opens is required
---
docs/source/java/install.rst | 44 +++++++++++----
java/memory/memory-core/pom.xml | 54 +++++++++++++++++++
.../apache/arrow/memory/util/MemoryUtil.java | 5 +-
.../org/apache/arrow/memory/TestOpens.java | 46 ++++++++++++++++
4 files changed, 137 insertions(+), 12 deletions(-)
create mode 100644 java/memory/memory-core/src/test/java/org/apache/arrow/memory/TestOpens.java
diff --git a/docs/source/java/install.rst b/docs/source/java/install.rst
index 9eaf2b588341..b0ae9e19c690 100644
--- a/docs/source/java/install.rst
+++ b/docs/source/java/install.rst
@@ -15,36 +15,48 @@
.. specific language governing permissions and limitations
.. under the License.
+=======================
Installing Java Modules
=======================
.. contents::
System Compatibility
---------------------
+====================
Java modules are regularly built and tested on macOS and Linux distributions.
Java Compatibility
-------------------
+==================
-Java modules are currently compatible with JDK 8, 9, 10, 11, 17, and 18.
+Java modules are compatible with JDK 8 and above.
Currently, JDK 8, 11, 17, and 18 are tested in CI.
When using Java 9 or later, some JDK internals must be exposed by
-adding ``--add-opens=java.base/java.nio=ALL-UNNAMED``. Otherwise,
-you may see errors like ``module java.base does not "opens
+adding ``--add-opens=java.base/java.nio=ALL-UNNAMED`` to the ``java`` command:
+
+.. code-block:: shell
+
+ # Directly on the command line
+ $ java --add-opens=java.base/java.nio=ALL-UNNAMED -jar ...
+ # Indirectly via environment variables
+ $ env _JAVA_OPTIONS="--add-opens=java.base/java.nio=ALL-UNNAMED" java -jar ...
+
+Otherwise, you may see errors like ``module java.base does not "opens
java.nio" to unnamed module``.
+If using Maven and Surefire for unit testing, :ref:`this argument must
+be added to Surefire as well `.
+
Installing from Maven
----------------------
+=====================
By default, Maven will download from the central repository: https://repo.maven.apache.org/maven2/org/apache/arrow/
Configure your pom.xml with the Java modules needed, for example:
arrow-vector, and arrow-memory-netty.
-.. code-block::
+.. code-block:: xml
-The ``--add-opens`` flag can be added when running unit tests through Maven:
+.. _java-install-maven-testing:
-.. code-block::
+The ``--add-opens`` flag must be added when running unit tests through Maven:
+
+.. code-block:: xml
@@ -131,6 +145,14 @@ Or they can be added via environment variable, for example when executing your c
_JAVA_OPTIONS="--add-opens=java.base/java.nio=ALL-UNNAMED" mvn exec:java -Dexec.mainClass="YourMainCode"
Installing from Source
-----------------------
+======================
See :ref:`java-development`.
+
+IDE Configuration
+=================
+
+Generally, no additional configuration should be needed. However,
+ensure your Maven or other build configuration has the ``--add-opens``
+flag as described above, so that the IDE picks it up and runs tests
+with that flag as well.
diff --git a/java/memory/memory-core/pom.xml b/java/memory/memory-core/pom.xml
index 073a20470c2a..e95a270b1539 100644
--- a/java/memory/memory-core/pom.xml
+++ b/java/memory/memory-core/pom.xml
@@ -37,4 +37,58 @@
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+
+
+ **/TestOpens.java
+
+
+
+
+
+
+
+
+ opens-tests
+
+
+ [16,]
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+
+ opens-tests
+ test
+
+ test
+
+
+
+ -Dfoo=bar
+
+
+ **/TestArrowBuf.java
+
+
+ **/TestOpens.java
+
+
+
+
+
+
+
+
+
diff --git a/java/memory/memory-core/src/main/java/org/apache/arrow/memory/util/MemoryUtil.java b/java/memory/memory-core/src/main/java/org/apache/arrow/memory/util/MemoryUtil.java
index c48ee66c2cc5..70e1a2586f2e 100644
--- a/java/memory/memory-core/src/main/java/org/apache/arrow/memory/util/MemoryUtil.java
+++ b/java/memory/memory-core/src/main/java/org/apache/arrow/memory/util/MemoryUtil.java
@@ -135,7 +135,10 @@ public Object run() {
} 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", e);
+ final RuntimeException failure = new RuntimeException(
+ "Failed to initialize MemoryUtil. Was Java started with " +
+ "`--add-opens=java.base/java.nio=ALL-UNNAMED`? " +
+ "(See https://arrow.apache.org/docs/java/install.html)", e);
failure.printStackTrace();
throw failure;
}
diff --git a/java/memory/memory-core/src/test/java/org/apache/arrow/memory/TestOpens.java b/java/memory/memory-core/src/test/java/org/apache/arrow/memory/TestOpens.java
new file mode 100644
index 000000000000..7efc11a08acf
--- /dev/null
+++ b/java/memory/memory-core/src/test/java/org/apache/arrow/memory/TestOpens.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.arrow.memory;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.Test;
+
+public class TestOpens {
+ /** Instantiating the RootAllocator should poke MemoryUtil and fail. */
+ @Test
+ public void testMemoryUtilFailsLoudly() {
+ // This test is configured by Maven to run WITHOUT add-opens. So this should fail on JDK16+
+ // (where JEP396 means that add-opens is required to access JDK internals).
+ // The test will likely fail in your IDE if it doesn't correctly pick this up.
+ Throwable e = assertThrows(Throwable.class, () -> {
+ BufferAllocator allocator = new RootAllocator();
+ allocator.close();
+ });
+ boolean found = false;
+ while (e != null) {
+ e = e.getCause();
+ if (e instanceof RuntimeException && e.getMessage().contains("Failed to initialize MemoryUtil")) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found, "Expected exception as not thrown");
+ }
+}