Apache Johnzon Docker Compose 部署指南

说明 Apache Johnzon 是 Java 库而非守护进程、无需独立进程托管,并给出一份用于演示编译与运行 Johnzon 2.2.0(JSON-P/JSON-B/Mapper)示例的构建环境 Docker Compose 编排。

Apache JohnzonApache JohnzonJava容器化部署ApacheDocker Compose2026/10/12

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-buildmvn package -DskipTests编译 + shade 打 fat-jar;改源码后重跑此服务
johnzon-build(替换)mvn dependency:tree核对依赖版本(Johnzon 2.2.0 等)
johnzon-build(替换)mvn test运行工程测试(如已编写)
johnzon-runjava -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 编码保存。

十二、参考链接