OSGi 中的服务引用

发布于 2024-08-13 09:32:31 字数 225 浏览 6 评论 0原文

一旦从捆绑上下文中检索到 OSGi 服务的实例,该服务停止时该实例是否会失效?

我的初步测试表明,即使服务包停止后,服务实例也可以使用,这与我对 OSGi 动态特性的理解相矛盾。

我想这可以归结为从 OSGi 容器中的另一个包检索服务(通过 ServiceTracker)实际上做了什么,它是创建一个新实例还是为您提供一个指向在容器中注册的实例的指针?

服务停止后使用服务实例是否有危险?

Once an instance of an OSGi service is retrieved from the bundle context does it become invalidated when the service is stopped?

My initial tests show that the service instance can be used even after the service bundle is stopped, which contradicts my understanding of the dynamic nature of OSGi.

I suppose this boils down to what retrieving a service (via ServiceTracker) from another bundle in the OSGi container actually does, does it create a new instance or does it give you a pointer to the instance that is registered in the container?

Are there any dangers in using the service instance after the service has been stopped?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

溺ぐ爱和你が 2024-08-20 09:32:31

这是一个非常好的问题,因此我深入研究了规范以寻找明确的答案。事实证明,有一整节都在讨论这个问题 - 请参阅从 OSGi 服务平台核心规范,第 4 版,版本 4.2

根据规范回答您的问题:

未注册的服务的行为是未定义的。此类服务
可以继续正常工作或自行决定抛出异常。

并防止潜在问题:

捆绑包必须侦听框架生成的事件以清理和删除过时的内容
参考文献。

该规范还提供了一些如何最大限度地减少过时引用的后果的提示。

This is a very good question so I digged into the specification in search for a definitive answer. It turns out that there is a whole section talking about this problem - see section 5.4 Stale References starting on page 132 of OSGi Service Platform Core Specification, Release 4, Version 4.2.

To answer your question according to the specification:

The behavior of a service that becomes unregistered is undefined. Such services
may continue to work properly or throw an exception at their discretion.

And to prevent potential problems:

Bundles must listen to events generated by the Framework to clean up and remove stale
references.

The specification also gives some tips how to minimize the consequences of stale references.

鹿港巷口少年归 2024-08-20 09:32:31

你是对的,它与 OSGi 的动态本质相矛盾。我认为,尽管 OSGi 容器和服务本身的不同实现可能表现不同,但不能保证该服务可用。

例如,如果服务是使用 Spring DM 创建并注册的,那么检索到的服务实际上是底层实现的基于 Spring 的代理,并且该实现仍然可能消失。因此,直接引用实现的服务引用可以防止该对象被删除,而基于代理的引用则不会。

You are right in that it is contradictory to the dynamic nature of OSGi. I believe that there is no guarantee that the service will be available, although different implementations of OSGi containers and services themselves may behave differently.

For example, if the service was created and registered with Spring DM, then the service retrieved is actually a Spring based proxy to the underlying implementation, and the implementation can still disappear. Thus a service reference that refers directly to an implementation may keep that object from being removed, whereas the proxy based reference will not.

找回味觉 2024-08-20 09:32:31

OSGi 规范指出:

捆绑包是可见的实体
在正常的应用程序编程中。为了
例如,当一个包停止时,所有
其服务将被取消注册。

因此,您不应该能够从已停止的捆绑包中获取服务。但从技术上讲,它是可以使用的,至少只要您持有对服务对象的引用(没有人可以从您手中夺走它,并且它不会被 GC 回收)。但我不认为使用该服务是省钱的。它可能依赖于其他捆绑包资源,这些资源在捆绑包停止后不可用。

The OSGi specification says:

Bundles are entities that are visible
in normal application programming. For
example, when a bundle is stopped, all
its services will be unregistered.

So you shouldn't be able to get a service from a stopped bundle. But technically it may be possible to use it, at least as long as you hold a reference to the service object (nobody can take it away from you and it will not be GC'd). But I don't think that it is save to use the service. It may depend on other bundle resources, that are not available after the bundle has stopped.

煮茶煮酒煮时光 2024-08-20 09:32:31

一旦 OSGi 服务的实例被
从捆绑上下文中检索确实
当服务失效时
停止了吗?

不,引用本身不会失效。只要容器内有东西保存着它,它就无法被 GC 回收。

然而,它是否仍然有用,仅取决于服务实现本身,而不是容器。

我的初步测试表明,即使服务包停止后,服务实例仍然可以使用,这与我对 OSGi 动态特性的理解相矛盾。

规范本身表明不应保留此类引用,但实施者应注意正确实施规范;意味着不存在矛盾,只是您可以实现和部署未按照规范正确运行的捆绑包。

我想这可以归结为从另一个包中检索服务(通过 ServiceTracker)
在 OSGi 容器中实际上是这样做的,它是创建一个新实例还是给你一个指针
到容器中注册的实例?

容器不会创建新的服务实例,除非涉及 ServiceFactory(请参阅规范)。查找服务应该始终为您提供指向容器中已注册实例的指针。

服务停止后使用服务实例是否有危险?

这仅取决于服务的实现;但是,通过在捆绑包中执行此操作,您会自动创建一个不符合规范的捆绑包。

在实践中,许多服务都是为了释放资源和引用而实现的,并且将不再正确响应。

Once an instance of an OSGi service is
retrieved from the bundle context does
it become invalidated when the service
is stopped?

No, the reference itself does not become invalidated. As long as something within the container is holding it, it can also not be GC'ed.

However, whether or not it will be still useful, depends only on the service implementation itself, not the container.

My initial tests show that the service instance can be used even after the service bundle >is stopped, which contradicts my understanding of the dynamic nature of OSGi.

The specifications itself indicate that such references shouldn't be held, but it's up to the implementer to take care for implementing the specifications correctly; means there is no contradiction, there is only the fact that you can implement and deploy bundles which don't behave correctly according to the specifications.

I suppose this boils down to what retrieving a service (via ServiceTracker) from another bundle
in the OSGi container actually does, does it create a new instance or does it give you a pointer
to the instance that is registered in the container?

The container does not create new instances of services, except if there is a ServiceFactory involved (see specs). Looking up a service should always give you a pointer to the registered instance in the container.

Are there any dangers in using the service instance after the service has been stopped?

That only depends on the service implementation; however, by doing so in a bundle, you automatically create a bundle that is not conform with the specs.

In practice, many services are implemented to release resources and references and will not respond properly any longer.

埋葬我深情 2024-08-20 09:32:31

关于您的问题,服务停止后使用服务实例是否有危险。引用 4.2 核心规范(5.4 陈旧引用):

服务的行为变成
未注册是未定义的。这样的
服务可能会继续正常工作
或向他们抛出异常
酌情权。

我不想在这里引用规范的整个部分,但以下句子很好地讨论了使用陈旧引用的危险:

过时引用是对属于以下对象的 Java 对象的引用:
到已停止或关联的包的类加载器
具有未注册的服务对象。标准 Java 没有
提供任何通用方法来清理陈旧的引用,并捆绑
开发人员必须仔细分析他们的代码以确保过时的
参考文献已被删除。

过时的引用可能有害,因为它们会阻碍 Java
垃圾收集器收集类,可能还有实例,
停止的捆绑包。这可能会导致内存显着增加
使用并可能导致更新本机代码库失败。捆绑使用
强烈建议服务使用服务跟踪器或
声明式服务。

Regarding your question whether it is dangerous to use a service instance after the service has been stopped. To cite from the 4.2 core spec (5.4 Stale References):

The behavior of a service that becomes
unregistered is undefined. Such
services may continue to work properly
or throw an exception at their
discretion.

I dont want to cite the whole section of the spec here, but the following sentences are a good discussion about the danger of using stale references:

A stale reference is a reference to a Java object that belongs
to the class loader of a bundle that is stopped or is associated
with a service object that is unregistered. Standard Java does not
provide any generic means to clean up stale references, and bundle
developers must analyze their code carefully to ensure that stale
references are deleted.

Stale references are potentially harmful because they hinder the Java
garbage collector from harvesting the classes, and possibly the instances,
of stopped bundles. This may result in significantly increased memory
usage and can cause updating native code libraries to fail. Bundles using
services are strongly recommended to use either the Service Tracker or
Declarative Services.

秋日私语 2024-08-20 09:32:31

服务参考永远不应该被保留作为参考。您应该始终在运行时查找服务。这会将您与 OSGI api 联系起来,但这并不总是需要的。

看看
- OSGI服务跟踪器
- OSGI声明服务
- OSGI 蓝图
- 弹簧DM
- 豌豆莓
- iPojo

都为您处理动态,其中大多数没有 OSGI api 可供使用。

问候,

林·托伦

A service reference should never be kept as a reference. You should always look up a service at runtime. This ties you to the OSGI api however, whihc is not always wanted.

Have a look at
- OSGI serviceTracker
- OSGI declarative services
- OSGI BluePrint
- Spring DM
- Peaberry
- iPojo

which all take care of the dynamism for you, most of them with no OSGI api to use.

Regards,

Leen Toelen

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文