如何部署OSGi应用程序和依赖项?

时间:2010-10-13 18:37:43

标签: java maven-2 osgi dependency-management

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

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

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

是否有任何镜头存在如命令行工具而不是GUI?

3 个答案:

答案 0 :(得分:38)

有许多方法可以将依赖包部署到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 Apache Karaf

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 Eclipse Virgo

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

4 Paremus Nimble

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 Apache Felix Gogo

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

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

答案 1 :(得分: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,因为它为他们的构建做了传递依赖管理。

答案 2 :(得分:-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应用程序中的隐式)。
  2. OSGI提供有序方式加载您的代码,管理模块依赖,甚至处理多个共存版本相同模块的>,动态添加/删除和启动/停止所谓的捆绑(OSGI部署单元),前提是您的捆绑包含处理潜在启动的逻辑/停止问题,如正确中断停止时所有启动的线程 - 可能已经传播的线程'通过其他依赖模块。另一方面,除非您开始考虑应用程序服务器的类加载器层次结构,否则Java EE和Web容器通常会包含可能产生更多胖部署的从属JAR的副本它有利于部署共享库'或者作为普通的POJO JAR,或者作为JAR的Java EE bean。无论如何,在后面的情况下,管理部署依赖性成为一个问题,你必须至少在构建时使用像Maven这样的框架来解决这个问题。然后,在运行时,您可能必须根据依赖性脚本启动/停止级联;否则,请利用特定的应用程序服务器扩展来解决Web和Java EE容器(例如Weblogic)中的这些动态部署问题。
  3. 如前所述,OSGI现在被大多数应用程序服务器用来管理自己的启动序列。随着平台复杂性的增加,API的增加,开发团队数量的增加以组装单个最终产品,以及使用众多第三方/开源组件,OSGI成为不可或缺的服务器 - 启动工具,以确保稳定版本和所有组件的一系列兼容版本。想想Eclipse IDE:有了数千个插件的目录和高速率的新版本,这个IDE将是一个非常脆弱的平台,没有OSGI作为基础。现代应用服务器面临同样的问题。
  4. 基于以上考虑,您可能很想将分层您的代码放入一些可以基于OSGI层的工具中,而OSGI层又提供核心服务一个托管业务逻辑的Java EE bean层,然后是一个Web servlet层来连接整个...但是还会出现另外两个问题: (a)如何让所有这些组件一起通信? OSGI有自己的存储库机制,除非在OSGI中明确发布,否则其他模块将无法看到部署的JAR的API。 Web和Java EE容器使用完全不同的存储库技术来访问每个其他组件。接口,即JNDI。再次,查看您的特定应用程序服务器文档,该文档可能提供从OSGI包中解决Java EE bean的方法,反之亦然(例如,Glassfish从V3开始);但要谨慎对待线程管理和事务范围。 (b)您如何避免干扰应用服务器启动序列? OSGI倾向于成为核心系统功能(在供应商的治理下),与Web和Java EE容器相比,自然面向托管您的应用程序代码(在您的治理下)。升级应用程序服务器或安装新版本可能会干扰您自己的OSGI部署;因此,您必须检查问题并组织部署脚本。
  5. 问题很丰富,分析很复杂。进一步的考虑必须考虑到构建应用程序的性质。此外,如果您打算使用开源Spring和/或Camel等开发框架,以及Oracle Fusion SOA组合,JBoss Switchyard等特定于供应商的开发框架,您还需要考虑许多其他技术限制。

    没有"一刀切的"回答这些问题,从本质上说,证明目前过多的重叠技术是合理的。

    首次解决该架构问题时,您可以通过合适的配置管理和部署存储库来优化生产力。