Apache Texen 介绍与选型指南

Apache Texen 是 Velocity 体系下基于 Ant 的多文件文本生成框架,本文给出其架构、功能、2007 年后的维护现状与同类选型对比,全部结论在 Ubuntu 22.04 实测验证。

Apache TexenApache TexenJavaApacheLinux2026/10/16

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 TemplatesGString 内嵌与 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 上下文注入一组预置对象,模板里直接可用:

上下文变量类型/来源用途
$generatororg.apache.texen.Generator调用 parse() 生成工人模板文件
$stringsorg.apache.velocity.util.StringUtils字符串工具(包名转换、驼峰化、拼接等)
$filesorg.apache.texen.util.FileUtil文件工具(实测用得最多的是 mkdir())
$propertiesorg.apache.texen.util.PropertiesUtil属性文件工具
$nowjava.util.Date生成时间戳(实测产物中常用于记录生成时刻)
$outputDirectoryjava.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 = 3Integer产物注释显示 maxDepth=3,按数字处理
verbose = trueBoolean产物注释显示 verbose=true,按布尔处理
license.file.contents = LICENSE.txtString(整个文件内容)键去掉 .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.0Ant 任务 + 双层模板Velocity 1.x2007 年后休眠原生(就是 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 属于模板驱动类,适合产物格式多变、以文本为主的场景。

七、参考链接