CentOS 8 安装 Apache Torque 指南
在 CentOS 8 上从零安装 Apache Torque 4.0(4.x 系列最终版),覆盖 EOL 后阿里云 vault 换源、JDK 11 与 Maven 3.5.4 安装、el8 显式 JAVA_HOME 配置、Maven 插件生成 OM 类与官方 jar 手工 classpath 直跑两种方案,并跑通 Derby 内存库上的真实增删改查,命令与回显均实测通过。
CentOS 8 安装 Apache Torque 指南
目标:在 CentOS 8 上从零搭建 Apache Torque 4.0(4.x 系列最终版)的开发与运行环境(JDK 11 + Maven 3.5.4 + Derby 10.14.2.0 嵌入式数据库),处理 CentOS 8 停止维护(EOL)后的软件源迁移与 el8 显式 JAVA_HOME 两大事项,跑通「XML schema → OM 类生成 → 建表 SQL 生成 → 建库 → 增删改查」完整链路;本文全部命令与回显均已在 CentOS 8.4.2105 实测通过。
Apache Torque 是 Apache DB 项目下的对象关系映射(ORM)框架。与 Hibernate 等基于反射的主流框架不同,Torque 从手写或逆向生成的 XML schema 出发,预生成数据对象(Data Object)、Peer 门面与记录映射器等全部 Java 类,运行时直接调用生成类访问数据库,无反射开销、无运行期配置魔法。CentOS 8 已于 2021 年底停止维护,官方源下线,因此本文先解决 EOL 软件源迁移,再完成 Torque 环境搭建。
一、环境信息
本节先固定可复现的基线环境,后续所有命令均在此环境执行。列出操作系统、架构、JDK、构建工具与组件版本,便于读者对照复现。
- 操作系统:CentOS 8.4.2105(
centos:8官方基线,EOL 版本) - 架构:x86_64
- JDK:OpenJDK 11.0.13.0.8-1.el8_4(dnf 包
java-11-openjdk-devel,8.4 vault 中的最高 JDK 大版本) - 构建工具:Apache Maven 3.5.4(dnf 包
maven,Red Hat 发行版 3.5.4-5) - 组件版本:Torque 4.0(4.x 系列最终版),运行时坐标
org.apache.torque:torque-runtime:4.0 - 嵌入式数据库:Apache Derby 10.14.2.0(
org.apache.derby:derby,内存模式) - Maven 坐标:
org.apache.torque:torque-runtime:4.0、org.apache.torque:torque-maven-plugin:4.0、org.apache.torque:torque-templates:4.0 - 验证用工作目录:
/root/torque-demo(Maven 工程)、/root/jar-run(jar 直跑)
系统与版本确认(实时回显):
cat /etc/os-release | head -2
NAME="CentOS Linux"
VERSION="8 (Core)"
uname -m
x86_64
💡 说明:Torque 是库而非服务,环境中不存在需要常驻的守护进程;数据库选用 Derby 嵌入式内存模式(跟随 JVM 存活),因此「安装完成」的判定标准是跑通一个含建表与增删改查的最小程序,而不是某个端口处于监听状态。
二、前置条件
本节说明安装前必须满足的条件。CentOS 8 的最大特殊性在于:官方源已下线,必须先迁移到归档源才能安装任何软件。
- 具有 root 或 sudo 权限的 CentOS 8 系统(本文实测基线为 8.4.2105,其他 8.x 小版本需把后文源地址中的版本号一并替换)。
- 明确本机可用的归档源站点。CentOS 8 EOL 后官方归档
vault.centos.org对多数网络环境返回 403(实测Cannot download repomd.xml),本文使用阿里云归档源mirrors.aliyun.com/centos-vault/,实测直连可用。 - 可访问 Maven 中央仓库
repo1.maven.org(Torque 全部构件均托管于 Maven Central)。 - 至少 2 GB 可用磁盘空间(JDK + Maven + 依赖合计约 500 MB)。
归档源连通性确认(实时回显):
curl -sI --max-time 20 https://mirrors.aliyun.com/centos-vault/8.4.2105/BaseOS/x86_64/os/repodata/repomd.xml | head -3
HTTP/1.1 200 OK
Date: Wed, 15 Oct 2026 01:35:42 GMT
Server: nginx
三、版本选型说明
本节给出 Torque 的版本谱系与 el8 平台的 JDK 约束,帮助读者确定安装组合。以下 Torque 版本列表与发布时间均从 Maven Central 的构件目录实时核验(maven-metadata.xml 与各版本 pom 的 Last-Modified 时间):
| 版本线 | 最新版 | 发布日期(Maven Central 实测) | JDK 基线(官网声明) | 适用场景 |
|---|---|---|---|---|
| 3.x(已淘汰) | 3.3 | 2010 年前后 | Java 1.3+ | 极老项目兼容,不建议新用 |
| 4.x(本文实测) | 4.0 | 2013-02-27 | JDK 1.6+ | 经典生成式 ORM,单体 runtime,文档最多 |
| 5.x | 5.1 | 2022-01-05(5.0 为 2020-08-14) | JDK 1.8+ | 模块化改造起点 |
| 6.x | 6.0 | 2024-05-08 | JDK 11+ | 移除老旧依赖后的现代基线 |
| 7.x(当前主线) | 7.0 | 2025-07-31 | JDK 17+ | 当前 production release,最新特性 |
关于维护状态需要如实说明:Torque 4.0 发布于 2013 年 2 月,此后项目经历了 5.0(2020 年)、5.1(2022 年)、6.0(2024 年)到 7.0(2025 年 7 月 31 日)的持续演进,项目仍在活跃维护,Maven Central 上当前 release 为 7.0;但 4.x 分支自 4.0 之后未再发布补丁版本,4.x 系列的最终版就是 4.0。官网(db.apache.org/torque)当前推荐新项目使用 7.0。
本文实际采用 4.0:它是 Torque 生成式 ORM 教程与社区资料覆盖最完整的版本,运行时为单体 jar(依赖 commons-configuration 1.6、commons-dbcp 1.3 等 11 个),对 JDK 基线要求最低(官网声明 JDK 1.6+),与 el8 平台的 JDK 供给恰好匹配。实测其在 JDK 11 与 JDK 17 上全链路(生成、编译、运行)均可跑通。
el8 平台的 JDK 选型受限于归档仓库的内容,实测核验结果:8.4.2105 vault 中没有 java-17-openjdk 包(dnf list available "java-17-openjdk*" 无匹配),JDK 11 的最新补丁为 11.0.13.0.8-1.el8_4,Maven 为 3.5.4-6.el8。因此本文组合为 JDK 11 + Maven 3.5.4。若读者使用 8.5 及以上的小版本归档仓库,可自行检查是否已出现 java-17-openjdk,并相应提高 JDK 基线。
数据库适配是 4.0 的一个硬约束,实测核验结果:torque-runtime 4.0 内置适配器仅有 Mssql、Hsqldb、Mysql、Derby、Oracle、Postgres、None 七种(jar tf torque-runtime-4.0.jar | grep adapter 实测),不包含 H2 适配器;同时 SQL 生成模板包(org.apache.torque.templates.sql)支持的 DDL 方言也只有 derby、hsqldb、mssql、mysql、oracle、postgresql 六种。因此本文选用 Derby 10.14.2.0:完全嵌入、零安装,且官方模板原生支持。Derby 版本上有一个实测踩坑:10.16.1.1 的字节码是 Java 17(class file major 61),在 JDK 11 加载驱动直接抛 UnsupportedClassVersionError;10.14.2.0 是 Java 8 字节码,JDK 8/11/17 均实测可运行,故统一采用 10.14.2.0。
Maven Central 上的版本核验回显:
curl -s --max-time 30 https://repo1.maven.org/maven2/org/apache/torque/torque/maven-metadata.xml | grep -E "latest|<version>" | head -9
<latest>7.0</latest>
<release>7.0</release>
<versions>
<version>3.3</version>
<version>4.0-beta1</version>
<version>4.0</version>
<version>5.0</version>
<version>5.1</version>
<version>6.0</version>
<version>7.0</version>
</versions>
四、方案 A:Maven 依赖安装(在线,推荐)
本节面向常规 Java 项目开发,先迁移 EOL 软件源,再通过 dnf 安装 JDK 11 与 Maven,配置 el8 特有的显式 JAVA_HOME,最后用 torque-maven-plugin 生成 OM 类与建表 SQL 并跑通增删改查。
4.1 方案说明
方案 A 的链路是:配置阿里云 vault 归档源 → dnf 安装 java-11-openjdk-devel 与 maven → 显式设置 JAVA_HOME 指向 JDK 11(el8 关键步骤)→ 创建 Maven 工程,声明 torque-maven-plugin(classpath 模板包模式)与 torque-runtime、Derby 依赖 → 手写 schema 并生成 OM 类与建表 DDL → 编译运行验证程序。优点是版本由 pom 统一管控、生成与编译一体化;缺点是首次构建需要联网下载依赖。
4.2 配置 EOL 软件源(vault 换源)
CentOS 8 EOL 后,镜像内置的 mirrorlist 指向已下线的 mirror 服务。直接把 mirror.centos.org 改成 vault.centos.org 是网上最常见的做法,但实测该域名在当前网络环境返回 403:
sed -i "s/mirror.centos.org/vault.centos.org/g; s/^#.*baseurl=http/baseurl=http/g; s/^mirrorlist=http/#mirrorlist=http/g" /etc/yum.repos.d/CentOS-*.repo
dnf -q makecache 2>&1 | tail -3
CentOS Linux 8 - AppStream 62 B/s | 38 B 00:01
Errors during downloading metadata for repository 'appstream':
- Status code: 403 for https://vault.centos.org/8/AppStream/x86_64/os/repodata/repomd.xml
Error: Failed to download metadata for repo 'appstream': Cannot download repomd.xml: Cannot download repodata/repomd.xml: All mirrors were tried
实测结论:vault.centos.org 对本环境返回 403,dnf makecache 失败。改用阿里云归档源,重写 repo 文件(注意版本号 8.4.2105 与实际小版本一致):
rm -f /etc/yum.repos.d/CentOS-*.repo
cat > /etc/yum.repos.d/CentOS-Base.repo <<'EOF'
[baseos]
name=CentOS-8.4.2105 - BaseOS
baseurl=https://mirrors.aliyun.com/centos-vault/8.4.2105/BaseOS/x86_64/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1
[appstream]
name=CentOS-8.4.2105 - AppStream
baseurl=https://mirrors.aliyun.com/centos-vault/8.4.2105/AppStream/x86_64/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1
[extras]
name=CentOS-8.4.2105 - Extras
baseurl=https://mirrors.aliyun.com/centos-vault/8.4.2105/extras/x86_64/os/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
enabled=1
EOF
dnf -q makecache; echo "CACHE_EXIT=$?"
CACHE_EXIT=0
验证点:dnf makecache 返回码 0,三个仓库元数据全部拉取成功。
4.3 安装 JDK 11 与 Maven(含 el8 显式 JAVA_HOME)
查询归档仓库中可用的 JDK 与 Maven 版本(实时回显):
dnf -q list --showduplicates java-11-openjdk-devel 2>/dev/null | tail -3
dnf -q list --showduplicates maven | tail -2
Available Packages
java-11-openjdk-devel.x86_64 1:11.0.12.0.7-0.el8_4 appstream
java-11-openjdk-devel.x86_64 1:11.0.13.0.8-1.el8_4 appstream
Available Packages
maven.x86_64 3.5.4-6.el8 appstream
安装(实时回显):
dnf -q install -y java-11-openjdk-devel maven 2>&1 | tail -3
Installed:
java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64 java-11-openjdk-devel-11.0.13.0.8-1.el8_4.x86_64
java-11-openjdk-headless-11.0.13.0.8-1.el8_4.x86_64 maven-3.5.4-6.el8.noarch
el8 关键事项:安装后系统默认 java 仍指向 JDK 8。 实测 java-11-openjdk 会把 java-1.8.0-openjdk 一并装入(作为依赖),且 alternatives 默认指针指向 1.8,/usr/bin/java 是 1.8.0_312,Maven 在未显式指定 JAVA_HOME 时也绑定 1.8:
java -version
mvn -v 2>/dev/null | grep -E "Apache Maven|Java version"
openjdk version "1.8.0_312"
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Java version: 1.8.0_312, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.312.b07-1.el8_4.x86_64/jre
这就是 el8 环境必须显式设置 JAVA_HOME 的原因。先确认 JDK 11 的实际安装路径,再在 shell 配置中固定(实时回显):
ls -d /usr/lib/jvm/java-11-openjdk-*
/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64
cat >> /root/.bashrc <<'EOF'
export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64
export PATH=$JAVA_HOME/bin:$PATH
EOF
source /root/.bashrc
java -version
mvn -v 2>/dev/null | grep -E "Apache Maven|Java version"
openjdk version "11.0.13" 2026-10-19 LTS
OpenJDK Runtime Environment (build 11.0.13+8-LTS)
Apache Maven 3.5.4 (Red Hat 3.5.4-5)
Java version: 11.0.13, vendor: Red Hat, Inc., runtime: /usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64
验证点:mvn -v 的 Java version 从 1.8.0_312 变为 11.0.13,说明 Maven 已通过 JAVA_HOME 正确绑定 JDK 11。若希望系统级切换默认 java(对所有登录会话生效,含 ssh),可另行执行 alternatives --set java /usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64/bin/java,两种方式选其一即可,本文采用 JAVA_HOME 方式(对 Maven/Gradle 等构建工具最可靠)。
4.4 创建工程与 schema
建立工程目录与数据库 schema 定义。Torque 的 schema 是一份手写 XML,描述表、列、主键与外键,是整个生成流程的唯一源头:
mkdir -p /root/torque-demo/src/main/schema
mkdir -p /root/torque-demo/src/main/java/com/example/torque
mkdir -p /root/torque-demo/src/main/resources
/root/torque-demo/src/main/schema/project-schema.xml 全文(bookstore 三表示例,直接照抄):
<?xml version="1.0" encoding="UTF-8"?>
<database name="bookstore" defaultIdMethod="native">
<table name="publisher" description="Publisher table">
<column name="publisher_id" primaryKey="true" required="true" type="INTEGER" description="Primary Key"/>
<column name="name" type="VARCHAR" size="128" required="true" description="Publisher Name"/>
</table>
<table name="author" description="Author table">
<column name="author_id" primaryKey="true" required="true" type="INTEGER" description="Primary Key"/>
<column name="first_name" type="VARCHAR" size="128" required="true" description="First Name"/>
<column name="last_name" type="VARCHAR" size="128" required="true" description="Last Name"/>
</table>
<table name="book" description="Book table">
<column name="book_id" primaryKey="true" required="true" type="INTEGER" description="Primary Key"/>
<column name="isbn" required="true" type="VARCHAR" size="24" description="ISBN"/>
<column name="title" required="true" type="VARCHAR" size="255" description="Book Title"/>
<column name="author_id" required="true" type="INTEGER" description="Foreign Key Author"/>
<column name="publisher_id" required="true" type="INTEGER" description="Foreign Key Publisher"/>
<foreign-key foreignTable="author" name="book_fk_author" onDelete="cascade">
<reference local="author_id" foreign="author_id"/>
</foreign-key>
<foreign-key foreignTable="publisher" name="book_fk_publisher" onDelete="cascade">
<reference local="publisher_id" foreign="publisher_id"/>
</foreign-key>
</table>
</database>
逐项说明关键配置:
database name="bookstore":数据库逻辑名,后续torque.properties与生成配置都要引用它。defaultIdMethod="native":主键交给数据库自增机制(Derby 下生成GENERATED BY DEFAULT AS IDENTITY列),插入时无须手工赋主键。type="INTEGER"、type="VARCHAR"、size="128":Torque 的逻辑类型,由 SQL 模板按目标数据库方言翻译成物理类型。foreign-key+reference:声明 book 到 author、publisher 的外键;onDelete="cascade"生成级联删除约束。
4.5 编写 pom.xml
/root/torque-demo/pom.xml 全文(直接照抄;该 pom 同时兼容 el8 自带的 Maven 3.5.4 与更新版本):
<?xml version="1.0" encoding="UTF-8"?>
<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.torque</groupId>
<artifactId>torque-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.torque</groupId>
<artifactId>torque-runtime</artifactId>
<version>4.0</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.14.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derbytools</artifactId>
<version>10.14.2.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.torque</groupId>
<artifactId>torque-maven-plugin</artifactId>
<version>4.0</version>
<dependencies>
<dependency>
<groupId>org.apache.torque</groupId>
<artifactId>torque-templates</artifactId>
<version>4.0</version>
</dependency>
</dependencies>
<configuration>
<packaging>classpath</packaging>
<configPackage>org.apache.torque.templates.om</configPackage>
<sourceDir>src/main/schema</sourceDir>
<options>
<torque.om.package>com.example.torque.om</torque.om.package>
</options>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>add-torque-sources</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-sources</source>
<source>src/main/generated-java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>sql</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.torque</groupId>
<artifactId>torque-maven-plugin</artifactId>
<version>4.0</version>
<dependencies>
<dependency>
<groupId>org.apache.torque</groupId>
<artifactId>torque-templates</artifactId>
<version>4.0</version>
</dependency>
</dependencies>
<configuration>
<packaging>classpath</packaging>
<configPackage>org.apache.torque.templates.sql</configPackage>
<sourceDir>src/main/schema</sourceDir>
<options>
<torque.database>derby</torque.database>
<torque.sql.generate.drops>true</torque.sql.generate.drops>
</options>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
逐项说明关键配置:
torque-runtime:4.0:运行期唯一 Torque 依赖,Maven 自动解析其传递依赖(commons-configuration 1.6、commons-dbcp 1.3、jcs 1.3、avalon-framework-api 4.3.1 等,共 11 个)。derby:10.14.2.0+derbytools:10.14.2.0:嵌入式数据库驱动(版本选型理由见第三章)。- 插件
packaging=classpath+configPackage=org.apache.torque.templates.om:直接以 classpath 上的模板包为生成配置(OM 生成模板自带 control 文件与全部模板),无须在工程里手写任何 control.xml 或模板;这是 torque-maven-plugin 4.0 最省事的用法。 sourceDir=src/main/schema:schema 源文件目录。不设置时插件默认找src/main/torque-gen/src(实测报Could not list files in the following Directory ... torque-gen/src),必须显式指向 schema 目录。torque.om.package:生成类的 Java 包名,模板包强制要求该选项,缺失时实测报Option torque.om.package must be set。maven.compiler.source/target=8:4.0 生成代码与运行时的字节码基线,JDK 11 按此目标编译,Maven 3.5.4 默认绑定的 compiler 插件完全支持。build-helper-maven-plugin:torque-maven-plugin 不会把生成目录注册为编译源目录(实测mvn compile直接报No sources to compile),必须用该插件把target/generated-sources(基类)与src/main/generated-java(可编辑类)加入编译范围。sqlprofile:同一个插件换用org.apache.torque.templates.sql模板包生成建表 DDL;torque.database=derby指定方言(该选项同样强制,缺失时报Option torque.database must be set)。
4.6 生成 OM 类与建表 SQL
生成 OM 类(实时回显):
cd /root/torque-demo && mvn -B torque:generate
[INFO] --- torque-maven-plugin:4.0:generate (default-cli) @ torque-demo ---
[INFO] Generation successful
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] Total time: 2.914 s
查看生成结果(实测共 24 个 Java 文件:target/generated-sources 下 12 个 Base* 基类 + src/main/generated-java 下 12 个可编辑业务类):
find target/generated-sources src/main/generated-java -name "*.java" | wc -l
ls src/main/generated-java/com/example/torque/om/
24
Author.java AuthorPeer.java AuthorPeerImpl.java AuthorRecordMapper.java
Book.java BookPeer.java BookPeerImpl.java BookRecordMapper.java
Publisher.java PublisherPeer.java PublisherPeerImpl.java PublisherRecordMapper.java
Torque 4.0 的生成物按「两层目录」组织:target/generated-sources 下的 Base* 类每次生成重新覆盖,承载全部标准逻辑;src/main/generated-java 下的无前缀业务类仅首次生成,之后模板以 skip 策略跳过,专门留给用户改写定制。重新执行 mvn torque:generate 不会覆盖用户对业务类的修改,这是 Torque 生成式 ORM 的核心定制机制。
生成建表 SQL 并复制到资源目录(实时回显):
cd /root/torque-demo && mvn -B -q torque:generate -Psql 2>&1 | grep -E "Start generation" | head -2
cp target/generated-sources/project-schema.sql src/main/resources/schema.sql
INFO org.apache.torque.generator.control.Controller - Processing output torque.sql.ddl
INFO org.apache.torque.generator.control.Controller - Start generation of File /root/torque-demo/target/generated-sources/project-schema.sql
生成的 schema.sql 核心内容(实测):
drop table publisher;
drop table author;
drop table book;
CREATE TABLE publisher
(
publisher_id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY,
name VARCHAR(128) NOT NULL,
PRIMARY KEY(publisher_id));
CREATE TABLE author
(
author_id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY,
first_name VARCHAR(128) NOT NULL,
last_name VARCHAR(128) NOT NULL,
PRIMARY KEY(author_id));
CREATE TABLE book
(
book_id INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY,
isbn VARCHAR(24) NOT NULL,
title VARCHAR(255) NOT NULL,
author_id INTEGER NOT NULL,
publisher_id INTEGER NOT NULL,
PRIMARY KEY(book_id));
ALTER TABLE book
ADD CONSTRAINT book_fk_author
FOREIGN KEY (author_id)
REFERENCES author (author_id)
ON DELETE CASCADE;
ALTER TABLE book
ADD CONSTRAINT book_fk_publisher
FOREIGN KEY (publisher_id)
REFERENCES publisher (publisher_id)
ON DELETE CASCADE;
验证点:defaultIdMethod="native" 如约生成 GENERATED BY DEFAULT AS IDENTITY 自增列;两条 ADD CONSTRAINT 外键带 ON DELETE CASCADE 级联删除。
4.7 编写验证程序并编译运行
验证程序与运行时配置与平台无关:Main.java 与 torque.properties 的全文见《Ubuntu 22.04 安装 Apache Torque 指南》4.7 节,文件路径为 /root/torque-demo/src/main/java/com/example/torque/Main.java 与 /root/torque-demo/src/main/resources/torque.properties,内容一字不差照抄即可。其中两处与本平台直接相关的要点:其一,Class.forName("org.apache.derby.jdbc.EmbeddedDriver") 显式注册驱动的语句在本平台(JDK 11)必须保留,实测 Derby 10.14.2.0 的 JDBC SPI 声明在 JDK 11 不会被自动加载(JDK 17 会),不注册则报 No suitable driver found;其二,torque.properties 的数据源工厂键名为 4.0 新式的 torque.dsfactory.bookstore.factory(写 3.x 的 .factory.class 实测报 No DataSourceFactory definition for default DB found),连接口令示例为 q1w2e3r4。
在 CentOS 上编译并运行(注意最后一行的 -Dfile.encoding=UTF-8 为本平台必需项,原因见本节末尾实测对比):
cd /root/torque-demo && mvn -B -q compile && echo "EXIT=$?"
mvn -B -q dependency:build-classpath -Dmdep.outputFile=/tmp/cp.txt
java -Dfile.encoding=UTF-8 -cp "target/classes:$(cat /tmp/cp.txt)" com.example.torque.Main
---- [1] Torque.init ----
Torque.init 完成, 默认数据库=bookstore, 数据库注册表键=[bookstore, default]
---- [2] 执行生成的 DDL 建表 ----
执行 CREATE/ALTER 语句数=5 (3 张表 + 2 个外键)
---- [3] 新增 (save / 主键自动生成) ----
Publisher 落库: name=人民文学出版社 主键=1
Author 落库: 罗贯中 主键=1
Book 落库: 三国演义 主键=1 author_id=1 publisher_id=1
---- [4] 查询 (Criteria + Peer.doSelect) ----
doSelect 命中: id=1 姓名=罗贯中
doSelectJoinAuthor: 《三国演义》 作者=罗贯中
---- [5] 更新 (save / retrieveByPK) ----
retrieveByPK(1) 标题=三国演义(校注本) ISBN=9787020008728
---- [6] 删除 (doDelete) ----
删除 book_id=1 后, 剩余 Book 行数=0, Author 行数=1 (外键只级联删 book, 作者保留)
---- 全部步骤通过 ----
结果解读:六组演示全部按预期输出——Torque.init 识别 bookstore 数据源;生成的 DDL 成功建出 3 张表与 2 个外键;三次 save() 主键由 IDENTITY 自动分配(均为 1);条件查询与联表查询正确命中;更新后 retrieveByPK 回读一致;删除 book 后 Author 保留(级联只作用于 book 的外键)。这表示 Torque 4.0 生成器与运行时已在 CentOS 8 的 JDK 11 上完整可用。
-Dfile.encoding=UTF-8 在 el8 默认 locale(POSIX,即 ANSI_X3.4-1968)下是硬需求。本平台的实测对比——不加参数时:
doSelectJoinAuthor: ?????? ??=???
---- [5] ?? (save / retrieveByPK) ----
retrieveByPK(1) ??=????(???) ISBN=9787020008728
加上参数后(见上面完整回显)中文全部正常。除了运行时参数,也可以一次性设置系统 locale(export LANG=C.UTF-8)后省略该参数。
五、方案 B:官方 jar 直用(离线友好)
本节面向没有 Maven/构建体系的场景,从 Maven Central 直接下载 torque-runtime 与其全部依赖 jar,用 javac + java 完成编译运行,不依赖任何构建工具。
5.1 方案说明
链路是:下载 14 个运行期 jar 并校验 sha1 → 复用方案 A 已生成的 24 个 OM 源文件(生成物与构建工具无关,任何方式产出的源码都能编译)→ javac -cp 编译 → java -cp 运行。适用于离线环境、脚本化部署或纯粹想「拿到 jar 就能用」的读者。
5.2 下载依赖 jar 与完整性校验
torque-runtime 4.0 的完整运行期依赖经 mvn dependency:list 实测为 14 个 jar(含 Derby 驱动)。逐一下载(命令较长,分两条列出,全部实测):
mkdir -p /root/jar-run/lib && cd /root/jar-run/lib
R=https://repo1.maven.org/maven2
curl -sfO $R/org/apache/torque/torque-runtime/4.0/torque-runtime-4.0.jar
curl -sfO $R/commons-beanutils/commons-beanutils-core/1.8.0/commons-beanutils-core-1.8.0.jar
curl -sfO $R/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar
curl -sfO $R/commons-configuration/commons-configuration/1.6/commons-configuration-1.6.jar
curl -sfO $R/commons-dbcp/commons-dbcp/1.3/commons-dbcp-1.3.jar
curl -sfO $R/commons-digester/commons-digester/1.8/commons-digester-1.8.jar
curl -sfO $R/commons-lang/commons-lang/2.6/commons-lang-2.6.jar
curl -sfO $R/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar
curl -sfO $R/commons-pool/commons-pool/1.5.6/commons-pool-1.5.6.jar
curl -sfO $R/concurrent/concurrent/1.0/concurrent-1.0.jar
curl -sfO $R/org/apache/avalon/framework/avalon-framework-api/4.3.1/avalon-framework-api-4.3.1.jar
curl -sfO $R/org/apache/jcs/jcs/1.3/jcs-1.3.jar
curl -sfO $R/org/apache/derby/derby/10.14.2.0/derby-10.14.2.0.jar
curl -sfO $R/org/apache/derby/derbytools/10.14.2.0/derbytools-10.14.2.0.jar
ls -1 | wc -l
14
校验两个核心 jar 的 sha1(期望值取自仓库同名 .sha1 文件,与实测值必须逐字一致):
cd /root/jar-run/lib
echo "runtime 期望: $(curl -s $R/org/apache/torque/torque-runtime/4.0/torque-runtime-4.0.jar.sha1)"
echo "runtime 实测: $(sha1sum torque-runtime-4.0.jar | cut -d' ' -f1)"
echo "derby 期望: $(curl -s $R/org/apache/derby/derby/10.14.2.0/derby-10.14.2.0.jar.sha1)"
echo "derby 实测: $(sha1sum derby-10.14.2.0.jar | cut -d' ' -f1)"
runtime 期望: 88a2be8e73374586c480516fc085b2f8fea12968
runtime 实测: 88a2be8e73374586c480516fc085b2f8fea12968
derby 期望: 7efad40ef52fbb1f08142f07a83b42d29e47d8ce
derby 实测: 7efad40ef52fbb1f08142f07a83b42d29e47d8ce
两个核心 jar 的实测大小:torque-runtime-4.0.jar 为 228845 字节,derby-10.14.2.0.jar 为 3232770 字节,14 个 jar 合计约 6.4 MB。
⚠️ 注意:jar 清单必须与 pom 解析结果一致。缺 jar 运行时报
NoClassDefFoundError;多 jar 无害。若不放心清单完整性,可在方案 A 的工程上执行mvn dependency:list逐一比对。
5.3 javac 编译与 java 运行
准备源码与资源(OM 生成物 + 验证程序 + 配置):
cd /root/jar-run
mkdir -p src-om src-om-mod res out
cp -r /root/torque-demo/target/generated-sources/com src-om/
cp -r /root/torque-demo/src/main/generated-java/com src-om-mod/
cp /root/torque-demo/src/main/resources/torque.properties /root/torque-demo/src/main/resources/schema.sql res/
编译(24 个 OM 类 + Main,共 25 个编译单元):
javac -encoding UTF-8 -cp "lib/*" -d out \
src-om/com/example/torque/om/*.java \
src-om-mod/com/example/torque/om/*.java \
/root/torque-demo/src/main/java/com/example/torque/Main.java
# 输出节选(实测)
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
15 warnings
验证点:编译成功产出 25 个 class;15 个警告全部是 new Integer(int) 构造器在 JDK 9+ 标记 deprecation 所致(2013 年生成代码的正常现象),不影响运行。
运行(注意 classpath 必须包含 res 目录,否则读不到 torque.properties 实测报 NullPointerException: inStream parameter is null;-Dfile.encoding=UTF-8 的原因见 4.7 节实测对比):
java -Dfile.encoding=UTF-8 -cp "out:res:lib/*" com.example.torque.Main
---- [1] Torque.init ----
Torque.init 完成, 默认数据库=bookstore, 数据库注册表键=[bookstore, default]
---- [2] 执行生成的 DDL 建表 ----
执行 CREATE/ALTER 语句数=5 (3 张表 + 2 个外键)
---- [3] 新增 (save / 主键自动生成) ----
Publisher 落库: name=人民文学出版社 主键=1
Author 落库: 罗贯中 主键=1
Book 落库: 三国演义 主键=1 author_id=1 publisher_id=1
---- [4] 查询 (Criteria + Peer.doSelect) ----
doSelect 命中: id=1 姓名=罗贯中
doSelectJoinAuthor: 《三国演义》 作者=罗贯中
---- [5] 更新 (save / retrieveByPK) ----
retrieveByPK(1) 标题=三国演义(校注本) ISBN=9787020008728
---- [6] 删除 (doDelete) ----
删除 book_id=1 后, 剩余 Book 行数=0, Author 行数=1 (外键只级联删 book, 作者保留)
---- 全部步骤通过 ----
验证点:java -cp 一行成功跑完六组结果,且无 NoClassDefFoundError,说明手工 classpath 可用;结果与方案 A 完全一致。
5.4 torque-generator 独立分发包的定位说明
Maven Central 的 org.apache.torque:torque-generator:4.0 另有 bin 分发包(torque-generator-4.0-bin.tar.gz,实测 4822484 字节),解压后为 torque-generator 主 jar 与 8 个依赖 jar。需要说明的是,4.0 版该包内没有命令行启动脚本,主 jar 的 MANIFEST 也没有 Main-Class(实测 jar tf 与 MANIFEST 核验),它面向 Ant 任务或自定义程序内嵌调用。想在无 Maven 环境做 OM 生成,本文 5.3 节的「预生成源码 + javac」方式即为可落地的替代路径;需要纯命令行生成的读者可评估 5.x 及以上版本的 generator 分发包。
六、方案对比与选择建议
本节汇总两种方案的差异,给出选型建议。两种方案运行的是同一份 Torque 4.0 代码与同一批生成类,差别仅在获取与装配方式。
| 维度 | 方案 A:Maven 插件 | 方案 B:jar 直用 |
|---|---|---|
| OM 类生成 | mvn torque:generate 一键生成 | 依赖方案 A 产出的源码(generator 4.0 无 CLI) |
| 运行期依赖 | Maven 自动解析 14 个 jar | 手工下载 14 个 jar 并拼 classpath |
| 是否联网 | 首次构建需联网 | 仅下载时需要联网 |
| 依赖版本管控 | pom 统一声明,可锁版本 | 无,靠文件命名区分 |
| 完整性校验 | Maven 自动校验 | 需手工比对 sha1 |
| 适用场景 | 常规工程开发 | 离线脚本、临时验证、无构建体系 |
选型建议:只要工程有构建体系,一律选方案 A——OM 生成是 Torque 的核心工作流,离开 Maven 插件(或 Ant 任务)无法完成;方案 B 的价值在于运行期部署:用方案 A 生成并提交源码后,运行环境完全可以无构建工具。两者也可共存——用方案 A 开发生成,用方案 B 分发运行。CentOS 平台的额外提示:方案 B 对 JDK 版本不敏感(只要能跑 torque-runtime 4.0 的 JDK 1.6+ 基线),比方案 A 更适合随应用分发的部署包。
七、配置说明
本节汇总 Torque 4.0 与 el8 平台实际需要设置的「配置」,分平台环境配置、生成期配置与运行期配置三组,全部实测核验。
7.1 平台环境配置(JAVA_HOME 与 locale)
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.13.0.8-1.el8_4.x86_64:el8 的系统默认 java 是 1.8.0_312(实测 4.3 节),Maven、javac 等工具链全部依赖该变量选对 JDK,必须写入/root/.bashrc或等价的会话配置。LANG=C.UTF-8(可选):一次性解决中文编码问题;不设置则所有java命令都要带-Dfile.encoding=UTF-8(实测 4.7 节对比)。
7.2 Maven 插件(生成期)配置
packaging=classpath:生成配置的来源模式。classpath 模式从 classpath 上的模板包读取全部配置;默认值directory模式则要求工程提供src/main/torque-gen/conf/control.xml(实测缺文件报control file file /root/torque-demo/src/main/torque-gen/conf/control.xml not found)。快速上手选 classpath 模式。configPackage=org.apache.torque.templates.om:OM 生成模板包。换org.apache.torque.templates.sql即生成 DDL(本文 sql profile)。sourceDir=src/main/schema:schema 文件目录,默认值src/main/torque-gen/src(实测目录不存在时直接报错)。options.torque.om.package:生成类包名,必填。- 生成输出目录:基类固定写
target/generated-sources,可编辑类固定写src/main/generated-java,两者均由插件默认值决定,一般无需调整。
7.3 torque.properties(运行期)配置
torque.database.default=bookstore
torque.database.bookstore.adapter=derby
torque.dsfactory.bookstore.factory=org.apache.torque.dsfactory.SharedPoolDataSourceFactory
torque.dsfactory.bookstore.connection.url=jdbc:derby:memory:bookstore;create=true
torque.dsfactory.bookstore.connection.user=sa
torque.dsfactory.bookstore.connection.password=q1w2e3r4
逐项说明:
torque.database.default:默认数据库逻辑名,Torque.getDefaultDB()返回它,多库场景下每个库各有一组同名键。adapter:数据库适配器,决定 ID 生成、SQL 方言等行为,可选值实测核验为 mssql/hsqldb/mysql/derby/oracle/postgres/none。dsfactory.<库名>.factory:数据源工厂实现,SharedPoolDataSourceFactory提供 DBCP 连接池。注意 4.0 的键名到此为止,没有 3.x 时代的.class后缀。connection.url/user/password:直通连接池的 JDBC 三要素。connection.*下其他属性(如driver)会被 DBCP 拒绝(实测报Property: driver ... is not supported by DataSource: DriverAdapterCPDS),驱动注册改在代码里显式Class.forName完成。torque.dsfactory.bookstore.pool.*:连接池参数(如最大连接数),本文未配置时使用默认值,日常开发够用。
八、多版本管理
Torque 各大版本 artifact 坐标相同、JDK 基线不同,多版本共存靠「隔离依赖坐标 + 隔离 jar 文件名」实现。
Maven 本地仓库中不同版本的构件并列存放,互不覆盖(实时回显):
ls -1 $HOME/.m2/repository/org/apache/torque/torque-runtime/
4.0
5.1
7.0
要点:工程要用哪个版本,只改 pom.xml 的 <dependency><version> 即可,其余版本留在本地仓库供其他工程复用。但注意跨大版本切换不是改数字那么简单:5.x 起运行时拆分为多模块、6.0/7.0 抬高 JDK 基线、部分配置键有变化,切换前应查阅对应版本官网。jar 直跑场景,把不同版本 jar 分目录存放(如 /root/jar-run-7/lib),运行时按需拼 classpath。
切换工程依赖版本并验证生效(实时回显):
cd /root/torque-demo && mvn -B dependency:tree 2>&1 | grep torque | head -5
[INFO] +- org.apache.torque:torque-runtime:jar:4.0:compile
[INFO] | +- commons-collections:commons-collections:jar:3.2.1:compile
[INFO] | +- commons-configuration:commons-configuration:jar:1.6:compile
[INFO] | +- commons-dbcp:commons-dbcp:jar:1.3:compile
[INFO] | +- commons-lang:commons-lang:jar:2.6:compile
验证点:依赖树顶层是 torque-runtime:4.0,其下为核心传递依赖,与手工下载清单一致。
九、常见问题(FAQ)
Q1:dnf makecache 报 Status code: 403 for https://vault.centos.org/.../repomd.xml 怎么办?
CentOS 8 EOL 后官方归档域名对多数网络环境返回 403(实测复现)。解决办法是把 repo 的 baseurl 指向可用的归档镜像(本文使用 mirrors.aliyun.com/centos-vault/8.4.2105/,见 4.2 节),注意 URL 中的小版本号必须与本机 /etc/os-release 对应的版本一致。
Q2:装完 java-11-openjdk-devel 后 java -version 还是显示 1.8.0_312?
el8 会把 java-1.8.0-openjdk 作为依赖一并装入,且 alternatives 默认指针指向 1.8(实测 4.3 节回显)。解决:在 shell 配置中显式 export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-<版本号>.x86_64 并把 $JAVA_HOME/bin 加到 PATH 前面;需要全系统生效可另用 alternatives --set java ...。未显式设置时 Maven 也绑定 1.8(实测 mvn -v 显示 Java version: 1.8.0_312)。
Q3:程序中文输出全变成 ??????
el8 默认 locale 为 POSIX(ANSI_X3.4-1968),JVM 以 ASCII 输出字符串。解决:运行时加 -Dfile.encoding=UTF-8,或 export LANG=C.UTF-8(4.7 节有加与不加的实测对比回显)。
Q4:mvn torque:generate 报 control file file .../src/main/torque-gen/conf/control.xml not found?
插件默认 packaging=directory,要求工程自备 control.xml。快速上手直接在插件配置里写 <packaging>classpath</packaging> 与 <configPackage>org.apache.torque.templates.om</configPackage>,用官方模板包自带的生成配置(见 4.5 节),无需手写任何 control 文件。
Q5:报 Option torque.om.package must be set 或 Could not list files in the following Directory ... torque-gen/src?
前者:OM 模板包要求显式指定生成类包名,在插件 <configuration> 里加 <options><torque.om.package>你的包名</torque.om.package></options>。后者:classpath 模式下插件不会自动用 src/main/schema,必须显式 <sourceDir>src/main/schema</sourceDir>(均见 4.5 节)。
Q6:运行报 No suitable driver found for jdbc:derby:...?
Torque 4.0 + commons-dbcp 1.3 的组合无法从 torque.properties 注入驱动类名(connection.driver/connection.driverClassName 均被拒绝),Derby 驱动又未必被 JDBC SPI 自动加载(实测 JDK 11 不会、JDK 17 会)。通用解法:在 Torque.init() 之前执行 Class.forName("org.apache.derby.jdbc.EmbeddedDriver")。
Q7:报 UnsupportedClassVersionError: org/apache/derby/jdbc/EmbeddedDriver has been compiled by a more recent version (class file version 61.0)?
用了 Derby 10.16.1.1——它是 Java 17 字节码,JDK 11 及以下无法加载(本文第三章实测踩坑)。把 Derby 降到 10.14.2.0(Java 8 字节码,JDK 8/11/17 全兼容)即可。
Q8:mvn compile 显示 BUILD SUCCESS 但类都编译不到,或运行报 ClassNotFoundException?
torque-maven-plugin 不会把生成目录注册为编译源目录。确认 pom 已配置 build-helper-maven-plugin 并把 target/generated-sources 与 src/main/generated-java 加入 <sources>(见 4.5 节);只注册 target/generated-sources 时,Base* 类能编过而 Author 等业务类报 cannot find symbol。
十、卸载与清理
Torque 本身不产生系统级安装,卸载即移除依赖与本地文件。
移除工程与本地 jar(清理本文全部产物):
rm -rf /root/torque-demo /root/jar-run
ls /root/torque-demo 2>&1
ls: cannot access '/root/torque-demo': No such file or directory
移除 Maven 本地仓库中的 Torque 构件(影响所有工程,慎用):
rm -rf $HOME/.m2/repository/org/apache/torque
卸载 JDK 与 Maven(仅当不再需要)。先以 -s 预演确认将删除的包,无误后去掉 -s 真正执行:
dnf -s remove java-11-openjdk-devel maven
# 输出节选(实测)
Dependencies resolved.
=============================================================================================================================
Package Architecture Version Repository Size
=============================================================================================================================
Removing:
java-11-openjdk-devel x86_64 1:11.0.13.0.8-1.el8_4 @appstream 49 M
maven noarch 3.5.4-6.el8 @appstream 9.3 M
Transaction Summary
=============================================================================================================================
Remove 2 Packages
确认无误后真正卸载:
dnf remove -y java-11-openjdk-devel maven
恢复软件源(如需退回 EOL 前状态已不可能,保留阿里云 vault 源即可;若机器其他软件依赖 java 8,无需任何动作,alternatives 默认仍指向 1.8)。
十一、参考链接
- Apache Torque 官方主页:https://db.apache.org/torque/
- Torque 版本与 JDK 基线官方说明(官网首页):https://db.apache.org/torque/
- Maven 中央仓库 torque-runtime 坐标页:https://repo1.maven.org/maven2/org/apache/torque/torque-runtime/
- Maven 中央仓库 torque-maven-plugin 坐标页:https://repo1.maven.org/maven2/org/apache/torque/torque-maven-plugin/
- Maven 中央仓库 torque-generator 坐标页(含 4.0 bin 分发包):https://repo1.maven.org/maven2/org/apache/torque/torque-generator/
- 阿里云 CentOS 归档源(centos-vault):https://mirrors.aliyun.com/centos-vault/
- Apache Derby 官方站点:https://db.apache.org/derby/