Apache Felix 常用 CLI 命令与工具详解
详解 Apache Felix Gogo Shell 常用命令:bundle 生命周期管理、lb/headers/inspect/refresh 等诊断命令,以及用 maven-bundle-plugin 构建 bundle 的流程。
Apache Felix 常用 CLI 命令与工具详解
Felix Framework 通过 Gogo shell 提供交互式命令行,用于安装、启停 bundle 与诊断框架状态。启动框架后即进入 shell:
cd /opt/felix/felix-framework-7.0.5
java -Xms256m -Xmx512m -jar bin/felix.jar
____________________________
Welcome to Apache Felix Gogo
g!
提示符 g! 表示已就绪,可直接输入命令。本文命令回显均来自真实运行。
一、Gogo Shell 与命令 scope
1.1 查看全部命令
执行 help 列出所有可用命令,回显中会显示命令按 scope 分组,scope 包括 felix:*、gogo:*、osgi:*、system:*、context:*、obr:*。
1.2 felix scope 命令清单
felix scope 提供的命令:
bundlelevel / cd / frameworklevel / headers / help / inspect / install /
lb / log / ls / refresh / resolve / start / stop / uninstall / update / which
不带 scope 前缀直接输入(如 lb、install)时,默认解析到 felix: scope。
1.3 查看单条命令帮助
g! help install
二、Bundle 生命周期命令
2.1 install — 安装
g! install file:/opt/felix-bundle/target/hello-osgi-1.0.0.jar
Bundle ID: 7
本地文件必须使用 file: 前缀的绝对路径。安装后状态为 Installed。
2.2 start / stop — 启动 / 停止
g! start 7
[hello-osgi] Bundle started: com.example.hello
g! stop 7
[hello-osgi] Bundle stopped: com.example.hello
start 触发 Activator#start;stop 触发 Activator#stop。状态在 Active 与 Resolved 之间切换。
2.3 update — 更新
从同一位置重新加载 bundle 内容:
g! update 7
[hello-osgi] Bundle stopped: com.example.hello
[hello-osgi] Bundle started: com.example.hello
若 bundle 处于活动状态,update 会先停止再启动。
2.4 uninstall — 卸载
g! uninstall 7
g!
卸载后 lb 中不再列出该 bundle。
2.5 refresh — 刷新
使解析结果对新版本生效,通常在 update 后调用:
g! refresh 7
(无输出,刷新成功)
2.6 resolve — 解析
g! resolve 7
Not all bundles could be resolved.
提示存在未满足的依赖时,应结合 inspect 定位缺失的 capability。
三、查询与诊断命令
3.1 lb — 列出 bundle
g! lb
ID|State |Level|Name
0|Active | 0|System Bundle (7.0.5)|7.0.5
1|Active | 1|jansi (1.18.0)|1.18.0
...
7|Installed | 1|hello-osgi (1.0.0)|1.0.0
State 常见取值:Installed(已安装未解析)、Resolved(已解析)、Active(已启动)。
3.2 headers — 查看 MANIFEST 响应头
g! headers 7
hello-osgi (7)
--------------
Bundle-Activator = com.example.hello.Activator
Bundle-ManifestVersion = 2
Bundle-SymbolicName = com.example.hello
Bundle-Version = 1.0.0
Export-Package = com.example.hello;uses:="org.osgi.framework";version="1.0.0"
Import-Package = org.osgi.framework;version="[1.8,2)"
...
headers 0 可查看系统 bundle 的响应头,其中的 Bundle-Version 即框架版本。
3.3 inspect — 查看 capability / requirement
命令签名:inspect (capability|requirement) <namespace> <bundle...>,别名 cap / req,必须传入已存在的 bundle id。
g! inspect req osgi.wiring.package 7
com.example.hello [7] requires:
-------------------------------
osgi.wiring.package; (&(osgi.wiring.package=org.osgi.framework)(version>=1.8.0)(!(version>=2.0.0))) resolved by:
osgi.wiring.package; org.osgi.framework 1.10.0 from org.apache.felix.framework [0]
g! inspect cap osgi.wiring.package 0
org.apache.felix.framework [0] provides:
----------------------------------------
osgi.wiring.package; org.osgi.framework 1.10.0 required by:
org.apache.felix.gogo.runtime [6]
...
3.4 bundlelevel — 查看 / 设置启动级别
g! bundlelevel 7
com.example.hello [7] is level 1
bundlelevel <id> <level> 可设置新级别。
3.5 which — 定位类来源
g! which 7 com.example.hello.Activator
Loaded from: com.example.hello [7]
用于确认某个类由哪个 bundle 导出。
3.6 frameworklevel — 框架启动级别
g! felix:frameworklevel
Level is 1
四、其他 scope 命令
4.1 system:*
system:* 映射到 java.lang.System 方法,例如查看 JVM 系统属性:
g! system:property java.version
注意 Felix 发行版没有 system:version,执行会报 CommandNotFoundException: Command not found: system:version(该命令属于 Karaf)。
4.2 log:*
读取框架日志服务:
g! log 5 info
Log reader service is unavailable.
默认发行包未部署 Log 服务 bundle 时返回上述提示。
4.3 obr:*
Bundle Repository 相关命令需要参数:
g! obr:repos
Cannot coerce repos() to any of [(String, String[])]
4.4 文件系统命令 ls / cd / pwd
g! pwd
/opt/felix/felix-framework-7.0.5
g! ls
..
DEPENDENCIES
LICENSE
LICENSE.kxml2
NOTICE
bin
bundle
conf
doc
felix-cache
felix:cd 可切换当前目录,felix:ls 列出目录内容。
五、使用 Maven 构建 OSGi bundle
5.1 引入 maven-bundle-plugin
maven-bundle-plugin 基于 bnd,负责把普通 Maven 工程打包为带 OSGi 响应头的 jar:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>5.1.9</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>com.example.hello</Bundle-SymbolicName>
<Bundle-Version>1.0.0</Bundle-Version>
<Bundle-Activator>com.example.hello.Activator</Bundle-Activator>
<Export-Package>com.example.hello</Export-Package>
<Import-Package>org.osgi.framework;version="[1.8,2)"</Import-Package>
</instructions>
</configuration>
</plugin>
5.2 打包命令
mvn -q -B package
产物位于 target/hello-osgi-1.0.0.jar。若需限制构建 JVM 内存:
MAVEN_OPTS="-Xms256m -Xmx512m" mvn -q -B package
5.3 校验 MANIFEST
unzip -p target/hello-osgi-1.0.0.jar META-INF/MANIFEST.MF
真实回显关键项:
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.example.hello
Bundle-Version: 1.0.0
Bundle-Activator: com.example.hello.Activator
Import-Package: org.osgi.framework;version="[1.8,2)"
Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=11))"
5.4 部署到 Felix
把产物安装到运行中的框架:
g! install file:/opt/felix-bundle/target/hello-osgi-1.0.0.jar
Bundle ID: 7
g! start 7
[hello-osgi] Bundle started: com.example.hello
六、命令速查表
| 命令 | 作用 |
|---|---|
lb | 列出全部 bundle 及状态 |
install <url> | 安装 bundle,返回 Bundle ID |
start <id> / stop <id> | 启动 / 停止 bundle |
update <id> | 重新加载 bundle 内容 |
uninstall <id> | 卸载 bundle |
refresh <id> | 刷新解析结果 |
resolve <id> | 解析 bundle 依赖 |
headers <id> | 查看 MANIFEST 响应头 |
inspect cap|req <ns> <id> | 查看 capability / requirement |
bundlelevel <id> | 查看启动级别 |
frameworklevel | 查看框架启动级别 |
which <id> <class> | 定位类来源 |
help | 列出全部命令 |
exit | 退出 shell 并停止框架 |
七、常见问题
Q1:install 报 URL 无法识别?
本地文件需带 file: 前缀并使用绝对路径,如 install file:/opt/felix-bundle/target/hello-osgi-1.0.0.jar。
Q2:inspect 报 Cannot coerce inspect(...)?
参数不完整或 bundle id 不存在。签名必须是 inspect (capability|requirement) <namespace> <bundle...>,且 bundle id 必须已存在。
Q3:start 后状态未变 Active?
多为依赖未解析,先用 resolve 与 inspect req 定位缺失的包或 capability。
Q4:update 后新代码未生效?
update 更新的是 bundle 内容,若已导出包被其他 bundle 引用,需再执行 refresh 使其重新解析。
Q5:退出 shell 会怎样?
执行 exit 或结束输入流,框架输出 gosh: stopping framework 后停机。