Apache Velocity 常用 CLI 命令与工具详解

汇总 Velocity 2.4.1 命令行使用形态:Velocity 本体无独立 CLI,逐条实测 Maven 构建、依赖管理、exec 运行、java 直跑与 JVM 堆诊断命令,附真实回显、堆内存限制方法与编码乱码排查手段。

Apache VelocityApache Velocity2026/10/12

Apache Velocity 常用 CLI 命令与工具详解

一、环境信息

项目值
操作系统Ubuntu 22.04.5 LTS
登录账号root
JDKOpenJDK 17.0.20.1
Maven3.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

三、前置条件

  1. 已安装 JDK 17 与 Maven(mvn -version 验证)。
  2. 已按 Maven 标准布局建好测试工程 /root/velocity-demo,本篇所有命令在该目录执行。
  3. 工程引入 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 模板调试手段

  1. 严格引用模式:给引擎设 runtime.strict_mode.enable=true,未定义引用会抛 MethodInvocationException 并带模板行列号,实测消息形如 Variable $undefinedRef has not been set at templates/strict-ref.vm[line 1, column 12],可直接定位拼写错误。
  2. 日志落盘: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
  1. 引擎弃用告警:换用旧配置键名时日志会打印 deprecated in favor of 提示,按提示改用新键名可消除 WARN。

五、注意事项

  1. exec:java 不新建 JVM:堆参数走 MAVEN_OPTS,pom 插件 jvmArgs 对 exec:java 无效;需要精确控制堆时优先用 java -cp 直跑。
  2. 修改模板后必须重新 mvn compile,java -cp 与 exec:java 读取的都是 target/classes 下的副本。
  3. dependency:get 拉取的构件进入本地仓库但不会出现在任何工程依赖里,仅用于预下载与离线分发。
  4. mvn -q 会抑制大部分 Maven 日志,排查构建问题时去掉 -q 观察 INFO 级输出。
  5. 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。

七、参考链接

  1. Velocity 引擎开发者文档:https://velocity.apache.org/engine/2.4/developer-guide.html
  2. exec-maven-plugin 用法:https://www.mojohaus.org/exec-maven-plugin/
  3. Maven 依赖插件文档:https://maven.apache.org/plugins/maven-dependency-plugin/
  4. jps 命令参考:https://docs.oracle.com/en/java/javase/17/docs/specs/man/jps.html