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

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

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

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

是否有任何镜头这样的东西存在作为命令行工具而不是GUI?

有许多方法可以将依赖包部署到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支持“function”,它基本上是提供function所需的捆绑包列表:

 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容器中的捆绑包可以使用它的function。

以下示例还显示在激活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允许您以脚本的forms运行您可以交互式输入的任何命令。 因此,您可以生成要安装的软件包列表并将其转换为脚本,甚至从工作配置中捕获已安装的软件包,以便可以从干净的开始重新创建它。

如果您创建一个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,因为它为他们的构建做了传递依赖管理,所以你有一个问题是有点混乱。

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

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)您如何避免干扰应用程序服务器启动序列?自然面向托管应用程序代码的Web和Java EE容器(在您的治理下)相比,OSGI倾向于成为核心系统function(在供应商的治理下)。 升级应用程序服务器或安装新版本可能会干扰您自己的OSGI部署; 您必须检查问题并组织部署脚本。

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

在这些问题上没有“一刀切”的答案,从本质上说,certificate了目前过多的重叠技术是正确的。

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