Ubuntu 22.04 安装 Apache Fory 指南
Ubuntu 22.04 安装 Apache Fory 1.7.6 指南:apt 安装 JDK 17 与 Maven,引入 fory-core 运行 POJO 序列化示例,含 JDK 17 的 --add-opens 说明、版本验证与卸载。
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),用于替代 JDKObjectOutputStream,可获得更小的字节体积与更高吞吐。 - 跨语言模式:
withLanguage(Language.XLANG),供 Java 与 Python/C++/Go 等多语言进程交换数据。
核心坐标为 org.apache.fory:fory-core。
1.2 前置条件
| 项目 | 要求 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(x86_64) |
| 包管理器 | apt |
| JDK | JDK 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 软件清单
| 软件 | 版本 | 说明 |
|---|---|---|
| OpenJDK | 17(17.0.20.1) | 运行环境 |
| Apache Maven | 3.6.3 | 依赖解析与构建 |
| Apache Fory | 1.7.6 | org.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 区间。