Ubuntu 22.04 安装 Apache Fory 指南

Ubuntu 22.04 安装 Apache Fory 1.7.6 指南:apt 安装 JDK 17 与 Maven,引入 fory-core 运行 POJO 序列化示例,含 JDK 17 的 --add-opens 说明、版本验证与卸载。

Apache ForyApache Fory2026/10/12

Ubuntu 22.04 安装 Apache Fory 指南

目标:在 Ubuntu 22.04 服务器上从零准备 Java 运行环境,通过 Maven 引入 Apache Fory(原 Apache Fury)核心依赖,编写并真实运行一个 POJO 序列化/反序列化示例,最后完成版本验证与卸载。

一、组件简介与前置条件

1.1 组件说明

Apache Fory(原名 Apache Fury)是一个基于 JIT 编译与零拷贝的跨语言序列化框架,同时支持 Java 原生序列化的高性能替换与跨语言(xlang)数据交换。它没有独立守护进程,以普通 Java 库的形式通过 Maven/Gradle 依赖引入到应用中:

  • Java 模式:Fory.builder().withLanguage(Language.JAVA),用于替代 JDK ObjectOutputStream,可获得更小的字节体积与更高吞吐。
  • 跨语言模式:withLanguage(Language.XLANG),供 Java 与 Python/C++/Go 等多语言进程交换数据。

核心坐标为 org.apache.fory:fory-core。

1.2 前置条件

项目要求
操作系统Ubuntu 22.04.5 LTS(x86_64)
包管理器apt
JDKJDK 17(Fory 1.7.6 支持 JDK 8+;JDK 17+ 运行建议按第六章补充 --add-opens)
构建工具Apache Maven 3.6+
磁盘源码与依赖约需 20 MB
内存建议 ≥ 1 GB;JVM 堆限定 256–512 MB
网络可访问 Maven 中央仓库 repo1.maven.org
运行账号root

1.3 软件清单

软件版本说明
OpenJDK17(17.0.20.1)运行环境
Apache Maven3.6.3依赖解析与构建
Apache Fory1.7.6org.apache.fory:fory-core
工作目录/root/fory-lab示例工程

二、安装 JDK 与 Maven

2.1 通过 apt 安装

apt-get update
apt-get install -y openjdk-17-jdk maven

真实回显(节选):

maven is already the newest version (3.6.3-5).
openjdk-17-jdk is already the newest version (17.0.20.1+1-1~22.04).
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.

2.2 验证 JDK

java -version

真实回显:

openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)

如机器上同时安装了多个 JDK,可用 update-alternatives --config java 切换默认版本。

2.3 验证 Maven

mvn -version

真实回显(节选):

Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64

三、创建工程并引入 Fory 依赖

3.1 创建 Maven 工程

mkdir -p /root/fory-lab/src/main/java/com/example
cd /root/fory-lab

3.2 编写 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId>
  <artifactId>fory-lab</artifactId>
  <version>1.0</version>
  <packaging>jar</packaging>
  <properties>
    <maven.compiler.source>17</maven.compiler.source>
    <maven.compiler.target>17</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.fory</groupId>
      <artifactId>fory-core</artifactId>
      <version>1.7.6</version>
    </dependency>
  </dependencies>
</project>

3.3 解析依赖

export MAVEN_OPTS="-Xmx384m"
mvn -q -B dependency:build-classpath -Dmdep.outputFile=cp.txt
cat cp.txt

真实回显:

/root/.m2/repository/org/apache/fory/fory-core/1.7.6/fory-core-1.7.6.jar:/root/.m2/repository/org/codehaus/janino/janino/3.1.12/janino-3.1.12.jar:/root/.m2/repository/org/codehaus/janino/commons-compiler/3.1.12/commons-compiler-3.1.12.jar

依赖树:

mvn -B dependency:tree
[INFO] com.example:fory-lab:jar:1.0
[INFO] \- org.apache.fory:fory-core:jar:1.7.6:compile
[INFO]    \- org.codehaus.janino:janino:jar:3.1.12:compile
[INFO]       \- org.codehaus.janino:commons-compiler:jar:3.1.12:compile
[INFO] BUILD SUCCESS

传递依赖仅 janino 与 commons-compiler(JIT 代码生成所需),体积很小。

四、最小序列化示例

4.1 编写源码

src/main/java/com/example/HelloFory.java:

package com.example;

import org.apache.fory.Fory;
import org.apache.fory.config.Language;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;

public class HelloFory {

  public static class User implements java.io.Serializable {
    public String name;
    public int age;
    public User() {}
    public User(String name, int age) { this.name = name; this.age = age; }
    @Override public String toString() { return "User{name=" + name + ", age=" + age + "}"; }
  }

  public static void main(String[] args) throws Exception {
    Fory fory = Fory.builder()
        .withLanguage(Language.JAVA)
        .requireClassRegistration(false)
        .build();

    User user = new User("Alice", 30);

    // Fory 序列化 / 反序列化往返
    byte[] foryBytes = fory.serialize(user);
    User back = (User) fory.deserialize(foryBytes);

    // JDK 原生序列化字节数对比
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try (ObjectOutputStream oos = new ObjectOutputStream(bos)) {
      oos.writeObject(user);
    }
    int jdkLen = bos.toByteArray().length;

    System.out.println("original     : " + user);
    System.out.println("deserialized : " + back);
    System.out.println("content equal: " + user.toString().equals(back.toString()));
    System.out.println("Fory bytes   : " + foryBytes.length);
    System.out.println("JDK  bytes   : " + jdkLen);
  }
}

说明:User 为普通 POJO。示例显式 requireClassRegistration(false) 以跳过类注册校验;生产环境更推荐调用 fory.register(User.class) 注册,可进一步缩小字节体积(详见第八章)。

4.2 编译

cd /root/fory-lab
CP=$(cat cp.txt)
javac -cp "$CP" -d target/classes src/main/java/com/example/HelloFory.java

4.3 运行并查看回显

java -Xmx384m -cp "target/classes:$CP" com.example.HelloFory

真实回显:

original     : User{name=Alice, age=30}
deserialized : User{name=Alice, age=30}
content equal: true
Fory bytes   : 53
JDK  bytes   : 93

可见同一对象 Fory 序列化字节数(53)远小于 JDK 原生序列化(93),且往返内容一致。

五、版本验证

运行时打印 Fory 版本:

System.out.println("Fory version : " + Fory.class.getPackage().getImplementationVersion());

真实回显:

Fory version : 1.7.6

也可通过依赖树确认解析到的版本为 org.apache.fory:fory-core:jar:1.7.6:compile。

六、JDK 17+ 运行时的 --add-opens 说明

Fory 通过反射/JIT 访问 JDK 内部结构。在 JDK 17 及以上(尤其启用强封装时),建议补充 --add-opens 参数以避免反射访问告警或失败:

java -Xmx384m \
  --add-opens java.base/java.lang=ALL-UNNAMED \
  --add-opens java.base/java.lang.invoke=ALL-UNNAMED \
  --add-opens java.base/java.util=ALL-UNNAMED \
  --add-opens java.base/java.util.concurrent=ALL-UNNAMED \
  --add-opens java.base/java.math=ALL-UNNAMED \
  --add-opens java.base/java.net=ALL-UNNAMED \
  --add-opens java.base/java.nio=ALL-UNNAMED \
  --add-opens java.base/java.time=ALL-UNNAMED \
  -cp "target/classes:$CP" com.example.HelloFory

在本次实测的 OpenJDK 17.0.20.1 上,不加该参数也能正常运行上述示例;加入后同样正常,属推荐的防御性配置。

七、卸载

停止使用后,删除工程目录与本地仓库中的依赖即可:

rm -rf /root/fory-lab
rm -rf /root/.m2/repository/org/apache/fory

如不再需要 JDK 与 Maven:

apt-get remove -y openjdk-17-jdk maven
apt-get autoremove -y

八、常见问题

Q1:序列化未注册的类时报 InsecureException: class ... is not registered?

Fory 默认 requireClassRegistration=true。两种处理方式:一是调用 fory.register(YourClass.class) 注册(推荐,且因不再写类名而字节更小);二是确认环境可信后设置 .requireClassRegistration(false)。

Q2:NoClassDefFoundError: org/apache/fory/Fory?

依赖未进入运行时 classpath。请确认 mvn dependency:build-classpath 已生成 cp.txt,且 java -cp 中同时包含 target/classes 与 cp.txt 内容。

Q3:JDK 17 上出现 WARNING: An illegal reflective access 或模块访问异常?

按第六章加入 --add-opens 参数即可。

Q4:Maven 下载依赖缓慢或失败?

可在 ~/.m2/settings.xml 配置国内镜像仓库(如阿里云 maven.aliyun.com)。

Q5:如何控制内存?

示例统一使用 -Xmx384m,请将 JVM 堆保持在 256–512 MB 区间。