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

汇总 Apache Tapestry 5.9.1 常用命令行工具与 Maven 命令,覆盖脚手架生成、生命周期构建、jetty 运行、依赖树、测试与 JVM 诊断工具,每条命令附实测回显,并给出常见报错的定位方法。

Apache TapestryApache Tapestry2026/10/12

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

一、环境信息

本篇全部命令在以下环境实测执行,回显均为真实输出:

项目实测值
操作系统Ubuntu 22.04.5 LTS(CentOS 8 命令一致,包管理差异见安装指南)
JDKOpenJDK 17.0.20.1(/usr/lib/jvm/java-17-openjdk-amd64)
Maven3.9.9(/opt/apache-maven-3.9.9,软链 /usr/local/bin/mvn)
应用框架Apache Tapestry 5.9.1(tapestry-core-jakarta 等全套 -jakarta 构件)
示例工程/root/tapestry-demo(com.example:tapestry-demo:1.0-SNAPSHOT,war 打包)
Web 服务器内嵌 Jetty 11.0.15(jetty-maven-plugin)
服务端口8080

二、工具概览

Tapestry 工程的日常操作围绕 Maven 生态展开:

工具/命令用途
mvn archetype:generate用官方 quickstart 脚手架生成工程骨架
mvn clean / compile / package清理、编译、打包 war
mvn jetty:run以内嵌 Jetty 启动应用(开发模式)
mvn test / surefire单元测试与集成测试
mvn dependency:tree分析依赖树(排查构件冲突)
mvn help:evaluate读取 pom 属性值
jps / jstat / jstack / jmapJDK 自带 JVM 进程观测工具
curl页面与接口验证
pkill停止后台 jetty:run 进程

三、前置条件

java -version
mvn -version

实测回显:

openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: /opt/apache-maven-3.9.9
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"

四、工具详解

4.1 mvn archetype:generate:生成工程骨架

cd /root
mvn -B archetype:generate \
  -DarchetypeGroupId=org.apache.tapestry \
  -DarchetypeArtifactId=quickstart \
  -DarchetypeVersion=5.9.1 \
  -DgroupId=com.example \
  -DartifactId=tapestry-demo \
  -Dversion=1.0-SNAPSHOT \
  -Dpackage=com.example \
  -DinteractiveMode=false

成功后生成 /root/tapestry-demo(pom.xml、src/main、src/test 与 Gradle 文件)。-B 为批处理模式,禁用交互与下载进度条;-DinteractiveMode=false 必须显式携带,否则无终端环境会挂起等待输入。

⚠️ 5.9 线不存在 tapestry-simple-archetype 构件,误用时实测报错:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-archetype-plugin:3.4.1:generate (default-cli) on project standalone-pom:
The desired archetype does not exist (org.apache.tapestry:tapestry-simple-archetype:5.9.1)

4.2 mvn clean:清理构建产物

cd /root/tapestry-demo && mvn -B clean

实测回显(末尾):

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  2.482 s
[INFO] Finished at: 2026-10-12T13:07:57Z
[INFO] ------------------------------------------------------------------------

删除 target/ 全部内容。正在以 jetty:run 运行的应用不受即时影响(类已加载),但随后可能触发热扫描异常,建议先停服务再 clean。

4.3 mvn compile:编译主代码

cd /root/tapestry-demo && mvn -B compile

实测回显(clean 后全新编译,末尾):

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  4.438 s
[INFO] Finished at: 2026-10-12T13:08:04Z
[INFO] ------------------------------------------------------------------------

产物在 target/classes。pom 的 maven-compiler-plugin 按 <release>11</release> 编译;Tapestry 5.9.1 构件本身字节码为 Java 8,JDK 17 编译运行均正常。

4.4 mvn package:打包 war

cd /root/tapestry-demo
export MAVEN_OPTS="-Xms256m -Xmx512m"
mvn -B -DskipTests package

实测回显(关键部分):

[INFO] --- surefire:3.1.2:test (default-test) @ tapestry-demo ---
[INFO] Tests are skipped.
[INFO] --- war:3.3.1:war (default-war) @ tapestry-demo ---
[INFO] Packaging webapp
[INFO] Assembling webapp [tapestry-demo] in [/root/tapestry-demo/target/tapestry-demo-1.0-SNAPSHOT]
[INFO] Building war: /root/tapestry-demo/target/tapestry-demo-1.0-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] Total time:  06:14 min

首次构建 6 分 14 秒(含全部依赖下载);依赖入本地仓库后,增量构建实测约 4 秒(CentOS 8 环境 time 统计 real 0m4.215s)。-DskipTests 只跳过执行仍编译测试代码;连编译都跳过用 -Dmaven.test.skip=true。

⚠️ quickstart 生成的 pom 需先修正两处再构建:surefire 版本 3.1 改为 3.1.2(该版本号不存在,否则报 Could not find artifact org.apache.maven.plugins:maven-surefire-plugin:jar:3.1);Tapestry 构件换成 -jakarta 后缀(见安装指南)。

4.5 mvn jetty:run:内嵌 Jetty 启动

cd /root/tapestry-demo
export MAVEN_OPTS="-Xms256m -Xmx512m"
nohup mvn -B jetty:run > /root/jetty.log 2>&1 &

实测启动日志关键行:

[INFO] <<< jetty:11.0.15:run (default-cli) < test-compile @ tapestry-demo <<<
[INFO] --- jetty:11.0.15:run (default-cli) @ tapestry-demo ---
[INFO] Web defaults = org/eclipse/jetty/webapp/webdefault.xml
[INFO] jetty-11.0.15; built: 2023-04-11T18:37:53.775Z; git: 5bc5e562c8d05c5862505aebe5cf83a61bdbcb96; jvm 17.0.20.1+1-1-22.04-Ubuntu
[INFO] Started ServerConnector@dc3eda6{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
[INFO] Started Server@239b98cb{STARTING}[11.0.15,sto=0] @7972ms
[INFO] Scan interval sec = 10

要点:

  • jetty:run 从源码目录直接运行(前置 test-compile 阶段自动编译),改 .tml、css、部分页面类后由 10 秒扫描自动重载;
  • 监听端口来自 pom 中 <httpConnector><port>8080</port>。实测 -Djetty.http.port=9090 不生效——第二个实例仍尝试绑定 8080 并报:
[ERROR] Failed to execute goal org.eclipse.jetty:jetty-maven-plugin:11.0.15:run (default-cli) on project tapestry-demo: Error starting jetty: Failed to bind to 0.0.0.0/0.0.0.0:8080: Address already in use
  • 前台运行时 Ctrl+C 停止;后台运行用:
pkill -f classworlds

(该模式串匹配 Maven 启动的主类 Launcher 所在命令行,实测可精准结束 jetty:run 进程组。)

4.6 mvn test:单元与集成测试

cd /root/tapestry-demo && mvn -B test

无图形环境服务器上的实测结果:

[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 -- in com.example.unit.ClassTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0 -- in com.example.tapestry.unit.pages.IndexTest
[INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0
[ERROR] Tests run: 24, Failures: 1, Errors: 0, Skipped: 23, Time elapsed: 135.8 s <<< FAILURE! -- in TestSuite
[ERROR]   NavigationTest>SeleniumTestCase.testStartup:249 ? NoClassDefFound org/openqa/selenium/bidi/HasBiDi
[ERROR] Tests run: 16, Failures: 1, Errors: 0, Skipped: 15

单元测试(com.example.unit、com.example.tapestry.unit)全部通过;集成测试(com.example.tapestry.integration)依赖 Selenium 浏览器,首例即失败并终止套件,整个命令以非零退出码结束。只跑单元测试:

mvn test -Dtest='com.example.unit.*,com.example.tapestry.unit.*'

4.7 mvn dependency:tree:依赖树分析

cd /root/tapestry-demo && mvn -B dependency:tree

实测输出中 Tapestry 相关子树(全文较长,此处节选):

[INFO] com.example:tapestry-demo:war:1.0-SNAPSHOT
[INFO] +- org.apache.tapestry:tapestry-core:jar:5.9.1:compile
[INFO] |  +- org.apache.tapestry:tapestry-ioc:jar:5.9.1:compile
[INFO] |  |  +- org.apache.tapestry:tapestry-func:jar:5.9.1:compile
[INFO] |  |  +- org.apache.tapestry:tapestry5-annotations:jar:5.9.1:compile
[INFO] |  |  \- org.apache.tapestry:plastic:jar:5.9.1:compile
[INFO] |  +- org.apache.tapestry:tapestry-json:jar:5.9.1:compile
[INFO] |  |  \- org.apache.tapestry:commons:jar:5.9.1:compile
[INFO] |  +- org.apache.tapestry:beanmodel:jar:5.9.1:compile
[INFO] |  \- org.apache.tapestry:tapestry-http:jar:5.9.1:compile
[INFO] +- org.apache.tapestry:tapestry-webresources:jar:5.9.1:compile
[INFO] +- org.apache.tapestry:tapestry-test:jar:5.9.1:test
[INFO] |  |  +- org.eclipse.jetty.orbit:javax.servlet:jar:3.0.0.v201112011016:test
[INFO] |  |  \- org.apache.tomcat:tomcat-servlet-api:jar:7.0.70:test
[INFO] \- jakarta.servlet:jakarta.servlet-api:jar:5.0.0:provided

该命令是排查 javax/jakarta 混用的第一工具:切换 -jakarta 构件后,应看到 tapestry-core-jakarta、tapestry-http-jakarta、tapestry-ioc-jakarta 等条目。另可按关键字过滤:mvn dependency:tree -Dincludes=org.apache.tapestry。

4.8 mvn help:evaluate:读取 pom 属性

cd /root/tapestry-demo && mvn -B -q help:evaluate -Dexpression=tapestry-version -DforceStdout

实测回显:

5.9.1

-q -DforceStdout 组合只输出属性值本身,便于脚本取值。

4.9 jps / jstat:JVM 进程观测

jps -v | grep Launcher

实测回显:

  4666 Launcher -Xms256m -Xmx512m -Dclassworlds.conf=/opt/apache-maven-3.9.9/bin/m2.conf -Dmaven.home=/opt/apache-maven-3.9.9 -Dlibrary.jansi.path=/opt/apache-maven-3.9.9/lib/jansi-native -Dmaven.multiModuleProjectDirectory=/root/tapestry-demo

堆水位抽查:

jstat -gcutil 5314 | head -3

实测回显:

  S0     S1     E      O      M     CCS    YGC     YGCT     FGC    FGCT     CGC    CGCT       GCT
  0.00  85.66  58.55  50.73  99.14  97.24     12     0.085     0     0.000     4     0.009     0.093

等价的 shell 验证方式:ps -ef | grep "[j]ava"(实测同样能看到 -Xms256m -Xmx512m)。线程卡顿排查用 jstack <pid>,堆转储用 jmap -dump:live,format=b,file=/tmp/heap.hprof <pid>。

4.10 curl:页面与接口验证套件

# 状态码
curl -s -o /dev/null -w "INDEX %{http_code}\n" http://127.0.0.1:8080/
# 版本与渲染验证
curl -s http://127.0.0.1:8080/ | grep -oE "Apache Tapestry Framework \(version [0-9.]+\)"
# 事件链接(预期 302)
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/index:complete
# 表单提交(先取 t:formdata 再 POST)
FD=$(curl -s http://127.0.0.1:8080/login | grep -oE "<input value=\"[^\"]+\" name=\"t:formdata\"" | sed "s/<input value=\"//;s/\" name=\"t:formdata\"//")
curl -sL -X POST http://127.0.0.1:8080/login.login \
  --data-urlencode "t:formdata=$FD" \
  --data-urlencode "email=admin" \
  --data-urlencode "password=q1w2e3r4" \
  --data-urlencode "submit_0=Sign in" | grep -oE "Welcome aboard!" | head -1

实测依次输出:INDEX 200、Apache Tapestry Framework (version 5.9.1)、302、Welcome aboard!。

五、注意事项

  1. 后台运行务必重定向日志(nohup ... > /root/jetty.log 2>&1 &),否则终端断开或日志刷屏都会影响操作;停止统一用 pkill -f classworlds。
  2. MAVEN_OPTS 是向 jetty:run JVM 注入堆参数的唯一途径(实测 ps -ef | grep "[j]ava" 可见 -Xms256m -Xmx512m);临时追加符号配置同样写在这里,如 -Dtapestry.production-mode=true。
  3. mvn clean 会删 target/,正在运行的 jetty:run 可能随即触发热扫描异常;先停服务再 clean。
  4. quickstart 生成的 Gradle 文件(build.gradle、gradlew 等)与 Maven 流程无关,可删除;pom 里 apache-staging 仓库声明也可删除,5.9.1 构件全部在 Maven Central。
  5. 改 pom 或 AppModule 类后,建议 mvn -DskipTests package 并重启 jetty:run;10 秒热扫描主要覆盖模板与静态资源,对模块类不可靠。
  6. 多工程并行时注意端口:jetty 端口只认 pom 显式配置,-Djetty.http.port 无效,需在各自 pom 的 <httpConnector> 里区分。

六、常见问题

Q1:archetype:generate 报 The desired archetype does not exist? 使用了不存在的构件名。5.9 线的正确脚手架是 org.apache.tapestry:quickstart,见 4.1 节命令。

Q2:构建报 Could not find artifact maven-surefire-plugin:jar:3.1? 脚手架版本属性错误,把 pom 中 <maven-surefire-version> 从 3.1 改为 3.1.2。

Q3:jetty:run 起来了但页面 503,日志有 NoClassDefFoundError: javax/servlet/Filter? 依赖里混用了 javax 版 Tapestry 构件与 jakarta 环境。用 mvn dependency:tree 确认后,把全部 Tapestry Web 构件换成 -jakarta 后缀版本,web.xml 换成 jakarta 5.0 描述符,重新构建启动。

Q4:mvn test 以失败退出(NoClassDefFound org/openqa/selenium/bidi/HasBiDi)? 集成测试需要 Selenium 浏览器,无图形环境跑不了。打包用 mvn package -DskipTests,或按 4.6 节只跑单元测试。

Q5:第二个 jetty:run 实例报 Address already in use? 端口被第一个实例占用,且 -Djetty.http.port 覆盖不了 pom 显式端口。修改第二个工程 pom 的 <httpConnector><port> 或先 pkill -f classworlds 停掉旧实例。

Q6:mvn -v 显示 platform encoding: ANSI_X3.4-1968,会影响中文渲染吗? 这是系统 locale 未配置 UTF-8 的表现。处理消息目录中的中文前先 locale-gen zh_CN.UTF-8(Ubuntu)或修改 /etc/locale.conf(CentOS 8),再以 UTF-8 locale 运行 Maven;实测 UTF-8 locale 下中文 properties 输出正常。

七、参考链接