28

通过不将数十个 JAR 依赖项包装到 lib 目录中,OSGi 似乎具有拥有小型可部署工件的绝佳优势。但是,我找不到任何可以告诉我将依赖项部署到容器的简单、可靠的方法。例如,我有一个使用 CXF 和几个 Spring 子项目的应用程序。如果我需要将此应用程序部署到新的 Glassfish 服务器,那么确保安装所有依赖项的最佳方法是什么?

我正在使用 Maven,似乎有某种方法可以有一个钩子来查看 META-INF/maven 目录并从 pom.xml 中提取依赖项列表并获取所需的库(可能来自本地仓库)。有没有办法做到这一点?

Pax 插件听起来有点像它正在这样做,但它似乎是基于提升 Felix 容器的?这不是我想要的,我正在处理一个已经在运行的远程容器。

有没有这样的东西作为命令行工具而不是GUI存在?

4

3 回答 3

40

有多种方法可以将依赖包部署到 OSGi 容器。这里是其中的一些:

1 Felix OBR 包存储库

您首先需要使用诸如 bindex 之类的工具为可用的捆绑软件创建一个 XML 索引文件。如果您使用的是 maven-bundle-plugin,那么它会自动在 ~/.m2/repository/repository.xml 中维护一个 OBR 索引。

使用 OBR 命令行界面加载索引:

> obr:addUrl file:/Users/derek/.m2/repository/repository.xml

然后让 OBR 部署您的目标包,并根据 OBR 索引确定依赖项:

> obr:deploy com.paremus.posh.sshd
Target resource(s):
-------------------
   Paremus Posh Ssh Daemon (1.0.23.SNAPSHOT)

Required resource(s):
---------------------
   Paremus Command API (1.0.23.SNAPSHOT)

Optional resource(s):
---------------------
   Paremus Config Admin Commands (1.0.23.SNAPSHOT)
   Paremus OSGi & LDAP Types (1.0.23.SNAPSHOT)

2 阿帕奇卡拉夫

Karaf 支持“功能”,它们基本上是提供该功能所需的捆绑包列表:

karaf@root> features:info obr
Description of obr 2.0.0 feature
----------------------------------------------------------------
Feature has no configuration
Feature has no dependencies.
Feature contains followed bundles:
  mvn:org.apache.felix/org.apache.felix.bundlerepository/1.6.4
  mvn:org.apache.karaf.shell/org.apache.karaf.shell.obr/2.0.0
  mvn:org.apache.karaf.features/org.apache.karaf.features.obr/2.0.0

karaf@root> features:install obr

3 日食处女座

Virgo 使用计划来定义组成应用程序的工件,它能够从本地和远程存储库自动提供应用程序的依赖项,包括捆绑包、计划、计划存档 (PAR) 和配置。

4 帕雷穆斯敏捷

Nimble 使用 OBR(或它自己的扩展)存储库索引,自动部署激活目标包所需的所有依赖包(并在目标包停止时卸载它们)。它还可以检测其他依赖项,例如 WAB 包需要 Web 扩展程序并根据可配置策略自动安装一个。

Nimble 也可以配置为启动 Glassfish,以便其功能可用于 Glassfish 容器中的捆绑包。

下面的示例还显示了在激活 sshd 时会自动安装日志记录支持:

$ posh
________________________________________
Welcome to Paremus Nimble!
Type 'help' for help.
[denzil.0]% nim:add --dry-run com.paremus.posh.sshd@active
-- sorted parts to install --
4325   osgi.resolved.bundle/ch.qos.logback.core:0.9.22
-- start dependency loop --
5729   osgi.resolved.bundle/com.paremus.util.logman:1.0.23.SNAPSHOT
5727   osgi.active.bundle/com.paremus.util.logman:1.0.23.SNAPSHOT
3797   osgi.resolved.bundle/ch.qos.logback.classic:0.9.25.SNAPSHOT
3792   osgi.resolved.bundle/slf4j.api:1.6
-- end dependency loop --
436   osgi.resolved.bundle/org.apache.mina.core:2.0.0.RC1
6533   osgi.resolved.bundle/sshd-core:0.3
398   osgi.resolved.bundle/com.paremus.posh.sshd:1.0.23.SNAPSHOT
396   osgi.active.bundle/com.paremus.posh.sshd:1.0.23.SNAPSHOT

(免责声明:我是 Paremus 的开发人员)

5 阿帕奇·费利克斯·戈戈

gogo 是新的 RFC147 标准命令行 shell。它已经在 Felix、Karaf、Nimble 中使用,并且很快将在 Glassfish 中使用。

Gogo 允许您以脚本的形式运行任何可以交互键入的命令。因此,您可以生成要安装的捆绑包列表并将其转换为脚本,甚至可以从工作配置中捕获已安装的捆绑包,以便可以从头开始重新创建它。

于 2010-10-13T23:43:16.797 回答
2

如果您创建一个 OSGi 应用程序和一个经典 Java 应用程序,它们做同样的事情并使用相同的库,那么您将需要完全相同的 JAR 集。最大的区别在于能够显式定义您的依赖项(并可能为您的应用程序生成更精细的 JAR)。

据我所知,只有一个纯 OSGi 服务器(Eclipse 的 Virgo,以前是 Spring 的 DM 服务器)。Glassfish 和 Websphere 支持 OSGi,但我没有玩过它们,所以我不能说太多。我能说的是,它们都需要一个 OSGi 容器,通常是 Eclipse 的 Equinox 或 Apache 的 Felix。

您的问题似乎真的是关于配置应用程序(确定需要部署的内容)。我知道对于 Maven 3.0,他们使用 Eclipse 的 P2 供应框架做了很多工作。

对于您的应用程序,您是部署 EAR 还是 WAR?对于其中任何一个,您的构建系统都需要生成包含所有依赖项的存档,否则它将无法工作。为什么你有问题有点令人困惑,因为人们使用 Maven,因为它为他们的构建进行传递依赖管理。

于 2010-10-13T19:51:04.097 回答
-1

您的问题的一个基本方面尚未解决。

Glassfish 确实是一个成熟的应用程序服务器,就像大多数现代应用程序服务器一样:它们为您提供了一个Web 容器(您将在其中部署 WAR 档案)、一个Java EE 容器(用于在 JAR 和 EAR 档案中部署 EJB),以及集成一个OSGI 容器。然后后者用于应用服务器自己的内部启动机制。

本质上,您可以针对三个容器。现代 IDE 和构建工具为您提供了打包逻辑以针对其中任何一个目标的方法。所以问题就变成了:我如何用所有这些可能性来构建我的应用程序?

有一些非常重要的技术问题不容忽视。(我在这里专注于客观和事实的考虑,远离任何主观选择、哲学、策略和其他可能对您的最终决定也有很大影响的上下文相关考虑):

  1. OSGI 容器不为您提供隐式或声明式 线程管理持久性事务管理Web 和 Java EE 容器等服务。因此,请计划分析这些问题并生成代码来管理您的线程并处理这些线程上的事务传播。当然,OSGi 提供了所有必要的 API 来处理这些方面,但确实需要编码(AOP 可能会有所帮助)。另一方面,在 Web 和 Java EE 容器中,您依赖容器管理的服务和/或使用 EJB 注释、部署描述符和服务器管理的对象(如池)来简单地声明您想要并行的线程数、线程的大小连接池,以及哪些事务属性。两种风格都有优点和缺点(OSGi 中的过程与 java app.server 中的声明或隐式)。
  2. OSGI 提供了一种有序的方式来加载你的代码,管理模块依赖,甚至处理同一个模块的多个共存版本动态添加/删除和启动/停止所谓的(OSGI 部署单元),前提是你的包确实包含处理潜在启动/停止问题的逻辑,例如在停止时正确中断所有启动的线程——这些线程可能已经通过其他依赖模块“传播”。另一方面,Java EE 和 Web 容器通常会装载依赖 JAR 的副本,这可能会产生更多的胖部署,除非您开始考虑应用服务器的类加载器层次结构并利用它将“共享库”部署为普通的 POJO JAR,或打包在 JAR 中的 Java EE bean。无论如何,在后面的情况下,管理部署依赖项成为一个问题,您必须至少在构建时使用像 Maven 这样的框架来解决这个问题。然后,在运行时,您可能必须根据依赖项编写启动/停止级联脚本;否则,利用特定的应用程序服务器扩展来解决 Web 和 Java EE 容器(例如 Weblogic)中的这些动态部署问题。
  3. 如前所述,现在大多数应用程序服务器都使用 OSGI 来管理它们自己的启动顺序。随着平台复杂性的增加、API 的增加、组装单个最终产品的开发团队数量的增加以及大量第三方/开源组件的使用,OSGI 成为不可或缺的服务器启动工具,以确保稳定版本和所有组件的一组一致的兼容版本。想想 Eclipse IDE:拥有数千个插件的目录和很高的新版本发布率,如果没有 OSGI 作为基础,这个 IDE 将是一个非常脆弱的平台。现代应用服务器面临同样的问题。
  4. 基于上述考虑,您可能很想将代码分层到一些设施中,这些设施可以基于 OSGI 层,而 OSGI 层又为托管业务逻辑的 Java EE bean 层提供核心服务,然后是 Web servlet 层进行接口整体......但另外两个问题弹出:(a)你如何使所有这些组件一起通信?OSGI 有自己的存储库机制,除非在 OSGI 中明确发布,否则其他模块不会看到已部署的 JAR 的 API。Web 和 Java EE 容器使用完全不同的存储库技术来访问彼此组件的接口,即 JNDI。同样,查看您的特定应用程序服务器文档,该文档可能提供从 OSGI 包处理 Java EE bean 的方法,反之亦然(例如 Glassfish,自 V3 以来);但要小心线程管理和事务范围。(b) 您将如何避免干扰应用程序服务器的启动顺序?与 Web 和 Java EE 容器相比, OSGI倾向于成为核心系统功能(在供应商的治理下)面向托管您的应用程序代码(在您的管理下)。升级您的应用服务器或安装新版本可能会干扰您自己的 OSGI 部署;因此,您必须检查问题并组织您的部署脚本。

问题很丰富,分析也很复杂。进一步的考虑必须考虑要构建的应用程序的性质。此外,如果您打算使用开源 Spring 和/或 Camel 等开发框架,以及 Oracle Fusion SOA 组合、JBoss Switchyard 等供应商特定框架,您将需要考虑许多其他技术限制。

在这些问题上没有“一刀切”的答案,从本质上讲,这证明了当前过多的重叠技术是合理的。

When that architecture question is first solved, then you can look to optimize productivity with a suitable configuration management and deployment repository.

于 2015-09-15T11:02:08.567 回答