构建 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 Data Interface 库(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 Data Interface 库(Windows)

    $ cd arrow/java
    $ mvn generate-resources -Pgenerate-libs-cdata-all-os -N
    $ dir "../java-dist/bin"
    |__ arrow_cdata_jni/
    
  • 构建除 JNI C Data Interface 库之外的所有 JNI 库(macOS / Linux)

    $ 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 C Data Interface 库之外的所有 JNI 库(Windows)

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

CMake

  • 仅构建 JNI C Data Interface 库(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 Data Interface 库(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 C Data Interface 库之外的所有 JNI 库(macOS / Linux)

    $ 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 C Data Interface 库之外的所有 JNI 库(Windows)

    $ 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 配置项 (profile)

    $ 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 toolchains,并设置特定的测试属性。

配置 Maven toolchains

为了能够使用特定的 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/ 子目录,并更新以下设置:

  • 在“Files”工具窗口中,找到 vector/target/generated-sources 路径,右键点击该目录,选择“Mark Directory as > Generated Sources Root”。无需标记其他生成的源代码目录,因为只有 vector 模块会生成源代码。

  • 对于 JDK 11,由于存在 IntelliJ Bug,您必须进入“Settings > Build, Execution, Deployment > Compiler > Java Compiler”,并禁用“Use ‘–release’ option for cross-compilation (Java 9 and later)”。否则,您会遇到类似“package sun.misc does not exist”的错误。

  • 如果 error-prone 发出虚假警告,您可以完全禁用它(在 Maven 工具窗口中禁用所有 error-prone 配置项,并“Reload All Maven Projects”)。

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

  • 要启用对像 dataset 这样基于 JNI 的模块的调试,请在 Maven 选项卡的“Profiles”下激活特定配置项。确保启用 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
    

安装 Nightly 软件包

警告

这些包不是正式版本。使用风险自负。

Arrow 的每日构建版本 (nightly builds) 会发布在邮件列表 builds@arrow.apache.org 上。工件已上传至 GitHub。例如,2022/07/30 的版本可以在 GitHub Nightly 找到。

从 Apache Nightlies 安装

  1. 查找所使用的 Arrow 库的 nightly 版本号。

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

  2. 将 Apache Nightlies 仓库添加到 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. 确定要使用的 nightly 软件包仓库,例如:https://github.com/ursacomputing/crossbow/releases/tag/nightly-packaging-2022-07-30-0-github-java-jars

  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 编译您的项目。

安装 Staging 软件包

警告

这些包不是正式版本。使用风险自负。

Arrow 的 staging 构建是在准备发布候选版本 (RC) 时创建的。这允许用户在投票发布之前在自己的应用程序中测试 RC 版本。

从 Apache Staging 安装

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

  2. 将 Apache Staging 仓库添加到 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>
    ...