Apache Texen 介绍与选型指南
Apache Texen 是 Velocity 体系下基于 Ant 的多文件文本生成框架,本文给出其架构、功能、2007 年后的维护现状与同类选型对比,全部结论在 Ubuntu 22.04 实测验证。
Apache Texen 介绍与选型指南
目标:说清 Apache Texen 是什么、架构如何、能做什么、维护现状与选型建议,帮助读者判断是否应在新项目中采用它。文中版本结论、依赖兼容性、运行行为均已在 Ubuntu 22.04(JDK 17 + Ant 1.10.12)环境逐项实测通过。
一、环境信息
本文所有结论基于以下真实环境实测得出:
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- JDK:OpenJDK 17.0.20.1(apt 安装 openjdk-17-jdk)
- 构建工具:Apache Ant 1.10.12(apt 安装 ant)
- 下载工具:GNU Wget 1.21.2
- 主角组件:Apache Texen 1.0(
org.apache.texen:texen:1.0,jar 仅 17159 字节) - 模板引擎搭配:Velocity 1.7(推荐)与 Velocity Engine 2.4.1(兼容性对照,均已实测)
版本核验回显(实测):
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)
ant -version
Apache Ant(TM) version 1.10.12 compiled on January 17 1970
从 Maven Central 检索 Texen 坐标(实测):
curl -s "https://search.maven.org/solrsearch/select?q=g:%22org.apache.texen%22+AND+a:%22texen%22&rows=5&wt=json"
{"responseHeader":{"status":0,"QTime":1,"params":{"q":"g:\"org.apache.texen\" AND a:\"texen\"","core":"","indent":"off","spellcheck":"true","fl":"id,g,a,latestVersion,p,ec,repositoryId,text,timestamp,versionCount","start":"","spellcheck.count":"5","sort":"score desc,timestamp desc,g asc,a asc","rows":"5","wt":"json","version":"2.2"}},"response":{"numFound":1,"start":0,"docs":[{"id":"org.apache.texen:texen","g":"org.apache.texen","a":"texen","latestVersion":"1.0","repositoryId":"central","p":"jar","timestamp":1177841709000,"versionCount":1,"text":["org.apache.texen","texen",".jar",".pom"],"ec":[".jar",".pom"]}]},"spellcheck":{"suggestions":[]}}
关键信息解读:numFound:1、latestVersion:"1.0"、versionCount:1 说明 Texen 自始至终只有一个版本 1.0;timestamp:1177841709000 对应 2007-04-29,即该版本发布于 2007 年。
二、软件概述
2.1 Texen 是什么
Apache Texen 是 Apache Velocity 子项目下的一个通用文本生成工具:它以 Ant 任务(TexenTask)为入口,用一个「控制模板」驱动任意多个「工人模板」渲染,把结果批量写成文件。简单说,它是"用模板批量产出文本文件"的生成器——生成什么内容、生成多少个文件、写到哪,全部由模板自己决定,因此既能生成 HTML 页面,也能生成 Java 源码、SQL 脚本、配置文件等任意文本。
它的经典战功是支撑 Apache Torque(Turbine 项目的 SQL/ORM 组件)批量生成数据库访问代码。官网 https://velocity.apache.org/texen/1.0/ 页脚显示 Last Published: 2007-06-24,与 Central 时间戳相互印证。
💡 技术拓展:文中的「模板引擎」指把模板(带占位符的文本)与数据上下文合并渲染成最终文本的组件。Java 生态常见模板引擎对比——
模板引擎 语法风格 特点 典型场景 Velocity $obj/#foreach简单直观、历史悠久 代码生成、邮件、页面 FreeMarker ${obj}/<#list>内建函数丰富、校验严格 报表、代码生成 Thymeleaf 原生 HTML 属性 可直接浏览器预览 Spring Boot Web 页面 Mustache {{obj}}逻辑无关(logic-less) 跨语言轻量渲染 Groovy Templates GString 内嵌 与 Groovy 语言融合 JVM 脚本化生成 Texen 内部固定使用 Velocity 作为渲染引擎(默认搭配 Velocity 1.7,本文实测环境亦如此),不提供引擎替换选项;只想"裸用"Velocity 而不需要 Ant 驱动的多文件编排,可直接使用 Velocity Engine 本身(见《Apache Velocity 快速入门与集成示例》)。
2.2 一个极小的 jar
Texen 1.0 的 jar 只有 17159 字节。先下载再用 jar tf 查看包结构:
wget https://repo1.maven.org/maven2/org/apache/texen/texen/1.0/texen-1.0.jar
jar tf texen-1.0.jar
输出节选(wget 进度略;jar 内清单实测如下):
META-INF/
META-INF/MANIFEST.MF
META-INF/LICENSE
META-INF/NOTICE
org/
org/apache/
org/apache/texen/
org/apache/texen/ant/
org/apache/texen/defaults/
org/apache/texen/util/
org/apache/texen/Generator.class
org/apache/texen/ant/TexenTask.class
org/apache/texen/defaults/texen.properties
org/apache/texen/util/FileUtil.class
org/apache/texen/util/PropertiesUtil.class
jar 内只有 4 个类与 1 个默认配置文件:入口任务 ant.TexenTask、核心引擎 Generator、工具类 util.FileUtil 与 util.PropertiesUtil。字节码 major version 为 46(Java 1.2 时代编译,实测 javap -verbose 输出 major version: 46),在任何现代 JDK 上都能直接加载运行——本文即在 JDK 17 上完整跑通全部示例。
2.3 维护现状(如实披露)
选型前必须知道的事实:
- 2007 年之后没有新版本:Central 上
versionCount:1,最新即 1.0,无任何后续修复版。 - 官网仅保留 1.0 一套文档,未发布 Texen 2.x 路线图。
- 项目未进 Apache Attic(未宣布退役),页面仍挂在 velocity.apache.org/texen 下,但实质处于休眠状态。
- 缺陷跟踪:Apache JIRA 中保留 TEXEN 项目,可查历史 issue,但无活跃处理。
结论:Texen 是一个"功能稳定但已停止演进"的工具。它能在 JDK 17 上正常工作(本文实测),但使用它意味着接受"无新版本、无官方补丁"的现状。老项目维护、离线脚手架生成等场景它依然可靠;新项目选型请先读「六、同类选型对比」。
三、核心架构
3.1 分层结构
Texen 的工作链路自上而下分四层:
| 层 | 组件 | 职责 |
|---|---|---|
| 构建入口 | Apache Ant | 执行 build.xml,把 <texen> 任务注册并触发 |
| 任务层 | org.apache.texen.ant.TexenTask | 收集 11 个属性(模板路径、输出目录、编码等),装配 Generator 并执行 |
| 引擎层 | org.apache.texen.Generator | 管理 Velocity 引擎实例、上下文、输出 Writer,逐模板渲染写文件 |
| 渲染层 | Velocity Engine | 解析 .vm 模板,合并上下文数据生成最终文本 |
TexenTask 的公开方法一览(javap 实测,即它对 build.xml 暴露的全部属性):
javap -classpath lib/texen-1.0.jar org.apache.texen.ant.TexenTask
public class org.apache.texen.ant.TexenTask extends org.apache.tools.ant.Task {
public org.apache.texen.ant.TexenTask();
public void setControlTemplate(java.lang.String);
public java.lang.String getControlTemplate();
public void setTemplatePath(java.lang.String) throws java.lang.Exception;
public java.lang.String getTemplatePath();
public void setOutputDirectory(java.io.File);
public java.lang.String getOutputDirectory();
public void setOutputFile(java.lang.String);
public void setOutputEncoding(java.lang.String);
public void setInputEncoding(java.lang.String);
public java.lang.String getOutputFile();
public void setLogFile(java.lang.String);
public java.lang.String getLogFile();
public void setContextProperties(java.lang.String);
public org.apache.commons.collections.ExtendedProperties getContextProperties();
public void setUseClasspath(boolean);
public void setUseResourceLoaderCache(java.lang.String);
public void setResourceLoaderModificationCheckInterval(java.lang.String);
public org.apache.velocity.context.Context initControlContext() throws java.lang.Exception;
public void execute() throws org.apache.tools.ant.BuildException;
}
这 11 个 setter 对应 TexenTask 的 11 个可配置属性,逐项实测行为见《Apache Texen 常用 CLI 命令与工具详解》。
3.2 控制模板与工人模板
Texen 采用两层模板模型:
- 控制模板(control template):一次生成只有一个入口。它负责编排:决定循环几次、每个文件叫什么名字、调用哪个工人模板。控制模板自身的渲染结果会写入
outputFile指定的报告文件(默认行为,实测有效)。 - 工人模板(worker template):由控制模板通过
$generator.parse调用,每次调用渲染一个输出文件。
$generator.parse 最常用的四参数形态(实测语法):
$generator.parse("HtmlTemplate.vm", $outputFile, "planet", $planet)
四个参数依次是:工人模板名、输出文件名、注入上下文的变量名、注入的变量值。这样工人模板内部就能通过 $planet 访问到传入的数据。
💡 技术拓展:「模板路径解析」决定了 Texen 从哪里找
.vm文件,由useClasspath属性切换两种资源加载方式——
加载方式 触发条件 模板查找位置 适用场景 文件系统加载 默认( useClasspath=false)templatePath指定的磁盘目录模板在工程目录下,改了立即生效 classpath 加载 useClasspath=trueAnt 类路径(模板目录需加入 taskdef 的 classpath) 模板打进 jar 包统一分发 本文实测环境两种方式均跑通:默认方式用
templatePath="templates";classpath 方式在<path>中追加<pathelement location="templates"/>。
3.3 预置上下文对象
渲染模板时,Generator 会向 Velocity 上下文注入一组预置对象,模板里直接可用:
| 上下文变量 | 类型/来源 | 用途 |
|---|---|---|
$generator | org.apache.texen.Generator | 调用 parse() 生成工人模板文件 |
$strings | org.apache.velocity.util.StringUtils | 字符串工具(包名转换、驼峰化、拼接等) |
$files | org.apache.texen.util.FileUtil | 文件工具(实测用得最多的是 mkdir()) |
$properties | org.apache.texen.util.PropertiesUtil | 属性文件工具 |
$now | java.util.Date | 生成时间戳(实测产物中常用于记录生成时刻) |
$outputDirectory | java.io.File | 当前输出目录 |
这些映射来自 jar 内默认配置 org/apache/texen/defaults/texen.properties,内容实测如下:
cd /tmp && mkdir -p texen-x && cd texen-x && jar xf /root/texen-demo/lib/texen-1.0.jar org/apache/texen/defaults/texen.properties && cat org/apache/texen/defaults/texen.properties
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
path.output=output
context.objects.strings=org.apache.velocity.util.StringUtils
context.objects.files=org.apache.texen.util.FileUtil
context.objects.properties=org.apache.texen.util.PropertiesUtil
后三行 context.objects.* 正是 $strings/$files/$properties 的来源;path.output=output 是输出目录的默认值。
四、功能特性
以下特性均在实测环境验证过,给出结论与佐证要点:
4.1 一控多的批量文件生成
一个控制模板可以循环生成任意数量、任意命名规则的文件。实测的行星示例用 3 行 VTL 生成了 3 个 HTML 文件;实体生成示例用同一个模板循环生成了 2 个 Java POJO 加 2 个建表 SQL,外加 1 个说明文件,一次 ant main 全部产出。
4.2 contextProperties 属性注入
contextProperties 指向一个属性文件,Texen 会把其中的键值注入模板上下文,并对三类值做自动类型转换(实测行为):
| 属性文件中的写法 | 注入上下文后的类型 | 实测结果 |
|---|---|---|
maxDepth = 3 | Integer | 产物注释显示 maxDepth=3,按数字处理 |
verbose = true | Boolean | 产物注释显示 verbose=true,按布尔处理 |
license.file.contents = LICENSE.txt | String(整个文件内容) | 键去掉 .file.contents 后缀变成 $license,文件全文注入模板 |
第三条是最实用的特性:可以把许可证头、版权声明等长文本单独放文件,由 Texen 注入到每个生成文件的头部。
4.3 工人模板上下文继承
控制模板中 #set 的变量(如 $appPkg、$className)在工人模板中直接可见——工人上下文以控制上下文为父级链式构建。实测中 build.properties 定义的包名在控制模板与 POJO 模板中都能读到,无需重复传参。
4.4 输入/输出编码控制
inputEncoding/outputEncoding 显式指定模板与产物的字符集。实测在未设置时,含中文的模板与产物出现 ? 乱码;设置 UTF-8 后中文完整保留(对照回显见《Apache Texen 在 Ubuntu 22.04 集成使用指南》注意事项一节)。
4.5 classpath 模板加载与缓存开关
useClasspath=true 时模板改由 classpath 加载,并可用 useResourceLoaderCache/resourceLoaderModificationCheckInterval 控制模板缓存与刷新间隔。实测 useResourceLoaderCache="true"、resourceLoaderModificationCheckInterval="0" 组合 BUILD SUCCESSFUL。
4.6 生成报告文件
控制模板自身的渲染结果会写入 outputFile 指定的报告文件(惯例命名 generation.report)。实测两种表现:控制模板只做编排时报告几乎为空(4 个空行);工人模板若以两参数形态调用(不指定输出文件名),其内容会全部并入报告。
五、适用场景与限制
5.1 适合的场景
- 脚手架/代码骨架生成:按实体清单批量产出 POJO、DAO、SQL DDL 等模板化程度高的代码文件。
- 多格式产物一次生成:同一份数据模型同时生成 Java 源码、SQL 脚本、文档页面(实测一工程三产物)。
- 构建期离线生成:以 Ant 为构建入口的团队可直接把
<texen>嵌进既有 build.xml,无网络、无额外服务依赖。 - 许可证/版权头批量注入:借助
file.contents特性把统一许可文本注入每个生成文件。
5.2 限制与风险
| 限制 | 实测依据 | 影响 |
|---|---|---|
| 2007 年后零更新 | Central versionCount:1、官网 Last Published 2007-06-24 | 无 bug 修复、无安全补丁渠道 |
| 仅兼容 Velocity 1.x 旧工具类 | Velocity 2.4.1 下 $strings 大部分方法缺失、contextProperties 属性触发 NoSuchMethodError(实测崩溃) | 升级 Velocity 需改造模板并放弃 contextProperties |
| 强依赖 Ant | 唯一入口是 Ant 任务 | Maven/Gradle 项目需额外桥接(如 maven-antrun) |
| 不自动创建嵌套输出目录 | 未建目录直接生成 output/com/quzuo/demo/User.java 时 FileNotFoundException(实测) | 模板必须先用 $files.mkdir 建目录 |
| logFile 属性无实际效果 | logFile="texen.log" 两种加载方式下均未产生日志文件(实测) | 排障只能依赖 ant -debug |
六、同类选型对比
面向"批量生成文本/代码"这一需求,可选方案与 Texen 的横向对比(关键差异见解读):
| 方案 | 形态 | 模板能力 | 维护状态 | 与 Ant 集成 | 适用判断 |
|---|---|---|---|---|---|
| Apache Texen 1.0 | Ant 任务 + 双层模板 | Velocity 1.x | 2007 年后休眠 | 原生(就是 Ant 任务) | Ant 遗产系统、零依赖离线生成 |
| Velocity Engine 直接用 | 嵌入式库 | Velocity 1.7/2.x 活跃维护 | 活跃 | 需自写代码或 antrun | 只需模板渲染、自行编排多文件 |
| Apache FreeMarker | 嵌入式库 | 内建函数更丰富 | 活跃 | 需自写代码 | 需要更强模板函数与报错定位 |
| JavaPoet / JCodeModel | 代码构造 API | 无模板(纯 API 拼装) | 活跃 | 需自写代码 | 类型安全的 Java 源码生成 |
| MyBatis Generator | 独立生成器 | 固定规则 + 可改配置 | 活跃 | Maven/Ant 均可 | 仅针对数据库表到 MyBatis 代码 |
| 注解处理器(APT) | 编译期插件 | 无模板 | 活跃 | 构建工具原生 | 编译期生成,不适合独立产物文件 |
关键差异与选型建议:
- 已有 Ant 体系、要"模板驱动 + 多文件编排":Texen 是最贴合的开箱方案,一个 taskdef 即接入,代价是接受其休眠状态。
- 希望长期维护、跟随 Velocity 2.x:不要用 Texen(兼容性坑实测存在),直接嵌入 Velocity Engine 或 FreeMarker,把"多文件编排"逻辑写在 Java/脚本里。
- 生成目标只有 Java 源码且追求类型安全:选 JavaPoet 一类代码构造库,模板引擎反而绕远。
- 生成目标固定为 MyBatis 映射代码:直接用 MyBatis Generator,无需自建模板。
💡 技术拓展:代码生成按「实现方式」可分为三类——模板驱动(Texen/FreeMarker:内容外观由模板控制,灵活但无类型检查)、API 构造(JavaPoet:类型安全但排版代码冗长)、编译期注解处理(APT:与编译流程融合但只能生成新类不能改既有文件)。Texen 属于模板驱动类,适合产物格式多变、以文本为主的场景。
七、参考链接
- Texen 官方文档(1.0,官网保留的唯一版本):https://velocity.apache.org/texen/1.0/
- Maven Central 坐标页:https://central.maven.org/maven2/org/apache/texen/texen/1.0/
- Central 检索接口(本文版本结论来源):https://search.maven.org/solrsearch/select?q=g:%22org.apache.texen%22+AND+a:%22texen%22&wt=json
- Apache Velocity 官网:https://velocity.apache.org/
- Apache Torque(Texen 的经典使用者):https://db.apache.org/torque/
- 本文配套实操文档:《Apache Texen 在 Ubuntu 22.04 集成使用指南》《Apache Texen 常用 CLI 命令与工具详解》