Apache Tapestry 常用 CLI 命令与工具详解
汇总 Apache Tapestry 5.9.1 常用命令行工具与 Maven 命令,覆盖脚手架生成、生命周期构建、jetty 运行、依赖树、测试与 JVM 诊断工具,每条命令附实测回显,并给出常见报错的定位方法。
Apache Tapestry 常用 CLI 命令与工具详解
一、环境信息
本篇全部命令在以下环境实测执行,回显均为真实输出:
| 项目 | 实测值 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(CentOS 8 命令一致,包管理差异见安装指南) |
| JDK | OpenJDK 17.0.20.1(/usr/lib/jvm/java-17-openjdk-amd64) |
| Maven | 3.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 / jmap | JDK 自带 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!。
五、注意事项
- 后台运行务必重定向日志(
nohup ... > /root/jetty.log 2>&1 &),否则终端断开或日志刷屏都会影响操作;停止统一用pkill -f classworlds。 MAVEN_OPTS是向 jetty:run JVM 注入堆参数的唯一途径(实测ps -ef | grep "[j]ava"可见-Xms256m -Xmx512m);临时追加符号配置同样写在这里,如-Dtapestry.production-mode=true。mvn clean会删 target/,正在运行的 jetty:run 可能随即触发热扫描异常;先停服务再 clean。- quickstart 生成的 Gradle 文件(build.gradle、gradlew 等)与 Maven 流程无关,可删除;pom 里
apache-staging仓库声明也可删除,5.9.1 构件全部在 Maven Central。 - 改 pom 或 AppModule 类后,建议
mvn -DskipTests package并重启 jetty:run;10 秒热扫描主要覆盖模板与静态资源,对模块类不可靠。 - 多工程并行时注意端口: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 输出正常。
七、参考链接
- Apache Tapestry 官网:https://tapestry.apache.org/
- Getting Started:https://tapestry.apache.org/getting-started.html
- Running the Application(jetty:run 说明):https://tapestry.apache.org/running-the-application.html
- Unit Testing / Integration Testing:https://tapestry.apache.org/unit-testing-pages-or-components.html
- Maven 官方文档:https://maven.apache.org/guides/index.html
- Jetty Maven Plugin:https://eclipse.dev/jetty/documentation/jetty-11/programming-guide-maven.html
- tapestry-core-jakarta(Maven Central):https://repo1.maven.org/maven2/org/apache/tapestry/tapestry-core-jakarta/5.9.1/
- quickstart 脚手架(Maven Central):https://repo1.maven.org/maven2/org/apache/tapestry/quickstart/5.9.1/
- Javadoc:https://tapestry.apache.org/current/apidocs/