Ubuntu 22.04 安装 Apache Daffodil 指南

Ubuntu 22.04 上安装 Apache Daffodil 4.2.0 的完整指南,涵盖 JDK 17 安装、官方发行包下载解压、DAFFODIL_HOME 配置、版本验证,以及最小解析/回写示例与卸载。

Apache DaffodilApache Daffodil2026/10/11

Ubuntu 22.04 安装 Apache Daffodil 指南

目标:在 Ubuntu 22.04 上从零安装 Apache Daffodil 4.2.0,配置运行环境,并用一个定长文本的 DFDL schema 跑通「解析 → 回写」最小闭环,最后给出卸载方法。

一、组件简介与前置条件

1.1 组件说明

Apache Daffodil 是 DFDL(Data Format Description Language,数据格式描述语言)的开源实现,用 DFDL schema(带 dfdl: 注解的 XML Schema)描述数据格式,把定长/文本/二进制数据与 XML 或 JSON 信息集(infoset)互转:

  • parse:按 schema 把原始数据解析为信息集(默认 XML,也可 JSON)。
  • unparse:按 schema 把信息集回写为原始数据。

Daffodil 是纯 JVM 命令行 / 库工具,无守护进程、不监听端口,bin/daffodil 为启动脚本。

1.2 前置条件

项目要求
操作系统Ubuntu 22.04 LTS(x86_64)
包管理器apt
JDKJDK 17(Daffodil 4.x 必需,JDK 11 会报 UnsupportedClassVersionError)
磁盘安装目录约需 150 MB(发行包约 48.6 MB)
内存建议 ≥ 1 GB;JVM 堆按需限制在 256–512 MB
网络可访问 Apache 发行镜像(本文使用阿里云镜像)
运行账号root

1.3 软件清单

软件版本说明
OpenJDK17运行环境
Apache Daffodil4.2.0DFDL 实现
安装位置/opt/daffodil发行包解压目录
发行包apache-daffodil-4.2.0-bin.tgz大小 50963452 字节

二、安装 JDK 17

2.1 通过 apt 安装

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

2.2 验证

java -version
ls -d /usr/lib/jvm/java-17-openjdk-*

真实回显示例:

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)
/usr/lib/jvm/java-17-openjdk-amd64

三、下载与解压 Apache Daffodil

3.1 下载发行包

官方归档站 archive.apache.org 对约 48 MB 的发行包下载较慢,建议使用阿里云镜像(当前版本 4.2.0):

mkdir -p /opt
cd /tmp
curl -sL -o daffodil.tgz \
  https://mirrors.aliyun.com/apache/daffodil/4.2.0/bin/apache-daffodil-4.2.0-bin.tgz
ls -l daffodil.tgz

3.2 校验并解压

sha512sum daffodil.tgz
tar xzf daffodil.tgz -C /opt
mv /opt/apache-daffodil-4.2.0-bin /opt/daffodil
ls /opt/daffodil

真实回显:

2c0e8e95369d4d1c755bac8828f833888d4f2ff05dbff8f2ffda93d5eafdba3be5a07b187363a01ae89e4d5a06f8addc73bc30a54b015335b037bf06a5786066  daffodil.tgz
LICENSE  NOTICE  README.md  bin  lib

该 SHA512 与官方 .sha512 文件一致。bin/ 目录内容:

daffodil
daffodil.bat

四、配置环境变量

4.1 写入 profile

创建 /etc/profile.d/daffodil.sh,内容如下(JAVA_HOME/bin 必须前置,否则启动脚本可能命中旧版 java):

export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export DAFFODIL_HOME=/opt/daffodil
export PATH=$JAVA_HOME/bin:$DAFFODIL_HOME/bin:$PATH

4.2 生效并验证

source /etc/profile.d/daffodil.sh
java -version

真实回显:

openjdk version "17.0.20.1" 2026-08-18

五、安装验证

5.1 版本检查

daffodil --version

真实回显:

Apache Daffodil 4.2.0

5.2 子命令总览

daffodil --help

真实回显:

Usage: daffodil [GLOBAL_OPTS] <subcommand> [SUBCOMMAND_OPTS]

Global Options:
  -v, --verbose   Increment verbosity level, one level for each -v
  -h, --help      Show help message
      --version   Show Daffodil's version

Subcommands:
  parse         Parse data to a DFDL infoset
  unparse       Unparse a DFDL infoset
  save-parser   Save a Daffodil parser for reuse
  test          List or execute TDML tests
  performance   Run performance test
  generate      Generate <language> code from a DFDL schema
  exi           Encode an XML file with EXI

5.3 限制 JVM 堆内存

Daffodil 启动脚本默认使用 -Xms1024m -Xmx1024m。可通过 DAFFODIL_JAVA_OPTS 覆盖(注意同时下调 -Xms):

export DAFFODIL_JAVA_OPTS="-Xms256m -Xmx512m"
daffodil --version

真实回显:

Apache Daffodil 4.2.0

六、最小 DFDL 解析与回写示例

6.1 准备 schema 与数据

工作目录 /root/dfdl。创建 person.dfdl.xsd(定长文本记录:姓名 5 字符、年龄 3 字符、编号 2 字符):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:dfdl="http://www.ogf.org/dfdl/dfdl-1.0/"
           targetNamespace="http://example.com/dfdl/person"
           xmlns:tns="http://example.com/dfdl/person"
           elementFormDefault="unqualified">

  <xs:include schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd"/>

  <xs:annotation>
    <xs:appinfo source="http://www.ogf.org/dfdl/">
      <dfdl:format ref="tns:GeneralFormat" encoding="ASCII" representation="text"/>
    </xs:appinfo>
  </xs:annotation>

  <xs:element name="person" type="tns:PersonType" dfdl:lengthKind="implicit"/>

  <xs:complexType name="PersonType">
    <xs:sequence>
      <xs:element name="name" type="xs:string"
                  dfdl:lengthKind="explicit" dfdl:length="5" dfdl:lengthUnits="characters"/>
      <xs:element name="age" type="xs:unsignedInt"
                  dfdl:lengthKind="explicit" dfdl:length="3" dfdl:lengthUnits="characters"
                  dfdl:textNumberPattern="000"/>
      <xs:element name="code" type="xs:string"
                  dfdl:lengthKind="explicit" dfdl:length="2" dfdl:lengthUnits="characters"/>
    </xs:sequence>
  </xs:complexType>

</xs:schema>

关键点:Daffodil 不内置通用默认格式属性,schema 必须通过 xs:include 引入官方 DFDLGeneralFormat.dfdl.xsd 并 dfdl:format ref="tns:GeneralFormat";该 include 路径需以 / 开头。

创建数据文件 person.txt(共 10 字符):

Alice025AB

6.2 parse:数据 → XML 信息集

cd /root/dfdl
daffodil parse -s person.dfdl.xsd person.txt

真实回显:

<?xml version="1.0" encoding="UTF-8"?>
<tns:person xmlns:tns="http://example.com/dfdl/person">
  <name>Alice</name>
  <age>25</age>
  <code>AB</code>
</tns:person>

6.3 unparse:信息集 → 原始数据(闭环)

daffodil parse -s person.dfdl.xsd person.txt -o person.xml
daffodil unparse -s person.dfdl.xsd person.xml -o person.out
od -c person.out
cmp person.txt person.out && echo IDENTICAL

真实回显:

0000000   A   l   i   c   e   0   2   5   A   B
0000012
IDENTICAL

unparse 输出与原始数据字节级一致。

6.4 输出 JSON 信息集

daffodil parse -s person.dfdl.xsd -I json person.txt

真实回显:

{
  "person": {
    "name": "Alice",
    "age": 25,
    "code": "AB"
  }
}

七、卸载 Apache Daffodil

Daffodil 为免安装绿色包,卸载只需删除安装目录与环境变量:

rm -rf /opt/daffodil
rm -f /etc/profile.d/daffodil.sh

若不再需要 JDK 17(系统中无其他依赖时):

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

八、常见问题

Q1:执行 daffodil 报 UnsupportedClassVersionError ... class file version 61.0?

JDK 版本过低。Daffodil 4.x 需 JDK 17,请安装 openjdk-17-jdk 并确保 JAVA_HOME 指向 JDK 17。

Q2:daffodil parse 报 defineFormat with name '{}GeneralFormat' was not found?

xs:include 路径未以 / 开头,或未使用 tns: 前缀引用(无 targetNamespace 的 DFDLGeneralFormat 被 chameleon 合并进当前 schema 命名空间)。正确写法为 schemaLocation="/org/apache/daffodil/xsd/DFDLGeneralFormat.dfdl.xsd" 且 ref="tns:GeneralFormat"。

Q3:Unable to parse xs:unsignedInt from text?

数据与 schema 字段切分不匹配(长度或字符不符)。请核对 dfdl:length 与实际数据。