Apache Velocity 常用 CLI 命令与工具详解
汇总 Velocity 2.4.1 命令行使用形态:Velocity 本体无独立 CLI,逐条实测 Maven 构建、依赖管理、exec 运行、java 直跑与 JVM 堆诊断命令,附真实回显、堆内存限制方法与编码乱码排查手段。
Apache Velocity 常用 CLI 命令与工具详解
一、环境信息
| 项目 | 值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS |
| 登录账号 | root |
| JDK | OpenJDK 17.0.20.1 |
| Maven | 3.6.3 |
| 组件 | velocity-engine-core 2.4.1 |
| 辅助依赖 | slf4j-simple 1.7.36 |
| 测试工程 | /root/velocity-demo(Maven 工程) |
二、工具概览
Apache Velocity 是类库形态的模板引擎,官方不提供独立 CLI 可执行程序;velocity-tools 工具箱同样只是 jar 依赖,没有命令行工具。Velocity 项目的命令行形态由三类工具组成:
| 工具 | 角色 | 典型命令 |
|---|---|---|
| Maven | 工程构建、依赖管理、运行入口 | mvn compile、mvn dependency:tree、mvn exec:java |
| java | 直接运行渲染程序 | java -cp 携带堆参数 |
| JDK 诊断命令 | 验证堆与运行状态 | jps -lv、java -XshowSettings:vm |
三、前置条件
- 已安装 JDK 17 与 Maven(
mvn -version验证)。 - 已按 Maven 标准布局建好测试工程 /root/velocity-demo,本篇所有命令在该目录执行。
- 工程引入 velocity-engine-core 2.4.1 与 slf4j-simple 1.7.36。
测试工程 pom.xml:
<?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</groupId>
<artifactId>velocity-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
</plugin>
</plugins>
</build>
</project>
用于堆参数采集的主类 /root/velocity-demo/src/main/java/com/example/VelocityDemo.java,支持 --hold 参数保活 60 秒便于采集运行中的 JVM 参数:
package com.example;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class VelocityDemo {
private static Map<String, Object> item(String name, double price) {
Map<String, Object> item = new HashMap<>();
item.put("name", name);
item.put("price", price);
return item;
}
public static void main(String[] args) throws Exception {
System.out.println("JVM maxMemory = "
+ Runtime.getRuntime().maxMemory() / 1024 / 1024 + " MB");
VelocityEngine engine = new VelocityEngine();
engine.setProperty("resource.loaders", "classpath");
engine.setProperty("resource.loader.classpath.class",
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
engine.setProperty("resource.default_encoding", "UTF-8");
engine.setProperty("velocimacro.library.path", "templates/macros.vm");
engine.init();
VelocityContext context = new VelocityContext();
context.put("name", "quzuo");
Map<String, Object> user = new HashMap<>();
user.put("name", "admin");
user.put("email", "admin@quzuo.net");
user.put("vip", true);
user.put("level", 3);
context.put("user", user);
List<Map<String, Object>> items = new ArrayList<>();
items.add(item("机械键盘", 299.0));
items.add(item("无线鼠标", 129.5));
items.add(item("显示器支架", 89.9));
context.put("items", items);
Template template = engine.getTemplate("templates/main.vm", "UTF-8");
StringWriter writer = new StringWriter();
template.merge(context, writer);
System.out.println("========== 渲染结果 ==========");
System.out.println(writer);
if (args.length > 0 && "--hold".equals(args[0])) {
Thread.sleep(60000);
}
}
}
四、工具详解
4.1 mvn -v:确认构建环境
mvn -v
实测回显:
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: en_US, platform encoding: ANSI_X3.4-1968
OS name: "linux", version: "6.8.0-138-generic", arch: "amd64", family: "unix"
platform encoding 为 ANSI_X3.4-1968 时中文输出会乱码,排查方式见 4.10。
4.2 mvn clean compile:编译工程
cd /root/velocity-demo && mvn -q clean compile
实测无输出即成功(退出码 0);非静默模式以 mvn clean compile 运行,末尾回显:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.292 s
4.3 mvn dependency:tree:确认 Velocity 依赖版本
cd /root/velocity-demo && mvn dependency:tree
实测回显(节选):
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ velocity-demo ---
[INFO] com.example:velocity-demo:jar:1.0.0
[INFO] +- org.apache.velocity:velocity-engine-core:jar:2.4.1:compile
[INFO] | +- org.apache.commons:commons-lang3:jar:3.17.0:compile
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.36:compile
[INFO] \- org.slf4j:slf4j-simple:jar:1.7.36:compile
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
4.4 mvn dependency:copy-dependencies:导出依赖 jar
cd /root/velocity-demo && mvn -q dependency:copy-dependencies -DoutputDirectory=libs
ls /root/velocity-demo/libs
实测回显:
commons-beanutils-1.9.4.jar commons-collections-3.2.2.jar commons-digester3-3.2.jar
commons-lang3-3.17.0.jar commons-logging-1.2.jar json-simple-3.0.2.jar
slf4j-api-1.7.36.jar slf4j-simple-1.7.36.jar
velocity-engine-core-2.4.1.jar velocity-tools-generic-3.1.jar
4.5 mvn dependency:get:无工程拉取依赖
不建工程直接把 Velocity 拉入本地仓库:
mvn -q dependency:get -Dartifact=org.apache.velocity:velocity-engine-core:2.4.1
echo $?
实测回显:
0
find /root/.m2/repository/org/apache/velocity/velocity-engine-core -name '*.jar'
实测回显:
/root/.m2/repository/org/apache/velocity/velocity-engine-core/2.4.1/velocity-engine-core-2.4.1.jar
4.6 mvn exec:java:以 Maven 入口运行渲染程序
cd /root/velocity-demo && LANG=C.UTF-8 mvn -q exec:java -Dexec.mainClass=com.example.VelocityDemo
实测回显:
JVM maxMemory = 8016 MB
========== 渲染结果 ==========
姓名:quzuo
正式引用:quzuo
不存在的引用(普通):[$missingValue]
不存在的引用(静默):[]
对象属性:admin / admin@quzuo.net
VIP 等级:3
商品清单:
1. 机械键盘 —— 单价 299.0 元
2. 无线鼠标 —— 单价 129.5 元
3. 显示器支架 —— 单价 89.9 元
共 3 件商品
==== 系统公告:本报告由 Velocity 模板引擎渲染 ====
---- 2026 quzuo.net 版权所有 ----
你好,张三!欢迎使用 Apache Velocity。
你好,李四!欢迎使用 Apache Velocity。
要点:exec:java 在 Maven 自身 JVM 内执行,maxMemory 随 Maven 进程默认值;pom 中若写死 mainClass,会覆盖命令行 -Dexec.mainClass 参数,实测传参不生效,因此 pom 不应配置 mainClass。
4.7 MAVEN_OPTS:限制 exec:java 的堆内存
cd /root/velocity-demo && MAVEN_OPTS='-Xms256m -Xmx512m' LANG=C.UTF-8 mvn -q exec:java -Dexec.mainClass=com.example.VelocityDemo
实测回显首行:
JVM maxMemory = 512 MB
4.8 mvn package 与 java 直跑:生产运行形态
cd /root/velocity-demo && mvn -q package -DskipTests
cd /root/velocity-demo && LANG=C.UTF-8 java -Xms256m -Xmx512m -XshowSettings:vm -cp 'target/classes:libs/*' com.example.VelocityDemo
实测回显(头部):
VM settings:
Min. Heap Size: 256.00M
Max. Heap Size: 512.00M
Using VM: OpenJDK 64-Bit Server VM
JVM maxMemory = 512 MB
========== 渲染结果 ==========
姓名:quzuo
打包为 jar 后用 jar 加 libs 运行(以 quickstart 工程产物为例):
cd /root/velocity-quickstart && LANG=C.UTF-8 java -Xms256m -Xmx512m -cp 'target/velocity-quickstart-1.0.0.jar:libs/*' com.example.App
实测回显:
欢迎来到 quzuo.net!
模块列表:
- 技术专栏
- 文档发布
- 归档中心
共 3 个模块。
4.9 PrintFlagsFinal:核对堆上限数值
java -Xms256m -Xmx512m -XX:+PrintFlagsFinal -version | grep -i maxheapsize
实测回显:
size_t MaxHeapSize = 536870912 {product} {command line}
size_t SoftMaxHeapSize = 536870912 {manageable} {ergonomic}
4.10 ps 与 jps:运行中采集 JVM 参数
利用 --hold 保活参数启动后立即采集(另一会话执行,或用作业控制):
cd /root/velocity-demo && java -Xms256m -Xmx512m -cp 'target/classes:libs/*' com.example.VelocityDemo --hold >/tmp/vd.log 2>&1 &
ps -ef | grep '[V]elocityDemo'
实测回显:
root 6914 6853 13 09:27 ? 00:00:00 java -Xms256m -Xmx512m -cp target/classes:libs/* com.example.VelocityDemo --hold
jps -lv
实测回显:
6914 com.example.VelocityDemo -Xms256m -Xmx512m
采集完成后结束进程:
kill 6914
4.11 编码诊断:定位中文乱码
java -XshowSettings:properties -version 2>&1 | grep -E 'file.encoding|native.encoding'
POSIX locale 下实测回显:
file.encoding = ANSI_X3.4-1968
native.encoding = ANSI_X3.4-1968
设置 LANG 后重查:
LANG=C.UTF-8 java -XshowSettings:properties -version 2>&1 | grep -E 'file.encoding|native.encoding'
实测回显:
file.encoding = UTF-8
native.encoding = UTF-8
4.12 模板调试手段
- 严格引用模式:给引擎设 runtime.strict_mode.enable=true,未定义引用会抛 MethodInvocationException 并带模板行列号,实测消息形如 Variable $undefinedRef has not been set at templates/strict-ref.vm[line 1, column 12],可直接定位拼写错误。
- 日志落盘:slf4j-simple 通过系统属性把 Velocity 日志写入文件:
cd /root/velocity-demo && LANG=C.UTF-8 java -Dorg.slf4j.simpleLogger.logFile=/var/log/velocity/velocity-demo.log -cp 'target/classes:libs/*' com.example.VelocityDemo
- 引擎弃用告警:换用旧配置键名时日志会打印 deprecated in favor of 提示,按提示改用新键名可消除 WARN。
五、注意事项
- exec:java 不新建 JVM:堆参数走 MAVEN_OPTS,pom 插件 jvmArgs 对 exec:java 无效;需要精确控制堆时优先用 java -cp 直跑。
- 修改模板后必须重新 mvn compile,java -cp 与 exec:java 读取的都是 target/classes 下的副本。
- dependency:get 拉取的构件进入本地仓库但不会出现在任何工程依赖里,仅用于预下载与离线分发。
- mvn -q 会抑制大部分 Maven 日志,排查构建问题时去掉 -q 观察 INFO 级输出。
- CentOS 8 环境注意 /usr/bin/mvn 读取 /etc/java/maven.conf 中的 JAVA_HOME,若 Maven 跑在旧 JDK 上编译 17 会报 invalid target release。
六、常见问题
Q1:mvn exec:java 报找不到主类或运行了错误的主类? A:检查 pom 中 exec-maven-plugin 是否配置了 mainClass;显式配置会覆盖 -Dexec.mainClass。实测去掉 pom 中的 mainClass 配置后,-Dexec.mainClass=com.example.ToolboxDemo 可正常切换入口类。
Q2:java -cp 运行报 NoClassDefFoundError: org/slf4j/LoggerFactory? A:classpath 少了 slf4j-api。velocity-engine-core 2.4.1 初始化即引用 SLF4J,用 dependency:copy-dependencies 导出全部依赖,并以 libs/* 方式拼入 classpath。
Q3:jar 方式运行时中文乱码,mvn 方式正常? A:两种方式 JVM 都继承会话 locale,检查执行会话是否带 LANG=C.UTF-8;最小化部署环境默认 POSIX locale,按 4.11 诊断并统一设置。
Q4:怎么确认线上进程的堆参数确实生效? A:组合验证:java -XshowSettings:vm 看 Min 与 Max Heap Size,PrintFlagsFinal 看 MaxHeapSize 数值,运行中的进程用 jps -lv 与 ps -ef 采集命令行参数,三者在 512MB 场景实测分别为 512.00M、536870912 与 -Xmx512m。
七、参考链接
- Velocity 引擎开发者文档:https://velocity.apache.org/engine/2.4/developer-guide.html
- exec-maven-plugin 用法:https://www.mojohaus.org/exec-maven-plugin/
- Maven 依赖插件文档:https://maven.apache.org/plugins/maven-dependency-plugin/
- jps 命令参考:https://docs.oracle.com/en/java/javase/17/docs/specs/man/jps.html