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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3926863/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 03:59:42  来源:igfitidea点击:

How to deploy OSGi apps and dependencies?

javamaven-2osgidependency-management

提问by jcalvert

OSGi seems to have an excellent benefit of having small deployable artifacts by not wrapping dozens of JAR dependencies into a lib directory. However, I can't find anything that tells me an easy, reliable way to deploy dependencies to a container. For instance, I have an application that uses CXF and several Spring subprojects. If I need to deploy this application to a new Glassfish server, what would be the best way to do so, ensuring that all dependencies get installed?

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

I'm using Maven, and it would seemthat there could be some way to have a hook that looks at the META-INF/maven directory and pulls the dependency list from the pom.xml and goes and fetches the required libs (probably from a local repo). Is there a way to do that?

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

The Pax plugin sort of sounds like it's doing this, but it seems to be based around boostrapping a Felix container? Which is not what I want, I am dealing with an already running, remote container.

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

Is there any shot such a thing exists as command line tool as opposed to GUI as well?

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

回答by Derek Baum

There are a number of ways to deploy dependent bundles to OSGi containers. Here are some of them:

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

1 The Felix OBR bundle repository

1 Felix OBR 包存储库

You first need to create an XML index file for your available bundles, using a tool such as bindex. If you are using the maven-bundle-plugin, then it automatically maintains an OBR index in ~/.m2/repository/repository.xml.

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

Load the index using the OBR command-line interface:

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

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

Then ask OBR to deploy your target bundle, with dependencies determined from the OBR index:

然后让 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

2 阿帕奇卡拉夫

Karaf supports "features", which are basically lists of bundles required to provide the feature:

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

3 月蚀处女座

Virgo uses plansto define the artifacts that comprise an application and it is able to automatically supply the dependencies of an application including bundles, plans, plan archives (PARs), and configurations, from both local and remote repositories.

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

4 Paremus Nimble

4 帕雷姆斯敏捷

Nimble uses OBR (or its own extended) repository indexes, to automatically deploy all dependent bundles needed to activate a target bundle (and uninstalls them when the target bundle is stopped). It can also detect other dependencies, such as a WAB bundle requires a web-extender and automatically install one according to a configurable policy.

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

Nimble can also be configured to launch Glassfish, so that its features are available to bundles in the Glassfish container.

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

The example below also shows that logging support is automatically installed when sshd is activated:

下面的示例还显示了在激活 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

(disclaimer: I'm a developer at Paremus)

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

5 Apache Felix Gogo

5 Apache Felix Gogo

gogo is the new RFC147 standard command-line shell. It is already used in Felix, Karaf, Nimble and will soon be available in Glassfish.

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

Gogo allows you to run any commands that you could type interactively, as a script. So you could generate the list of bundles to install and convert it to a script, or even capture the installed bundles from a working configuration so that it can be re-created from a clean start.

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

回答by SteveD

If you create an OSGi application and a classic Java application that do the same thing and use the same libraries then you'll need exactly the same set of JARs. The big difference is being able to explicitly define your dependencies (and possibly produce more granular JARs for your application).

如果您创建一个 OSGi 应用程序和一个执行相同操作并使用相同库的经典 Java 应用程序,那么您将需要完全相同的 JAR 集。最大的区别是能够显式定义您的依赖项(并可能为您的应用程序生成更细粒度的 JAR)。

There's only one pure OSGi-based server that I know of (Eclipse's Virgo, previously Spring's DM Server). Glassfish and Websphere have support for OSGi, but I haven't played with them so I can't say much. What I can say is that all of them require an OSGi container and that's usually Eclipse's Equinox or Apache's Felix.

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

Your question seems to really be about provisioning the application (working out what needs to be deployed). I know that for Maven 3.0 they've done a bunch of stuff working with Eclipse's P2 provisioning framework.

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

For your application are you deploying an EAR or WAR? For either of those, your build system will need to produce the archive with all dependencies or it won't work. It's a bit confusing on why you have a problem because people use Maven because it does the transitive dependency management for their builds.

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

回答by berhauz

There is a fundamental aspect of your question that is not yet addressed.

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

Glassfish is indeed a full fledged Application server like most modern application servers: these provide you with a Web container(where you would deploy WAR archives), a Java EE container(to deploy EJB's in JAR and EAR archives), as well as integrate an OSGI container. The later is then used for the application server's own internal start-up mechanisms.

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

In essence, you may target three containers. Modern IDE's and build tools provide you with means to pack your logic to target any of these. So the question becomes: how do I architect my application with all those possibilities?

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

There are a few very important technicalissues not to lose from sight. (I focus here on objective and factual considerations, keeping out from any subjective choices, philosophy, strategy, and other context-dependent considerations that indeed may also weight much on your final decision):

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

  1. An OSGI container does not provide you with Implicit or DeclarativeThread Management, Persistence, or Transaction managementservices like the Web and Java EE containers. So, do plan to analyse these issues and produce the code to manage your threads and deal with transaction propagation over these threads for instance. Of course OSGi provides all necessary APIs to deal with those aspects, but does require coding (where AOP may help). On the other hand, in the Web and Java EE containers, you rely on container-managed services and/or use EJB annotations, deployment descriptors, and server managed objects like pools to simply declare how many threads you want in parallel, the sizes of connection pools, and which transaction attributes. There are advantages and drawbacks in either style (procedural in OSGi versus declarative or implicit in java app. servers).
  2. OSGI provides an orderlyway of loadingyour code, manage module dependencies, even deal with multiple coexisting versionsof the same module, and dynamically add/remove and start/stopso-called bundles(OSGI deployment units), provided indeed your bundle contains the logic to handle potential start/stop issues like properly interrupting all launched threads on a stop -- threads which could have 'propagated' through other dependent modules. On the other hand, Java EE and Web containers will often embark copies of dependent JAR's that may yield more fat deployments unless you start to consider your application server's classloader hierarchyand take advantage of it to deploy 'shared libraries' either as plain POJO JARs, or as Java EE beans packed in JAR's. Anyhow, in the later cases, managing deployment dependencies becomes a concern which you will have to address at least at build timeusing frameworks like Maven indeed. Then, at run time you may have to script start/stop cascades according to dependencies; else, take advantage from specific application server extensions that address these dynamic deploymentissues in Web and Java EE containers (e.g. Weblogic).
  3. As already said, OSGI is now used by most application servers to manage their own start-up sequence. With the increasing complexity of platforms, multiplication of API's, increrase in the number of development teams to assemble a single final product, as well as use of numerous third party / open source components, OSGI becomes an indispensable server-start-up toolto ensure stable releases and a coherent set of compatible versions of all components. Think about the Eclipse IDE: with a catalogue of thousands of plug-ins and a high rate of new releases, this IDE would be a much brittle platform without OSGI as a base. Modern Application servers face just the same problem.
  4. Based on above considerations, you may be much tempted to layeryour code into some facilities which you could base into the OSGI layer, which in turn provides core services to a Java EE bean layer hosting business logic, and then a Web servlet layer to interface the whole... but two other questions pop up: (a) How do you make all these components communicate together?OSGI has its own repository mechanism and the deployed JAR's API's will not be visible by other modules unless explicitly published in OSGI. Web and Java EE containers use a completely different repository technology to access each-other components' interfaces, namely JNDI. Again, look at your specific application server documentation which may provide means to address Java EE beans from OSGI bundles and vice-versa (Glassfish for instance, since V3); but be cautious about thread management and transaction scopes. (b) How would you avoid interfering in the application server start-up sequence?OSGI tends to become a core system feature (under the vendor's governance), compared to the Web and Java EE containers naturallyoriented to host your application code (under your governance). Upgrading your application server or installing a new release can interfere with your own OSGI deployments; you'll have to check the issue and organize your deployment scripts as a consequence.
  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:拥有数千个插件的目录和高发布率,如果没有 OSGI 作为基础,这个 IDE 将是一个非常脆弱的平台。现代应用服务器面临同样的问题。
  4. 基于上述考虑,您可能很想将您的代码分层到一些设施中,您可以将这些设施置于 OSGI 层中,后者又为承载业务逻辑的 Java EE bean 层提供核心服务,然后是 Web servlet 层以进行接口整个……但另外两个问题又出现了:(a) 你如何让所有这些组件一起通信?OSGI 有自己的存储库机制,除非在 OSGI 中明确发布,否则其他模块将看不到部署的 JAR 的 API。Web 和 Java EE 容器使用完全不同的存储库技术来访问彼此组件的接口,即 JNDI。再次查看您的特定应用程序服务器文档,这些文档可能提供从 OSGI 包中处理 Java EE bean 的方法,反之亦然(例如,从 V3 开始,Glassfish);但要注意线程管理和事务范围。(b) 如何避免干扰应用服务器的启动顺序?自然而然地,与 Web 和 Java EE 容器相比,OSGI 倾向于成为核心系统特性(在供应商的治理下)面向托管您的应用程序代码(在您的管理下)。升级您的应用程序服务器或安装新版本可能会干扰您自己的 OSGI 部署;因此,您必须检查问题并组织部署脚本。

The question is rich and its analysis is complex. Further consideration must take into account the nature of the application to build. Moreover, if you intend to use development frameworks like open source Spring and/or Camel, as well as vendor specific ones like Oracle Fusion SOA composites, JBoss Switchyard, etc. you will have many other technical constraints to take into consideration.

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

There is no "one-size-fits-all" answer in these matters and that, in essence, justifies the current plethora of overlapping technologies.

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

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

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