2

我目前正在努力为我们的 OSGi 捆绑包提供一些对 OSGi 非常不友好的 3rd-party 库。其中一个库(我已经使用 bnd 将其变成了一个包)设法加载它不应该加载的类(至少通过 OSGi 规则)。让我们假设 bundle 被调用Foo,并且它加载类的包被调用bar

Foobar作为可选导入。不过这应该没关系,因为没有可以导出的捆绑包bar。我没有使用任何引导委托。jar包含的-filebar位于应用程序类路径上(OSGi 框架嵌入在我的应用程序中运行)。

显然Foo以某种方式绕过了 OSGi 类加载基础设施。如何才能做到这一点?我很确定它不使用自定义类加载器,因为它没有理由拥有一个(没有功能Foo提供需要这样的东西)。那么,bundle 可以使用哪些标准的、开箱即用的方法来绕过 OSGi 类加载?

4

4 回答 4

1

如果类在应用程序类加载器上可用,这将起到作用:

BundleContext.class.getClassLoader().loadClass("bar.X")

如果您可以通过加载器加载任何类,则可以获取所有其他类。当然,如果您要运行安全性,您可以禁止访问类加载器。

于 2013-08-02T09:20:38.120 回答
1

您使用的是什么 OSGi 框架?您是否有命令提示符命令或其他方式来请求有关包的详细信息?OSGi 规范允许您进行详细调查,并且大多数框架为 OSGi PackageAdmin 和其他 API 提供了匹配的命令/接口。

其他 OSGi 框架也会发生这种情况吗?

如果您使用ProSyst 的 mBedded Server作为 OSGi 框架,您可以使用命令发现谁在从哪里加载什么

pkginfo [<package>[ <package>]]- 显示指定包的依赖关系。如果没有参数,您将收到有关框架中所有可用包的信息。

于 2012-08-02T07:54:23.480 回答
0

以下是猜测,因为没有足够的信息来给出明确的答案。该库可能正在使用线程上下文类加载器 (TCCL)。如果bar包对您自己的捆绑包可见(即,如果它是捆绑包中的私有包)并且您调用Foo捆绑包,则可能已将 TCCL 设置为允许bar从捆绑包中加载该包。

要测试这个理论,请尝试更改您的代码以null在调用Foo包之前显式设置 TCCL:然后它会抛出一个ClassNotFoundException.

于 2012-08-02T09:38:55.597 回答
0

好吧,以下是我没有证据的假设。

实现非 OSGi可选导入的最简单方法是使用Class.forName(name)- 请注意没有 classLoader 的签名。让我们看一下源代码:

return forName0(className, true, ClassLoader.getCallerClassLoader());

反过来,让我们看看ClassLoader.getCallerClassLoader()

...
Class caller = Reflection.getCallerClass(3);
...

3 - 是要调用的帧数(例如getCallerClass(0)- 将返回反射类)。您可以轻松计算堆栈中#3 的代码,如果 OSGi 未加载它,它将使用默认的 classLoader。

于 2012-08-02T07:40:48.167 回答