2

我正在尝试评估我们的商店是否适合在没有整个 NetBeans 平台的情况下使用 NetBeans Lookup API。

到目前为止,我设法使用以下代码创建了一个项目:

 for (SomeInterface si : Lookup.getDefault().lookupAll(SomeInterface.class)) {
     si.doSomething();
 }

我还创建了几个其他项目,每个项目都有一个实现 SomeInterface 的 AnImplementation 类,以及包含引用该类的行的随附文件 META-INF/services/path.to.SomeInterface(例如“other.path.to.AnImplementation” )。

当我将这些实现项目添加到 NetBeans IDE 中主项目的库(依赖项)时,它工作正常,我可以从两个实现中看到 doSomething() 的连续结果。

我的问题是如何在不引用主项目中的子项目的情况下完成这项工作;子项目的jar在构建时不会包含在主项目的生成jar中,可以随意添加或删除它们,改变上述代码的结果。

如果我没记错的话,这就是 Lookup API 文档中宣传的行为。提前致谢。

编辑:目前,我的结论是,如果没有 NetBeans 平台(或 OSGi?),就无法检测启动时存在哪些服务提供者。您需要在类路径中引用它们的 jar,从而在启动之前识别它们。随意证明我错了。

4

2 回答 2

4

您必须在调用应用程序中引用子项目,因为这会将其放在类路径中 - 如果 jar/库不在类路径中,则 Lookup 和 ServiceLoader 等 API 将无法找到它。

如果您使用 OSGI 或 NetBeans 平台,这些系统允许您在运行时更改类路径。

Geertjans 博客有一个关于此的条目(使用 NetBeans 平台之外的 Lookup API),在他的博客中,他还引用了John O'Connors 博客,该博客对比了 ServiceLoader 和 Lookup API

编辑

我刚刚看到Jon Skeets类似问题的回答。您可以使用该-Djava.ext.dirs=lib属性将文件夹(在本例中为“libs”)设置为必须为您的类路径查找 jar 的位置。

于 2011-05-31T07:43:34.227 回答
1

据我了解,您不必将所有模块与主项目捆绑在一起即可工作。您只需要在启动应用程序时确保您的模块位于类路径中,因为全局Lookup使用幕后的ServiceLoader机制。根据您的问题,我建议考虑是否

  • 直接使用 ServiceLoader 更适合您的问题或
  • Guice这样的 DI 框架值得一试或
  • 如果 OSGI 也提供对您有用的东西并使用它。

不要误会我的意思,我非常喜欢 NetBeans 和 NetBeans 平台,但在我看来,Lookup由于上面列出的可能性,单独使用的用途有限。

于 2011-05-30T21:54:12.020 回答