java OSGi 包启动级别是如何定义的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7462259/
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 20:04:51  来源:igfitidea点击:

How is the OSGi bundle start level defined?

javaosgi

提问by xconspirisist

How is the OSGi bundle start level defined?

OSGi 包启动级别是如何定义的?

I am using Apache felix and would like to persist the start level across framework executions. I do not anticipate a need to change the start level of a bundle very frequently at all an an entry in Manifest.MF seems the most sensible. I've to org.osgi.framework.startlevel but have not seen a practical example.

我正在使用 Apache felix 并希望跨框架执行保持启动级别。我不认为需要非常频繁地更改包的起始级别,Manifest.MF 中的条目似乎是最明智的。我必须到 org.osgi.framework.startlevel 但还没有看到一个实际的例子。

I am also using maven with the maven-bundle-plugin, if there is an elegant way to incorporate the start level in the POM that would be brilliant.

我还将 maven 与 maven-bundle-plugin 一起使用,如果有一种优雅的方式将开始级别合并到 POM 中,那将是非常棒的。

采纳答案by seh

Bundles don't define their own start level at build-time; the administrator or agent that installsthe bundle into the framework defines it.

包在构建时没有定义自己的开始级别;安装到框架中的管理员或代理定义了它。

The core framework defines a Start Levelinterface in section 8. Quoting:

核心框架在第 8 节定义了一个Start Level接口。引用:

The Start Level API provides the following functions:

  • Controls the beginning start level of the OSGi Framework.

  • Is used to modify the active start level of the Framework.

  • Can be used to assign a specific start level to a bundle.

  • Can set the initial start level for newly installed bundles.

Start Level API 提供以下功能:

  • 控制 OSGi 框架的起始启动级别。

  • 用于修改Framework 的活动启动级别。

  • 可用于为捆绑分配特定的起始级别。

  • 可以为新安装的包设置初始启动级别。

The last two are relevant to your inquiry here. Section 8.3.4—Changing a Bundle's Start Level—indicates that the framework will store an assigned start level persistently.

最后两个与您在此处的查询相关。第 8.3.4 节 —更改 Bundle 的起始级别— 表明框架将永久存储分配的起始级别。

If you're using Apache Felix, there are several ways you can install bundles and assign their start level, whether explicitly or by allowing them to inherit a default start level for installed bundles:

如果您使用的是 Apache Felix,您可以通过多种方式安装包并指定它们的启动级别,无论是显式还是允许它们继承已安装包的默认启动级别:

Also, see the felix.startlevel.bundleproperty, which controls bundles installed through means other than those above.

另外,请参阅felix.startlevel.bundle属性,它控制通过上述方式以外的方式安装的包。

As for setting a manifest property (such as with Maven at build time), there used to be a way to do this in Equinox—now deprecated—but there is no standard means for a bundle to indicate to the framework what its proper start level should be.

至于设置清单属性(例如在构建时使用 Maven),曾经有一种方法可以在 Equinox 中执行此操作(现在已弃用)但没有标准方法让包向框架指示其正确的启动级别应该。

回答by Mike Van

X,

X,

I think there is an easier way to do what you're talking about. Currently, you are using the Felix OSGi implementation directly, which is very powerful. However, if you'd like the kind of granular control over bundle deployment, that's built into an OSGi container called Karaf. Think of Karaf as a car whose engine can be either Felix or Equinox. It something that rides on top of OSGi framework implementations and offers additional functionality. For example, Karaf provides a Provisioning mechanism. Deploying multiple bundles is called Provisioning. Because Provisioning isn't part of the OSGi spec, different OSGi containers implement provisioning in different ways. In Karaf, we do this through something called a features.xml file.

我认为有一种更简单的方法来做你所说的。目前,您正在直接使用 Felix OSGi 实现,它非常强大。但是,如果您希望对包部署进行这种精细控制,那么它内置于一个名为 Karaf 的 OSGi 容器中。将 Karaf 想象成一辆发动机可以是 Felix 或 Equinox 的汽车。它基于 OSGi 框架实现并提供附加功能。例如,Karaf 提供了一个 Provisioning 机制。部署多个捆绑包称为供应。因为供应不是 OSGi 规范的一部分,所以不同的 OSGi 容器以不同的方式实现供应。在 Karaf 中,我们通过称为 features.xml 文件的内容来完成此操作。

In a features.xml file, you identify a specific set of bundles you want deployed together. Then you name that group. In this file you can also identify the specific start order you'd like Karaf to deploy the bundes.

在 features.xml 文件中,您确定要一起部署的一组特定捆绑包。然后你命名那个组。在此文件中,您还可以确定希望 Karaf 部署捆绑的特定启动顺序。

A word on OSGi start-orders. A bundle cannot be started until all mandatory wiring has occured. This means that you can define a start order, but OSGi takes this as guidances, not mandatory. For example, if you have a bundle A that requires an import of bundle b's "foo" package, you can tell the container to start A before B all you want. But it won't respect that order because in reality B needs to be started in order to A to start. Its ok though, the container knows (usually) what order to start bundles in.

关于 OSGi 启动命令的一句话。在所有强制接线发生之前,不能启动捆绑。这意味着您可以定义启动顺序,但 OSGi 将此作为指导,而不是强制性的。例如,如果您有一个包 A 需要导入包 b 的“foo”包,您可以告诉容器在 B 之前启动 A,然后再启动 B。但它不会尊重该顺序,因为实际上 B 需要启动才能启动 A。不过没关系,容器知道(通常)以什么顺序启动包。

The rub comes in the use of optional versus mandatory imports in a bundle. If your bundle imports b.foo, but that import is optional, the container will respect the bundle start order (A then B). But watch out, if A actually needs to import b.foo, but you've marked it as optional, A will start without Wiring to b.foo, and A will throw a ClassNotFoundException. This nasty little bug can occur when using the various packages in Spring.

问题在于在捆绑中使用可选导入和强制导入。如果您的包导入 b.foo,但该导入是可选的,则容器将遵循包启动顺序(A 然后 B)。但请注意,如果 A 确实需要导入 b.foo,但您已将其标记为可选,则 A 将在不连接到 b.foo 的情况下启动,并且 A 将抛出 ClassNotFoundException。在 Spring 中使用各种包时可能会出现这个讨厌的小错误。

To make your life easy, Spring does the majority of its imports as "optional". If a given spring bundle actually needs to resolve a dependancy before working and that import is marked as optional, your bundles will deploy sparodically. Of course,the fix for this is to create a bundle fragment that modifies the bundle imports to "mandatory", but that's really beyond the scope of your question.

为了让您的生活更轻松,Spring 将其大部分导入作为“可选”进行。如果给定的 spring 包在工作之前确实需要解决依赖关系,并且该导入被标记为可选,则您的包将随机部署。当然,解决此问题的方法是创建一个将包导入修改为“强制”的包片段,但这确实超出了您的问题范围。

I hope this clarifies things for you.

我希望这能为你澄清事情。

回答by Roland

bundle.adapt(BundleStartLevel.class).setStartLevel(startlevel);