Apache Johnzon Docker Compose 部署指南
说明 Apache Johnzon 是 Java 库而非守护进程、无需独立进程托管,并给出一份用于演示编译与运行 Johnzon 2.2.0(JSON-P/JSON-B/Mapper)示例的构建环境 Docker Compose 编排。
Apache Johnzon Docker Compose 部署指南
目标:Apache Johnzon 是 Java 侧 JSON 解析/绑定库(JSR-353/374/367 参考实现),它不是一个常驻的守护进程服务,因此没有「独立拉起一个服务」的 Compose 场景。本文首先说明「库无需独立进程托管」的结论,再给出一份构建/运行环境的 Compose 编排——用 Maven 基础镜像挂载示例源码,编译并运行 Johnzon 2.2.0 的 JSON-P/JSON-B/Mapper 示例,采集真实回显。已在 Ubuntu 22.04、Docker Compose 环境下实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS
- Docker:29.8.1;Docker Compose:v5.5.1
- Compose 目标镜像:
maven:3.9-eclipse-temurin-17(含 Maven 3.9.9 + JDK 17,实测镜像大小 775MB) - 示例源码目录:
/opt/johnzon-demo(工程) - Compose 工作目录:
/opt/johnzon-compose - 依赖版本:Johnzon 2.2.0、jakarta.json-api 2.1.3、jakarta.json.bind-api 3.0.1
- Maven 镜像加速:阿里云
https://maven.aliyun.com/repository/public
二、镜像选型说明
| 用途 | 镜像 | 说明 |
|---|---|---|
| 编译构建 | maven:3.9-eclipse-temurin-17 | 内置 Maven 3.9.9 与 JDK 17,可直接执行 mvn package |
| 运行示例 | maven:3.9-eclipse-temurin-17(复用) | 直接以 java -jar 运行打好的 fat-jar,无需额外 JRE 镜像 |
💡 说明:Johnzon 本身不提供任何官方 Docker 镜像——因为它是被上层 Java 应用 import 的库,而非可独立启动的程序。上表的 Maven 镜像仅充当「编译/运行 Johnzon 示例」的构建环境载体;Johnzon 2.2.0 编译目标为 Java 11,选 17 镜像向下兼容。
三、前置条件
- 服务器已安装 Docker 与 Docker Compose 插件(
docker --version、docker compose version可执行)。 - 需能访问 Maven 仓库(本文使用阿里云镜像加速);Johnzon 演示工程无外部网络依赖,离线编译亦可(依赖进缓存后)。
- 示例源码目录
/opt/johnzon-demo已包含pom.xml与src/main/java(创建方法见《Ubuntu 22.04 安装 Apache Johnzon 指南》)。
四、部署步骤(构建环境 Compose)
4.1 编写 Compose 编排文件
创建 Compose 工作目录 /opt/johnzon-compose,先放置 Maven 镜像加速配置 maven-settings.xml:
mkdir -p /opt/johnzon-compose
cat > /opt/johnzon-compose/maven-settings.xml <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<name>Aliyun Maven Central Mirror</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
</settings>
EOF
创建 /opt/johnzon-compose/compose.yml:
services:
johnzon-build:
image: maven:3.9-eclipse-temurin-17
container_name: johnzon-build
working_dir: /opt/johnzon-demo
command: ["mvn", "package", "-DskipTests"]
volumes:
- /opt/johnzon-demo:/opt/johnzon-demo
- m2cache:/root/.m2
- ./maven-settings.xml:/root/.m2/settings.xml:ro
environment:
- MAVEN_OPTS=-Xms256m -Xmx512m
johnzon-run:
image: maven:3.9-eclipse-temurin-17
container_name: johnzon-run
working_dir: /opt/johnzon-demo
command: ["java", "-Xms256m", "-Xmx512m", "-Dfile.encoding=UTF-8", "-jar", "target/johnzon-demo-1.0.0.jar"]
volumes:
- /opt/johnzon-demo:/opt/johnzon-demo
depends_on:
- johnzon-build
volumes:
m2cache:
💡 说明:
working_dir + command让 johnzon-build 把挂载的源码目录作为工作台执行 Maven 打包;m2cache命名卷缓存依赖避免重复下载;maven-settings.xml只读挂载注入镜像加速配置;MAVEN_OPTS限制构建进程堆 256–512MB。
4.2 启动并验证编译服务正常退出
cd /opt/johnzon-compose
docker compose up -d
真实回显:
[+] Running 2/0
✔ Container johnzon-build Started
✔ Container johnzon-run Started
首次运行时 johnzon-run 会因 jar 尚未编译完成而退出(depends_on 只保证启动顺序),属预期;待 johnzon-build 退出后重启 johnzon-run 即可(见 4.4)。
查看服务状态(johnzon-build 状态为 Exited (0) 即编译成功):
cd /opt/johnzon-compose
docker compose ps -a
真实回显:
NAME IMAGE STATUS
johnzon-build maven:3.9-eclipse-temurin-17 Exited (0) About a minute ago
johnzon-run maven:3.9-eclipse-temurin-17 Exited (1) 2 minutes ago
4.3 查看编译日志确认产物生成
cd /opt/johnzon-compose
docker compose logs johnzon-build
真实回显(关键行):
johnzon-build | Downloading from aliyunmaven: https://maven.aliyun.com/repository/public/org/apache/maven/plugins/maven-resources-plugin/3.4.0/maven-resources-plugin-3.4.0.pom
johnzon-build | [INFO] Building jar: /opt/johnzon-demo/target/johnzon-demo-1.0.0.jar
johnzon-build | [INFO] Including jakarta.json:jakarta.json-api:jar:2.1.3 in the shaded jar.
johnzon-build | [INFO] Including jakarta.json.bind:jakarta.json.bind-api:jar:3.0.1 in the shaded jar.
johnzon-build | [INFO] Including org.apache.johnzon:johnzon-core:jar:2.2.0 in the shaded jar.
johnzon-build | [INFO] Including org.apache.johnzon:johnzon-mapper:jar:2.2.0 in the shaded jar.
johnzon-build | [INFO] Including org.apache.johnzon:johnzon-jsonb:jar:2.2.0 in the shaded jar.
johnzon-build | [INFO] Replacing original artifact with shaded artifact.
johnzon-build | [INFO] BUILD SUCCESS
产物已落回宿主机挂载目录:
ls -lh /opt/johnzon-demo/target/johnzon-demo-1.0.0.jar
真实回显:
-rw-r--r-- 1 root root 635K Oct 11 13:05 /opt/johnzon-demo/target/johnzon-demo-1.0.0.jar
4.4 在构建环境中运行 Johnzon 示例
先清理退出码非 0 的旧 run 记录,再通过 run 服务执行 fat-jar:
cd /opt/johnzon-compose
docker compose down
docker compose up -d johnzon-run
查看运行日志(JsonpDemo 输出):
docker compose logs johnzon-run
真实回显:
johnzon-run | [build] compact = {"id":1001,"name":"johnzon","price":49.9,"tags":["json","parser"],"author":{"name":"Apache","site":"johnzon.apache.org"}}
johnzon-run | [pretty]
johnzon-run | {
johnzon-run | "id":1001,
johnzon-run | "name":"johnzon",
johnzon-run | "price":49.9,
johnzon-run | "tags":[
johnzon-run | "json",
johnzon-run | "parser"
johnzon-run | ],
johnzon-run | "author":{
johnzon-run | "name":"Apache",
johnzon-run | "site":"johnzon.apache.org"
johnzon-run | }
johnzon-run | }
johnzon-run | [parse] user = root
johnzon-run | [parse] port = 22
johnzon-run | [parse] roles = ["admin","dev"]
用 docker compose run --rm 临时运行工程内其他主类(Mapper 示例):
cd /opt/johnzon-compose
docker compose run --rm --name johnzon-run2 johnzon-run \
java -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -cp target/johnzon-demo-1.0.0.jar demo.MapperDemo
真实回显:
[write] {"password":"q1w2e3r4","internal":"hidden","port":22,"host":"web1.example.com","id":1,"user":"root"}
[read] host=web1.example.com port=22 user=root
[pretty]
{
"internal":"hidden",
"id":1,
"host":"web1.example.com",
"port":22,
"user":"root",
"password":"q1w2e3r4"
}
[array] [{"password":"q1w2e3r4","internal":"hidden","port":22,"host":"web1.example.com","id":1,"user":"root"},{"password":"q1w2e3r4","internal":"hidden","port":22,"host":"web1.example.com","id":1,"user":"root"}]
[array-read] size=2 first=web1.example.com
[map] {a=1, b=x}
五、数据持久化说明
- 依赖缓存:命名卷
m2cache挂载到/root/.m2,Maven 下载的 Johnzon 2.2.0、插件等全部落卷内;二次构建不再访问外网,docker compose down后重新up缓存依然有效。 - 构建产物:
target/位于挂载目录/opt/johnzon-demo内,jar 直接落在宿主机磁盘,即使删除 johnzon-build 服务(docker compose rm)产物也不丢失。 - 源码:源码目录 bind mount 进构建服务,改动后重新
up -d johnzon-build即增量编译。
查看依赖缓存卷:
docker volume ls
真实回显(相关行):
local johnzon-compose_m2cache
六、常用环境变量表
| 变量 | 示例值 | 作用 |
|---|---|---|
| MAVEN_OPTS | -Xms256m -Xmx512m | 限制 Maven 构建进程 JVM 堆 256–512MB |
| JAVA_TOOL_OPTIONS | -Dfile.encoding=UTF-8 | 运行示例进程全局编码(中文 JSON 必备) |
| MAVEN_ARGS | -DskipTests | 追加到 mvn 命令后的默认参数(如需) |
| JAVA_HOME | /opt/java/openjdk | 镜像内已内置,一般无需覆盖 |
七、常用配置参数说明(command)
| 服务 | command | 说明 |
|---|---|---|
| johnzon-build | mvn package -DskipTests | 编译 + shade 打 fat-jar;改源码后重跑此服务 |
| johnzon-build(替换) | mvn dependency:tree | 核对依赖版本(Johnzon 2.2.0 等) |
| johnzon-build(替换) | mvn test | 运行工程测试(如已编写) |
| johnzon-run | java -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -jar target/johnzon-demo-1.0.0.jar | 运行 fat-jar 默认主类 demo.JsonpDemo |
| johnzon-run(替换) | java -cp target/johnzon-demo-1.0.0.jar demo.JsonbDemo | 运行 JSON-B 示例 |
| johnzon-run(替换) | java -cp target/johnzon-demo-1.0.0.jar demo.MapperDemo | 运行 Mapper 示例 |
八、配置文件持久化(conf 挂载)
- maven-settings.xml:宿主机
/opt/johnzon-compose/maven-settings.xml只读挂载到/root/.m2/settings.xml,提供阿里云镜像加速;修改后docker compose restart johnzon-build或重新up -d生效。 - pom.xml:随源码目录挂载(
/opt/johnzon-demo/pom.xml),升级 Johnzon 版本只需改<johnzon.version>后重建。 - JVM 参数:写在 compose 的
environment/command中,随编排文件持久化;如需独立管理可改为.env文件注入。
九、等价 docker run 运行方式
不使用 Compose 时,等价的裸命令(先建缓存卷):
# 创建依赖缓存卷
docker volume create m2cache
# 编译打包(等价 johnzon-build)
docker run --rm --name johnzon-build \
-v /opt/johnzon-demo:/opt/johnzon-demo \
-v m2cache:/root/.m2 \
-v /opt/johnzon-compose/maven-settings.xml:/root/.m2/settings.xml:ro \
-e MAVEN_OPTS="-Xms256m -Xmx512m" \
-w /opt/johnzon-demo \
maven:3.9-eclipse-temurin-17 \
mvn package -DskipTests
# 运行示例(等价 johnzon-run)
docker run --rm --name johnzon-run \
-v /opt/johnzon-demo:/opt/johnzon-demo \
-w /opt/johnzon-demo \
maven:3.9-eclipse-temurin-17 \
java -Xms256m -Xmx512m -Dfile.encoding=UTF-8 -jar target/johnzon-demo-1.0.0.jar
十、常用运维命令
cd /opt/johnzon-compose
# 启动(触发编译)
docker compose up -d
# 查看服务状态(含已退出)
docker compose ps -a
# 查看单个服务日志
docker compose logs johnzon-build
docker compose logs johnzon-run
# 一次运行示例(临时服务,退出即删)
docker compose run --rm johnzon-run java -jar target/johnzon-demo-1.0.0.jar
# 停止并移除服务(保留 m2cache 缓存卷)
docker compose down
真实回显:
[+] Running 2/0
✔ Container johnzon-build Removed
[+] Running 1/1
✔ Network johnzon-compose_default Removing
✔ Network johnzon-compose_default Removed
# 清除全部(含 m2cache 依赖缓存卷)
docker compose down -v
十一、常见问题(FAQ)
Q1:johnzon-run 首次启动退出码为 1
首次 up 时 fat-jar 还未编译完成(depends_on 只保证启动顺序)。等待 johnzon-build Exited (0) 后执行 docker compose down && docker compose up -d johnzon-run 重跑即可。
Q2:构建日志显示从 repo.maven.apache.org 下载、速度很慢
maven-settings.xml 没有挂载成功。检查 compose.yml 中 ./maven-settings.xml:/root/.m2/settings.xml:ro 行;注意宿主机路径须与 compose.yml 同目录或改为绝对路径。
Q3:编译报 class file for jakarta.json.JsonValue not found
Johnzon 2.2.0 将 jakarta.json-api/json.bind-api 声明为 provided。在 /opt/johnzon-demo/pom.xml 显式添加两个 API 依赖(见《Ubuntu 22.04 安装 Apache Johnzon 指南》4.4 节)后重新 up -d johnzon-build。
Q4:想升级 Johnzon 版本怎么办
修改 /opt/johnzon-demo/pom.xml 中的 <johnzon.version>(并同步核对 jakarta API 版本),然后 docker compose up -d johnzon-build 重新构建;m2cache 卷会缓存新旧两套依赖,互不影响。
Q5:示例输出中文乱码
给 johnzon-run 的 command 追加 -Dfile.encoding=UTF-8(本文编排已内置),并在源码中统一使用 UTF-8 编码保存。
十二、参考链接
- Apache Johnzon 官网:https://johnzon.apache.org/
- Maven 官方镜像:https://hub.docker.com/_/maven
- Docker Compose 文档:https://docs.docker.com/compose/
- 阿里云 Maven 镜像:https://developer.aliyun.com/mirror/maven
- Johnzon Maven 仓库:https://repo.maven.apache.org/maven2/org/apache/johnzon/