4.9. OSGi
OSGi 支持添加到 Jersey 1.2版。自那之后,您应该能够使用标准 OSGi意味着球衣基于web应用程序运行在 OSGi 运行时中描述的 OSGi 服务平台企业规范。Jersey 目前兼容 OSGi 4.2.0,该规范可以从 OSGi 4.2.0站点下载。
运行OSGi web应用程序的两种支撑方式有:
- WAB (Web Application Bundle)
- HTTP Service
WAR 实际上只是一个 OSGi 类型的 WAR 文件。HTTP服务特性允许您在 OSGi运行时中发布 Java EE Servlet 。
下面两个例子被添加到 Jersey 分布描述上述特点,展示如何使用Jersey:
两个例子是多模块 maven 项目, OSGi 应用程序 包含一个模块和一个测试模块。测试是基于PAX Exam。两个 OSGi 的例子还包括自述文件包含指令如何使用 Apache Felix框架手动运行示例应用程序。
其余的章节描述了如何运行上述示例在 GlassFish 4 应用服务器上。
4.9.1. Enabling the OSGi shell in Glassfish 在 Glassfish 使用 OSGi 壳
自从 GlassFish 使用 Apache Felix ,GlassFish的OSGi运行时就出现了。然而,出于安全原因, OSGi shell 被关闭。但是您可以显式地启用它通过GlassFish 控制台开始,创建一个Java系统属性glassfish.osgi.start.level.final 最后,将它的值设置为3:
Example 4.19.
启动控制台:
~/glassfish/bin$ ./asadmin
Use "exit" to exit and "help" for online help.
asadmin>
检查 java 属性值(从配置文件中加载):
asadmin> list-jvm-options
...
-Dglassfish.osgi.start.level.final=2
...
根据类型添加值:
asadmin> create-jvm-options --target server -Dglassfish.osgi.start.level.final=3
第二个选项是修改 osgi.properties 配置文件:
# Final start level of OSGi framework. This is used by GlassFish launcher code
# to set the start level of the OSGi framework once server is up and running so that
# optional services can start. The initial start level of framework is controlled using
# the standard framework property called org.osgi.framework.startlevel.beginning
glassfish.osgi.start.level.final=3
执行 Felix shell:
asadmin> osgi lb
... list of bundles ...
或者启动 shell 使用 osgi-shell 命令 (域必须启动,否则 osgi shell 不能启动):
asadmin> osgi-shell
Use "exit" to exit and "help" for online help.
gogo$
直接执行 osgi 命令:
gogo$ lb
... list of bundles ...
4.9.2. WAB Example
如前所述,WAR 只是一个 OSGi 类型的 WAR 文件。除了通常的 OSGi 头必须除了含有一种特殊的头,Web-ContextPath,指定web应用程序的上下文路径。我们的 WAB (在其他旁边)出现在以下标题清单:
Web-ContextPath: helloworld
Webapp-Context: helloworld
Bundle-ClassPath: WEB-INF/classese
第二个标题是忽视了 GlassFish ,但可能需要其他容器不能完全符合上面提到的企业 OSGi 规范。第三个清单头值得一提的是捆绑包类路径中指定在哪里可以找到应用程序的 Java 类包存档。可以找到更多关于标题出现在OSGi 在 OSGi Wiki。
更详细的信息,请参见 WAB Example 示例源代码。这个例子没打包成一个war 文件,而是在构建时一个 war 和一组额外的 jar 被产生出来。看下一个示例看如何 在GlassFish 部署基于 OSGi 的 Jersey 应用程序。
4.9.3. HTTP Service Example
注意
当在 GlassFish 部署一个 OSGi HTTP 服务的例子时,请确保 OSGi HTTP 服务包是安装在您的 GlassFish 实例中。
你可以直接安装和激活 Jersey 应用程序包。在我们的示例中,您可以安装示例包存储在本地(和另外 Jersey 源码构建):
1) 编译 (可选)
examples$ cd osgi-http-service/bundle
bundle$ mvn clean package
也可以从Java.net Maven Repository获取编译好的二进制文件
2) 安装进 OSGi 运行时:
gogo$ install file:///path/to/file/bundle.jar
Bundle ID: 303
或直接从 maven repository 安装:
gogo$ install http://maven.java.net/content/repositories/releases/org/glassfish/jersey/examples/osgi-http-service/bundle/<version>/bundle-<version>.jar
Bundle ID: 303
确保 <version> 替换为适当的版本号。哪一个是合适取决于特定的 您正在使用 GlassFish 4. x版本。包的版本不能高于 GlassFish 4.x 中 Jersey 集成的版本服务器。Jersey 包在 OSGi 级别声明其他包的依赖关系,这些依赖项版本敏感的。如果假设使用例子包从是 2.5 版本,但是 Glassfish 中 Jersey 版本是 2.3.1,依赖不会合适,包不会开始。如果发生这种情况,这个错误将是这样的:
gogo$ lb
...
303 | Installed | 1| jersey-examples-osgi-http-service-bundle (2.5.0.SNAPSHOT)
gogo$ start 303
org.osgi.framework.BundleException: Unresolved constraint in bundle
org.glassfish.jersey.examples.osgi-http-service.bundle [303]: Unable to resolve 308.0: missing requirement
[303.0] osgi.wiring.package; (&(osgi.wiring.package=org.glassfish.jersey.servlet)
(version>=2.5.0)(!(version>=3.0.0)))
gogo$
在相反的情况下(例如包版本是 2.3.1 和 Glassfish 中 Jersey版本更高),一切都应该正常运行
同样,如果你是从 主干源码编译 GlassFish 和使用从最近的 Jersey 发布的示例,您很可能能够运行从最近的 Jersey 发布的示例,作为球衣团队通常集成了所有新发布的在 GlassFish 中 Jersey 版。
最后,启动包:
gogo$ start 303
再一次,包ID(在我们的例子中 303 )已经被正确的安装命令返回的。
该示例应用程序现在应该启动并运行。你可以访问它在 http://localhost:8080/osgi/jersey-http-service/status。更多细节请参阅 HTTP 服务示例源代码示例。