0

我有一个名为的活动包bundleA,它实现了一个使用从另一个包调用Example的方法调用的类。实现并通过加载(感谢SPI Fly)。在from中,我需要获取调用的捆绑包(不通过or因为我无法更改 API)。我可以得到's ,但不能得到调用包的:doSomething()ExampleImplExampleServiceLoaderExampleImpl.doSomething()bundleABundleWiringdoSomething()BundleBundleContextbundleABundleWiringBundleWiring

Bundle bundleA = FrameworkUtil.getBundle(ExampleClass.class);
BundleWiring bundleWiringOfBundleA = bundle.adapt(BundleWiring.class);

如何获得调用包的BundleWiring

在我的特殊情况下,调用包总是一个 WAB,它恰好在Liferay Portal 7.0中运行。因此,如果有特定于 Liferay Portal 的解决方案,我会接受,但更通用的 OSGi 解决方案也可以。

请注意,我希望调用捆绑的捆绑接线而不是依赖于当前捆绑接线的每个捆绑的捆绑接线。我知道我可以获得依赖于当前捆绑布线的捆绑布线,但这不会帮助我专门获得调用捆绑:

Bundle bundleA = FrameworkUtil.getBundle(ExampleClass.class);
List<BundleWires> bundleWires =
    bundleWiring.getProvidedWires(BundleRevision.PACKAGE_NAMESPACE);
bundleWires.get(0).getRequirerWiring();
4

4 回答 4

0

在 Liferay 中,调用 WABBundleContext存储在ServletContextas 中"osgi-bundlecontext"

BundleContext bundleContext = servletContext.getAttribute("osgi-bundlecontext");
Bundle bundle = bundleContext.getBundle();
BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);

因此,只要您可以访问ServletContextLiferay 中的 ,您就可以获得调用包的BundleBundleWiring

于 2017-11-16T21:11:03.050 回答
-1

你不能这样做。OSGi 根本不干预跨包方法调用,因此您可以用来尝试获取此信息的唯一方法是 Java 调用堆栈,使用Thread.currentThread().getStackTrace(). 然而StackTraceElement,这个返回的对象只给你类名而不是java.lang.Class对象,所以没有办法将它们关联回包。

除了不可能之外,我非常怀疑这是否是一个好主意。您根本不应该导出实现类,更不用说尝试使它们对调用者敏感。

如果您需要实现对调用包敏感的行为,那么实现该功能的规范且正确的方法是使用ServiceFactory接口注册服务。

于 2017-10-30T21:49:19.523 回答
-1

您可以使用BundleTracker并对正在安装的所有 WAB 做出反应。然后,您可以检查每个 WAB,例如扫描类以获取注释。

声明式服务和现有的 WAB 支持以这种方式工作。不过,编写这样的扩展程序并不容易。

于 2017-10-31T07:54:00.473 回答
-1

你说你不能改变API。但是你能改变调用包吗?如果是这样,那么您可以使用调用捆绑包而不是原始服务的“代理”服务。然后,您可以将Bundle和/或传递BundleContext给代理服务并将您的依赖逻辑放在那里。

想到的另一个选择是使用ThreadLocal变量将此信息传递给被调用的包,但我不确定这种方法可能有什么副作用。

于 2017-10-31T08:15:48.227 回答