构建 Arrow Java#

系统设置#

Arrow Java 使用 Maven 构建系统。

构建需要

  • JDK 11+

  • Maven 3+

注意

CI 将测试所有支持的 JDK LTS 版本,以及最新的非 LTS 版本。

构建#

以下所有说明都假设您已克隆 Arrow git 存储库

$ git clone https://github.com/apache/arrow.git
$ cd arrow
$ git submodule update --init --recursive

以下是使用以下方法编译 Arrow Java 模块的可用选项:

  • Maven 构建工具。

  • Docker Compose。

  • Archery。

构建 Java 模块#

要构建默认模块,请转到项目根目录并执行

Maven#

$ cd arrow/java
$ export JAVA_HOME=<absolute path to your java home>
$ java --version
$ mvn clean install

Docker compose#

$ cd arrow/java
$ export JAVA_HOME=<absolute path to your java home>
$ java --version
$ docker-compose run java

Archery#

$ cd arrow/java
$ export JAVA_HOME=<absolute path to your java home>
$ java --version
$ archery docker run java

构建 JNI 库 (*.dylib / *.so / *.dll)#

首先,我们需要构建 JNI 绑定将使用的 C++ 共享库。我们可以手动构建这些库,也可以使用 Archery 使用 Docker 容器构建它们(这需要安装 Docker、Docker Compose 和 Archery)。

注意

如果您在 Apple Silicon 上构建,请确保使用为此架构编译的 JDK 版本。例如,请参阅 Azul JDK

如果您在 Windows 操作系统上构建,请参阅 在 Windows 上开发

Maven#

  • 仅构建 JNI C 数据接口库(macOS / Linux)

    $ cd arrow/java
    $ export JAVA_HOME=<absolute path to your java home>
    $ java --version
    $ mvn generate-resources -Pgenerate-libs-cdata-all-os -N
    $ ls -latr ../java-dist/lib
    |__ arrow_cdata_jni/
    
  • 仅构建 JNI C 数据接口库(Windows)

    $ cd arrow/java
    $ mvn generate-resources -Pgenerate-libs-cdata-all-os -N
    $ dir "../java-dist/bin"
    |__ arrow_cdata_jni/
    
  • 构建所有 JNI 库(macOS / Linux),除了 JNI C 数据接口库

    $ cd arrow/java
    $ export JAVA_HOME=<absolute path to your java home>
    $ java --version
    $ mvn generate-resources -Pgenerate-libs-jni-macos-linux -N
    $ ls -latr java-dist/lib
    |__ arrow_dataset_jni/
    |__ arrow_orc_jni/
    |__ gandiva_jni/
    
  • 构建所有 JNI 库(Windows),除了 JNI C 数据接口库

    $ cd arrow/java
    $ mvn generate-resources -Pgenerate-libs-jni-windows -N
    $ dir "../java-dist/bin"
    |__ arrow_dataset_jni/
    

CMake#

  • 仅构建 JNI C 数据接口库(macOS / Linux)

    $ cd arrow
    $ mkdir -p java-dist java-cdata
    $ cmake \
        -S java \
        -B java-cdata \
        -DARROW_JAVA_JNI_ENABLE_C=ON \
        -DARROW_JAVA_JNI_ENABLE_DEFAULT=OFF \
        -DBUILD_TESTING=OFF \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=java-dist
    $ cmake --build java-cdata --target install --config Release
    $ ls -latr java-dist/lib
    |__ arrow_cdata_jni/
    
  • 仅构建 JNI C 数据接口库(Windows)

    $ cd arrow
    $ mkdir java-dist, java-cdata
    $ cmake ^
        -S java ^
        -B java-cdata ^
        -DARROW_JAVA_JNI_ENABLE_C=ON ^
        -DARROW_JAVA_JNI_ENABLE_DEFAULT=OFF ^
        -DBUILD_TESTING=OFF ^
        -DCMAKE_BUILD_TYPE=Release ^
        -DCMAKE_INSTALL_PREFIX=java-dist
    $ cmake --build java-cdata --target install --config Release
    $ dir "java-dist/bin"
    |__ arrow_cdata_jni/
    
  • 构建所有 JNI 库(macOS / Linux),除了 JNI C 数据接口库

    $ cd arrow
    $ brew bundle --file=cpp/Brewfile
    # Homebrew Bundle complete! 25 Brewfile dependencies now installed.
    $ brew uninstall aws-sdk-cpp
    #  (We can't use aws-sdk-cpp installed by Homebrew because it has
    #  an issue: https://github.com/aws/aws-sdk-cpp/issues/1809 )
    $ export JAVA_HOME=<absolute path to your java home>
    $ mkdir -p java-dist cpp-jni
    $ cmake \
        -S cpp \
        -B cpp-jni \
        -DARROW_BUILD_SHARED=OFF \
        -DARROW_CSV=ON \
        -DARROW_DATASET=ON \
        -DARROW_DEPENDENCY_SOURCE=BUNDLED \
        -DARROW_DEPENDENCY_USE_SHARED=OFF \
        -DARROW_FILESYSTEM=ON \
        -DARROW_GANDIVA=ON \
        -DARROW_GANDIVA_STATIC_LIBSTDCPP=ON \
        -DARROW_JSON=ON \
        -DARROW_ORC=ON \
        -DARROW_PARQUET=ON \
        -DARROW_S3=ON \
        -DARROW_SUBSTRAIT=ON \
        -DARROW_USE_CCACHE=ON \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=java-dist \
        -DCMAKE_UNITY_BUILD=ON
    $ cmake --build cpp-jni --target install --config Release
    $ cmake \
        -S java \
        -B java-jni \
        -DARROW_JAVA_JNI_ENABLE_C=OFF \
        -DARROW_JAVA_JNI_ENABLE_DEFAULT=ON \
        -DBUILD_TESTING=OFF \
        -DCMAKE_BUILD_TYPE=Release \
        -DCMAKE_INSTALL_PREFIX=java-dist \
        -DCMAKE_PREFIX_PATH=$PWD/java-dist \
        -DProtobuf_ROOT=$PWD/../cpp-jni/protobuf_ep-install \
        -DProtobuf_USE_STATIC_LIBS=ON
    $ cmake --build java-jni --target install --config Release
    $ ls -latr java-dist/lib/
    |__ arrow_dataset_jni/
    |__ arrow_orc_jni/
    |__ gandiva_jni/
    
  • 构建所有 JNI 库(Windows),除了 JNI C 数据接口库

    $ cd arrow
    $ mkdir java-dist, cpp-jni
    $ cmake ^
        -S cpp ^
        -B cpp-jni ^
        -DARROW_BUILD_SHARED=OFF ^
        -DARROW_CSV=ON ^
        -DARROW_DATASET=ON ^
        -DARROW_DEPENDENCY_USE_SHARED=OFF ^
        -DARROW_FILESYSTEM=ON ^
        -DARROW_GANDIVA=OFF ^
        -DARROW_JSON=ON ^
        -DARROW_ORC=ON ^
        -DARROW_PARQUET=ON ^
        -DARROW_S3=ON ^
        -DARROW_SUBSTRAIT=ON ^
        -DARROW_USE_CCACHE=ON ^
        -DARROW_WITH_BROTLI=ON ^
        -DARROW_WITH_LZ4=ON ^
        -DARROW_WITH_SNAPPY=ON ^
        -DARROW_WITH_ZLIB=ON ^
        -DARROW_WITH_ZSTD=ON ^
        -DCMAKE_BUILD_TYPE=Release ^
        -DCMAKE_INSTALL_PREFIX=java-dist ^
        -DCMAKE_UNITY_BUILD=ON ^
        -GNinja
    $ cd cpp-jni
    $ ninja install
    $ cd ../
    $ cmake ^
        -S java ^
        -B java-jni ^
        -DARROW_JAVA_JNI_ENABLE_C=OFF ^
        -DARROW_JAVA_JNI_ENABLE_DATASET=ON ^
        -DARROW_JAVA_JNI_ENABLE_DEFAULT=ON ^
        -DARROW_JAVA_JNI_ENABLE_GANDIVA=OFF ^
        -DARROW_JAVA_JNI_ENABLE_ORC=ON ^
        -DBUILD_TESTING=OFF ^
        -DCMAKE_BUILD_TYPE=Release ^
        -DCMAKE_INSTALL_PREFIX=java-dist ^
        -DCMAKE_PREFIX_PATH=$PWD/java-dist
    $ cmake --build java-jni --target install --config Release
    $ dir "java-dist/bin"
    |__ arrow_orc_jni/
    |__ arrow_dataset_jni/
    

Archery#

$ cd arrow
$ archery docker run java-jni-manylinux-2014
$ ls -latr java-dist
|__ arrow_cdata_jni/
|__ arrow_dataset_jni/
|__ arrow_orc_jni/
|__ gandiva_jni/

构建 Java JNI 模块#

  • 要编译 JNI 绑定,请使用 arrow-c-data Maven 配置文件

    $ cd arrow/java
    $ mvn -Darrow.c.jni.dist.dir=<absolute path to your arrow folder>/java-dist/lib -Parrow-c-data clean install
    
  • 要为 ORC / Gandiva / Dataset 编译 JNI 绑定,请使用 arrow-jni Maven 配置文件

    $ cd arrow/java
    $ mvn \
        -Darrow.cpp.build.dir=<absolute path to your arrow folder>/java-dist/lib/ \
        -Darrow.c.jni.dist.dir=<absolute path to your arrow folder>/java-dist/lib/ \
        -Parrow-jni clean install
    

测试#

默认情况下,Maven 使用相同的 Java 版本来构建代码和运行测试。

也可以为测试使用不同的 JDK 版本。这需要事先配置 Maven 工具链,然后需要设置特定的测试属性。

配置 Maven 工具链#

要能够为测试使用 JDK 版本,需要先在 Maven toolchains.xml 配置文件中注册它,该文件通常位于 ${HOME}/.m2 下,并在其中添加以下代码段

<?xml version="1.0" encoding="UTF8"?>
<toolchains>

  [...]

  <toolchain>
    <type>jdk</type>
    <provides>
      <version>21</version> <!-- Replace with the corresponding JDK version: 11, 17, ... -->
      <vendor>temurin</vendor> <!-- Replace with the vendor/distribution: temurin, oracle, zulu ... -->
    </provides>
    <configuration>
      <jdkHome>path/to/jdk/home</jdkHome> <!-- Replace with the path to the JDK -->
    </configuration>
  </toolchain>

  [...]

</toolchains>

使用特定 JDK 进行测试#

要使用特定 JDK 版本运行 Arrow 测试,请使用 arrow.test.jdk-version 属性。

例如,要使用 JDK 17 运行 Arrow 测试,请使用以下代码段

$ cd arrow/java
$ mvn -Darrow.test.jdk-version=17 clean verify

IDE 配置#

IntelliJ#

要在 IntelliJ 中开始使用 Arrow:使用 mvn clean install 从命令行构建项目一次。然后打开 Arrow 存储库的 java/ 子目录,并更新以下设置

  • 在“文件”工具窗口中,找到路径 vector/target/generated-sources,右键单击该目录,然后选择“标记目录为”>“生成的源代码根目录”。无需标记其他生成的源代码目录,因为只有 vector 模块生成源代码。

  • 对于 JDK 11,由于 IntelliJ 错误,您必须转到“设置”>“构建、执行、部署”>“编译器”>“Java 编译器”,并禁用“使用“--release”选项进行交叉编译(Java 9 及更高版本)”。否则,您将收到类似“包 sun.misc 不存在”的错误。

  • 如果它给出虚假警告,您可能希望完全禁用 error-prone(在 Maven 工具窗口中禁用 error-prone 配置文件,并“重新加载所有 Maven 项目”)。

  • 如果使用 IntelliJ 的 Maven 集成进行构建,则可能需要由于 IntelliJ 错误而在 pom.xml 文件中将 <fork> 更改为 false

  • 要启用基于 JNI 的模块(如 dataset)的调试,请在“配置文件”下的 Maven 选项卡中激活特定配置文件。确保启用了 arrow-c-dataarrow-jnigenerate-libs-cdata-all-osgenerate-libs-jni-macos-linuxjdk11+ 配置文件,以便 IDE 可以构建它们并启用调试。

如果您使用 IntelliJ Maven 集成而不是直接使用 IntelliJ 进行构建/测试,则可能无需更新所有这些设置。

常见错误#

  • 在使用 JNI 代码时:如果 C++ 构建找不到依赖项,并出现以下错误

    Could NOT find Boost (missing: Boost_INCLUDE_DIR system filesystem)
    Could NOT find Lz4 (missing: LZ4_LIB)
    Could NOT find zstd (missing: ZSTD_LIB)
    

    指定应在构建时下载依赖项(有关更多详细信息,请参阅 依赖项解析

    -Dre2_SOURCE=BUNDLED \
    -DBoost_SOURCE=BUNDLED \
    -Dutf8proc_SOURCE=BUNDLED \
    -DSnappy_SOURCE=BUNDLED \
    -DORC_SOURCE=BUNDLED \
    -DZLIB_SOURCE=BUNDLED
    

安装每日构建包#

警告

这些软件包不是正式发布版本。使用它们需自担风险。

Arrow 每日构建发布在邮件列表 [email protected] 上。工件上传到 GitHub。例如,对于 2022/07/30,可以在 GitHub 每日构建 中找到它们。

从 Apache 每日构建安装#

  1. 查找所用 Arrow 库的每日构建版本号。

    例如,对于 arrow-memory,请访问 https://nightlies.apache.org/arrow/java/org/apache/arrow/arrow-memory/ 并查看可用的版本(例如 9.0.0.dev501)。

  2. 将 Apache 每日构建存储库添加到 Maven/Gradle 项目。

    <properties>
       <arrow.version>9.0.0.dev501</arrow.version>
    </properties>
    ...
    <repositories>
       <repository>
             <id>arrow-apache-nightlies</id>
             <url>https://nightlies.apache.org/arrow/java</url>
       </repository>
    </repositories>
    ...
    <dependencies>
       <dependency>
             <groupId>org.apache.arrow</groupId>
             <artifactId>arrow-vector</artifactId>
             <version>${arrow.version}</version>
       </dependency>
    </dependencies>
    ...
    

手动安装#

  1. 确定要使用的每日构建包存储库,例如:ursacomputing/crossbow

  2. 将软件包添加到您的 pom.xml 中,例如:flight-core(它依赖于:arrow-format、arrow-vector、arrow-memory-core 和 arrow-memory-netty)。

    <properties>
       <maven.compiler.source>8</maven.compiler.source>
       <maven.compiler.target>8</maven.compiler.target>
       <arrow.version>9.0.0.dev501</arrow.version>
    </properties>
    
    <dependencies>
       <dependency>
             <groupId>org.apache.arrow</groupId>
             <artifactId>flight-core</artifactId>
             <version>${arrow.version}</version>
       </dependency>
    </dependencies>
    
  3. 将必要的 pom 和 jar 文件下载到临时目录

    $ mkdir nightly-packaging-2022-07-30-0-github-java-jars
    $ cd nightly-packaging-2022-07-30-0-github-java-jars
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-java-root-9.0.0.dev501.pom
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-format-9.0.0.dev501.pom
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-format-9.0.0.dev501.jar
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-vector-9.0.0.dev501.pom
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-vector-9.0.0.dev501.jar
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-memory-9.0.0.dev501.pom
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-memory-core-9.0.0.dev501.pom
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-memory-netty-9.0.0.dev501.pom
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-memory-core-9.0.0.dev501.jar
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-memory-netty-9.0.0.dev501.jar
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/arrow-flight-9.0.0.dev501.pom
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/flight-core-9.0.0.dev501.pom
    $ wget https://github.com/ursacomputing/crossbow/releases/download/nightly-packaging-2022-07-30-0-github-java-jars/flight-core-9.0.0.dev501.jar
    $ tree
    .
    ├── arrow-flight-9.0.0.dev501.pom
    ├── arrow-format-9.0.0.dev501.jar
    ├── arrow-format-9.0.0.dev501.pom
    ├── arrow-java-root-9.0.0.dev501.pom
    ├── arrow-memory-9.0.0.dev501.pom
    ├── arrow-memory-core-9.0.0.dev501.jar
    ├── arrow-memory-core-9.0.0.dev501.pom
    ├── arrow-memory-netty-9.0.0.dev501.jar
    ├── arrow-memory-netty-9.0.0.dev501.pom
    ├── arrow-vector-9.0.0.dev501.jar
    ├── arrow-vector-9.0.0.dev501.pom
    ├── flight-core-9.0.0.dev501.jar
    └── flight-core-9.0.0.dev501.pom
    
  4. 使用 mvn install:install-file 将工件安装到本地 Maven 存储库

    $ mvn install:install-file -Dfile="$(pwd)/arrow-java-root-9.0.0.dev501.pom" -DgroupId=org.apache.arrow -DartifactId=arrow-java-root -Dversion=9.0.0.dev501 -Dpackaging=pom
    $ mvn install:install-file -Dfile="$(pwd)/arrow-format-9.0.0.dev501.pom" -DgroupId=org.apache.arrow -DartifactId=arrow-format -Dversion=9.0.0.dev501 -Dpackaging=pom
    $ mvn install:install-file -Dfile="$(pwd)/arrow-format-9.0.0.dev501.jar" -DgroupId=org.apache.arrow -DartifactId=arrow-format -Dversion=9.0.0.dev501 -Dpackaging=jar
    $ mvn install:install-file -Dfile="$(pwd)/arrow-vector-9.0.0.dev501.pom" -DgroupId=org.apache.arrow -DartifactId=arrow-vector -Dversion=9.0.0.dev501 -Dpackaging=pom
    $ mvn install:install-file -Dfile="$(pwd)/arrow-vector-9.0.0.dev501.jar" -DgroupId=org.apache.arrow -DartifactId=arrow-vector -Dversion=9.0.0.dev501 -Dpackaging=jar
    $ mvn install:install-file -Dfile="$(pwd)/arrow-memory-9.0.0.dev501.pom" -DgroupId=org.apache.arrow -DartifactId=arrow-memory -Dversion=9.0.0.dev501 -Dpackaging=pom
    $ mvn install:install-file -Dfile="$(pwd)/arrow-memory-core-9.0.0.dev501.pom" -DgroupId=org.apache.arrow -DartifactId=arrow-memory-core -Dversion=9.0.0.dev501 -Dpackaging=pom
    $ mvn install:install-file -Dfile="$(pwd)/arrow-memory-netty-9.0.0.dev501.pom" -DgroupId=org.apache.arrow -DartifactId=arrow-memory-netty -Dversion=9.0.0.dev501 -Dpackaging=pom
    $ mvn install:install-file -Dfile="$(pwd)/arrow-memory-core-9.0.0.dev501.jar" -DgroupId=org.apache.arrow -DartifactId=arrow-memory-core -Dversion=9.0.0.dev501 -Dpackaging=jar
    $ mvn install:install-file -Dfile="$(pwd)/arrow-memory-netty-9.0.0.dev501.jar" -DgroupId=org.apache.arrow -DartifactId=arrow-memory-netty -Dversion=9.0.0.dev501 -Dpackaging=jar
    $ mvn install:install-file -Dfile="$(pwd)/arrow-flight-9.0.0.dev501.pom" -DgroupId=org.apache.arrow -DartifactId=arrow-flight -Dversion=9.0.0.dev501 -Dpackaging=pom
    $ mvn install:install-file -Dfile="$(pwd)/flight-core-9.0.0.dev501.pom" -DgroupId=org.apache.arrow -DartifactId=flight-core -Dversion=9.0.0.dev501 -Dpackaging=pom
    $ mvn install:install-file -Dfile="$(pwd)/flight-core-9.0.0.dev501.jar" -DgroupId=org.apache.arrow -DartifactId=flight-core -Dversion=9.0.0.dev501 -Dpackaging=jar
    
  5. 验证软件包是否已安装

    $ tree ~/.m2/repository/org/apache/arrow
    .
    ├── arrow-flight
    │   ├── 9.0.0.dev501
    │      └── arrow-flight-9.0.0.dev501.pom
    ├── arrow-format
    │   ├── 9.0.0.dev501
    │      ├── arrow-format-9.0.0.dev501.jar
    │      └── arrow-format-9.0.0.dev501.pom
    ├── arrow-java-root
    │   ├── 9.0.0.dev501
    │      └── arrow-java-root-9.0.0.dev501.pom
    ├── arrow-memory
    │   ├── 9.0.0.dev501
    │      └── arrow-memory-9.0.0.dev501.pom
    ├── arrow-memory-core
    │   ├── 9.0.0.dev501
    │      ├── arrow-memory-core-9.0.0.dev501.jar
    │      └── arrow-memory-core-9.0.0.dev501.pom
    ├── arrow-memory-netty
    │   ├── 9.0.0.dev501
    │      ├── arrow-memory-netty-9.0.0.dev501.jar
    │      └── arrow-memory-netty-9.0.0.dev501.pom
    ├── arrow-vector
    │   ├── 9.0.0.dev501
    │      ├── _remote.repositories
    │      ├── arrow-vector-9.0.0.dev501.jar
    │      └── arrow-vector-9.0.0.dev501.pom
    └── flight-core
       ├── 9.0.0.dev501
          ├── flight-core-9.0.0.dev501.jar
          └── flight-core-9.0.0.dev501.pom
    
  6. 像往常一样使用 mvn clean install 编译您的项目。

安装暂存包#

警告

这些软件包不是正式发布版本。使用它们需自担风险。

在准备发布候选版本 (RC) 时会创建 Arrow 暂存构建。这允许用户在对发布进行投票之前在他们的应用程序中测试 RC。

从 Apache 暂存安装#

  1. 查找所用 Arrow 库的下一个版本号。

  2. 将 Apache 暂存存储库添加到 Maven/Gradle 项目。

    <properties>
       <arrow.version>9.0.0</arrow.version>
    </properties>
    ...
    <repositories>
       <repository>
             <id>arrow-apache-staging</id>
             <url>https://repository.apache.org/content/repositories/staging</url>
       </repository>
    </repositories>
    ...
    <dependencies>
       <dependency>
             <groupId>org.apache.arrow</groupId>
             <artifactId>arrow-vector</artifactId>
             <version>${arrow.version}</version>
       </dependency>
    </dependencies>
    ...