Apache Sling 常用 CLI 命令与工具详解
汇总 Apache Sling 常用命令行工具与 REST 接口:服务启停、SlingPostServlet 内容读写删除、OSGi 控制台状态查询、管理密码修改、进程与端口核验及日志排查,示例命令与回显全部在真实环境逐步实测
Apache Sling 常用 CLI 命令与工具详解
目标:整理 Apache Sling 9(launchpad standalone jar 形态)日常运维所需的命令行工具与 REST 接口——服务启停、内容读写删除、OSGi 控制台状态查询、管理密码修改、进程端口核验与日志排查。示例命令与回显均在 Ubuntu 22.04.5 真实环境逐步实测。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Java:OpenJDK 1.8.0_504(
openjdk-8-jdk-headless,含jps) - Apache Sling:9(
org.apache.sling.launchpad-9.jar) - 安装目录:
/opt/sling-lp9;sling home:/opt/sling-lp9/sling - 监听端口:8080
- 托管方式:systemd(单元
sling.service) - 管理账号:
admin,口令q1w2e3r4(由默认口令admin改而来,改法见 4.4 节)
二、工具概览
| 工具/接口 | 用途 | 本文实测 |
|---|---|---|
java -jar(launchpad jar) | 启动 Sling(支持 -p 端口等参数) | 4.1 节 |
systemctl(sling.service) | 服务启停与开机自启 | 4.1 节 |
| curl + SlingPostServlet | 内容节点创建/更新/删除 | 4.2 节 |
curl + .json / .tidy.json | 内容 JSON 读取 | 4.2 节 |
| curl + Web Console JSON | bundle 与运行状态查询 | 4.3 节 |
| curl + userManager 端点 | 管理密码修改 | 4.4 节 |
ss / ps / jps -v | 端口、进程与 JVM 参数核验 | 4.5 节 |
logs/error.log 等三份日志 | 故障排查 | 4.6 节 |
💡 Sling 本体不提供独立 CLI 二进制;「命令行工具」由三部分组成:启动命令行参数、系统常规工具(systemd、ss、jps)与内置 REST 接口(curl 调用)。
三、前置条件
- 已按《Apache Sling 安装指南》完成安装并托管到 systemd,
systemctl is-active sling返回active。 - 已安装
openjdk-8-jdk-headless(jps)、iproute2(ss)、procps(ps)、curl。 - 本文 REST 示例统一使用
admin/q1w2e3r4;实例若仍是默认口令,把-u admin:q1w2e3r4换成-u admin:admin即可(改密方法见 4.4 节)。
四、工具详解
4.1 启动与服务管理命令
前台启动(排障用,日志直出终端,Ctrl+C 退出):
cd /opt/sling-lp9
java -Xms256m -Xmx512m -jar org.apache.sling.launchpad-9.jar
带端口参数启动(实测 -p 8888):
# cd /opt/sling-lp9 && java -jar org.apache.sling.launchpad-9.jar -p 8888
12.10.2026 05:16:41.008 *INFO * [main] HTTP server port: 8888
12.10.2026 05:16:44.699 *INFO * [main] Startup completed
生产建议 systemd 托管(单元文件写法见《Apache Sling 安装指南》第七章),常用命令:
# systemctl start sling
# systemctl is-active sling
active
# systemctl stop sling
# systemctl is-active sling
inactive
# systemctl start sling
# systemctl status sling --no-pager -n 3 | head -10
● sling.service - Apache Sling Launchpad 9
Loaded: loaded (/etc/systemd/system/sling.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-10-12 05:19:07 UTC; 25s ago
Main PID: 5757 (java)
Tasks: 126 (limit: 5753)
Memory: 414.1M
CPU: 25.922s
CGroup: /system.slice/sling.service
└─5757 /usr/bin/java -Xms256m -Xmx512m -jar /opt/sling-lp9/org.apache.sling.launchpad-9.jar
Sling Starter 14(方案 B)对应的启动主类与常用参数(java -cp "org.apache.sling.feature.launcher-1.3.4/lib/*" org.apache.sling.feature.launcher.impl.Main --help 实测节选):
| 选项 | 说明 |
|---|---|
-f <FAR文件> | 指定 feature 文件(如 org.apache.sling.starter-14-oak_tar_far.far) |
-c <cache_dir> | 指定缓存目录 |
-p <home_dir> | 指定 home 目录 |
-D key1=val1 | 设置框架属性 |
-V key1=val1 | 设置 feature 变量值 |
-CO | 仅缓存依赖,不启动框架 |
-v | 详细日志(trace/debug/info/warn/error/off) |
JAVA_OPTS 环境变量 | 注入 JVM 参数 |
4.2 内容读写 REST(SlingPostServlet)
创建节点(表单字段即节点属性,返回 201):
# curl -s -i -u admin:q1w2e3r4 -F"sling:resourceType=foo" -F"title=hello" http://localhost:8080/content/mynode | head -6
HTTP/1.1 201 Created
Date: Mon, 12 Oct 2026 05:14:58 GMT
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Location: /mynode
Content-Type: text/html;charset=utf-8
读取节点 JSON(.json 紧凑格式 / .tidy.json 缩进格式):
# curl -s -u admin:q1w2e3r4 http://localhost:8080/content/mynode.json
{"jcr:primaryType":"sling:OrderedFolder","jcr:createdBy":"admin","jcr:created":"Mon Oct 12 2026 05:14:58 GMT+0000","title":"hello","sling:resourceType":"foo"}
# curl -s -u admin:q1w2e3r4 http://localhost:8080/content/mynode.tidy.json
{
"jcr:primaryType": "sling:OrderedFolder",
"jcr:createdBy": "admin",
"jcr:created": "Mon Oct 12 2026 05:14:58 GMT+0000",
"title": "hello",
"sling:resourceType": "foo"
}
更新节点(对同 URL 重新 POST 覆盖属性,返回 200):
# curl -s -o /dev/null -w "update=%{http_code}\n" -u admin:q1w2e3r4 -F"title=hello-updated" http://localhost:8080/content/mynode
update=200
# curl -s -u admin:q1w2e3r4 http://localhost:8080/content/mynode.json
{"jcr:primaryType":"sling:OrderedFolder","jcr:createdBy":"admin","jcr:created":"Mon Oct 12 2026 05:14:58 GMT+0000","title":"hello-updated","sling:resourceType":"foo"}
删除节点(DELETE,返回 204;删除后再 GET 返回 404):
# curl -s -o /dev/null -w "del=%{http_code}\n" -u admin:q1w2e3r4 -X DELETE http://localhost:8080/content/mynode
del=204
# curl -s -o /dev/null -w "get_after_del=%{http_code}\n" -u admin:q1w2e3r4 http://localhost:8080/content/mynode.json
get_after_del=404
4.3 Web Console 与状态查询接口
bundle 状态(一次性掌握全部 OSGi bundle):
# curl -s -u admin:q1w2e3r4 "http://localhost:8080/system/console/bundles.json" | head -c 200
{"status":"Bundle information: 155 bundles in total - all 155 bundles active.","s":[155,151,4,0,0],"data":[{"id":0,"name":"System Bundle","fragment":false,"stateRaw":32,"state":"Active","version":"5.6.4","symbolicName":"org.apache.felix.framework",...
status 字段直接给出总数与 Active 汇总;data 数组含每个 bundle 的名称、版本与状态。核心 bundle 版本抽查(grep bundles.json):
"name":"Apache Sling API",...,"state":"Active","version":"2.16.2"
"name":"Apache Sling Engine Implementation",...,"state":"Active","version":"2.6.8"
"name":"Apache Sling JCR Oak Repository Server",...,"state":"Active","version":"1.1.4"
运行模式与 sling home:
# curl -s -u admin:q1w2e3r4 "http://localhost:8080/system/console/status-slingsettings.json" | grep -E "Run Modes|Sling Home"
"Sling Home = /opt/sling-lp9/sling",
"Sling Home URL = file:/opt/sling-lp9/sling/",
"Run Modes = [oak_tar]"]
凭据校验:无凭据访问控制台接口统一返回 401:
# curl -s -o /dev/null -w "noauth_console=%{http_code}\n" http://localhost:8080/system/console/bundles.json
noauth_console=401
4.4 管理密码修改(userManager 端点)
# curl -s -i -u admin:admin -X POST -F"oldPwd=admin" -F"newPwd=q1w2e3r4" -F"newPwdConfirm=q1w2e3r4" http://localhost:8080/system/userManager/user/admin.changePassword.html | head -3
HTTP/1.1 200 OK
Date: Mon, 12 Oct 2026 05:15:29 GMT
X-Content-Type-Options: nosniff
改后双向验证:
# curl -s -o /dev/null -w "%{http_code}\n" -u admin:admin http://localhost:8080/index.html
401
# curl -s -o /dev/null -w "%{http_code}\n" -u admin:q1w2e3r4 http://localhost:8080/index.html
200
⚠️ 路径必须为
user/admin.changePassword.html(斜杠连接)。写成user.admin.changePassword.html实测返回 500,正文为java.lang.UnsupportedOperationException: create 'userManager' at /system。
4.5 进程、端口与 JVM 核验
# ss -tlnp | grep 8080
LISTEN 0 50 *:8080 *:* users:(("java",pid=5757,fd=249))
# ps -ef | grep "[j]ava" | head -1
root 5757 1 0 05:19 ? 00:00:25 /usr/bin/java -Xms256m -Xmx512m -jar /opt/sling-lp9/org.apache.sling.launchpad-9.jar
# jps -v | grep -i sling
5757 org.apache.sling.launchpad-9.jar -Xms256m -Xmx512m
三个视图核对一致即配置生效:ss 确认端口监听进程 PID,ps/jps -v 确认该 PID 的启动参数含 -Xms256m -Xmx512m。
4.6 日志文件排查
sling home 的 logs/ 下三份日志(实测样例):
# tail -2 /opt/sling-lp9/sling/logs/error.log
12.10.2026 05:25:50.111 *INFO* [async-index-update-async] org.apache.jackrabbit.oak.plugins.index.lucene.directory.IndexSanityChecker Local index directory content found to be valid for index [/oak:index/lucene]. Stats Local: 26 files (1.7 MB), Remote: 26 files (1.7 MB)
12.10.2026 05:25:53.397 *INFO* [127.0.0.1 [1791782753393] GET /content/mynode.json HTTP/1.1] org.apache.sling.engine.impl.SlingRequestProcessorImpl service: Resource /content/mynode.json not found
# tail -2 /opt/sling-lp9/sling/logs/request.log
12/Oct/2026:05:25:53 +0000 [3] -> GET /content/mynode.json HTTP/1.1
12/Oct/2026:05:25:53 +0000 [3] <- 404 text/html 8ms
# tail -2 /opt/sling-lp9/sling/logs/access.log
127.0.0.1 - admin 12/Oct/2026:05:25:53 +0000 "DELETE /content/mynode HTTP/1.1" 204 - "-" "curl/7.81.0"
127.0.0.1 - admin 12/Oct/2026:05:25:53 +0000 "GET /content/mynode.json HTTP/1.1" 404 2537 "-" "curl/7.81.0"
分工:error.log 看异常与 Oak 索引活动;request.log 看单请求进出与耗时;access.log 看访问者、账号与状态码。启动阶段的问题以启动日志(nohup 重定向文件或 journal)为准。
五、注意事项
- 所有 REST 写操作都会直接落在 Oak 仓储(
repository/segmentstore),生产操作前先备份 sling home。 DELETE无回收站,204 即物理删除;误删需从备份恢复。systemctl status看到的 Memory 是进程 RSS,堆实际受-Xmx控制,两者含义不同。- curl 密码直接写在命令行会被 shell history 记录,公用运维机建议改用
curl -u admin --prompt或配置 netrc。
六、常见问题(FAQ)
Q1:POST 返回 500 且提示 create userManager?
原因:改密 URL 少了斜杠(user.admin.changePassword.html)。解决:改用 user/admin.changePassword.html。
Q2:curl 返回 000 或 Connection refused?
排查顺序:systemctl is-active sling 确认服务 → ss -tlnp | grep 8080 确认端口 → tail /opt/sling-lp9/sling/logs/error.log 看异常。首次启动约 30 秒内端口不会监听,属正常。
Q3:bundle 状态里出现 非 Active 条目?
用 curl -s -u admin:q1w2e3r4 "http://localhost:8080/system/console/bundles.json" 定位 state 非 Active 的 symbolicName,再查 error.log 中该 bundle 的解析错误;常见原因是 Java 版本不符或手工改动 sling home 后依赖缺失。
Q4:.json 读取返回 404?
路径不存在或已被删除(实测删除后 GET 返回 404)。用 tidier 路径验证:访问父路径 .tidy.json 列出子节点确认实际结构。
Q5:改了 JVM 参数但 jps -v 仍是旧值?
原因:进程未重启。解决:systemctl restart sling 后重新 jps -v | grep -i sling 核对。
七、参考链接
- Apache Sling 入门文档:https://sling.apache.org/documentation/getting-started.html
- Apache Sling 操作手册(Manipulating Content - SlingPostServlet):https://sling.apache.org/documentation/bundles/manipulating-content-the-slingpostservlet-servlets-post.html
- Apache Sling Web Console:https://sling.apache.org/documentation/bundles/web-console.html
- UserManager REST API(jackrabbit-usermanager):https://sling.apache.org/documentation/bundles/jackrabbit-usermanager.html
- launchpad 归档发行目录:https://archive.apache.org/dist/sling/