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

详解 Apache Felix Gogo Shell 常用命令:bundle 生命周期管理、lb/headers/inspect/refresh 等诊断命令,以及用 maven-bundle-plugin 构建 bundle 的流程。

Apache FelixApache Felix2026/10/12

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 后停机。