在 Eclipse 插件中使用时 Reflections 库不工作
我使用 Reflections 库开发了一个应用程序,用于查询具有特定注释的所有类。一切都很顺利,直到我决定从我的应用程序创建一个 Eclipse 插件。然后反射就停止工作了。
鉴于我的应用程序在不属于 Eclipse 插件时工作正常,我认为这应该是类加载器问题。 因此,我将插件激活器类的类加载器、上下文类加载器以及我能想象到的所有其他类加载器添加到我的 Reflections
类中,但没有成功。这是我的代码的简化版本:
ConfigurationBuilder config = new ConfigurationBuilder();
config.addClassLoaders(thePluginActivatorClassLoader);
config.addClassLoaders(ClasspathHelper.getContextClassLoader());
config.addClassLoaders("all the classloaders I could imagine");
config.filterInputsBy(new FilterBuilder().include("package I want to analyze"));
Reflections reflections = new Reflections(config);
Set<Class<?>> classes = reflections.getTypesAnnotatedWith(MyAnnotation.class); //this Set is empty
我还尝试将要加载的类的 URL 添加到 ConfigurationBuilder
类,但没有帮助。
有人可以告诉我是否有办法让 Reflections
作为 Eclipse 插件的一部分工作?或者我应该更好地寻找另一种替代方案?非常感谢,我真的很困惑。
I have developed an application using the Reflections library for querying all the classes having a particular annotation. Everything was working like a charm until I decided to create an Eclipse plug-in from my application. Then Reflections stop working.
Given that my application is working fine when not part of an Eclipse plug-in, I think it should be a class-loader problem.
So I added to my Reflections
class the classloaders of the plug-in activator class, the context class loader, and all other class loaders I could imagine, without any success. This is a simplified version of my code:
ConfigurationBuilder config = new ConfigurationBuilder();
config.addClassLoaders(thePluginActivatorClassLoader);
config.addClassLoaders(ClasspathHelper.getContextClassLoader());
config.addClassLoaders("all the classloaders I could imagine");
config.filterInputsBy(new FilterBuilder().include("package I want to analyze"));
Reflections reflections = new Reflections(config);
Set<Class<?>> classes = reflections.getTypesAnnotatedWith(MyAnnotation.class); //this Set is empty
I also tried adding URLs of the classes I want to load to the ConfigurationBuilder
class, but it did not help.
Could someone tell me if there is a way to make Reflections
work as part of an Eclipse plug-in ?, or should I better look for another alternative ?. Thanks a lot, I am really puzzled about it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我假设您已经知道如何创建捆绑包(否则,请检查这个)。
经过对 Reflections API 的一些调试和探索后,我意识到问题在于 Reflections 根本无法读取 OSGi URL(bundleresource://...),从而导致异常:
并且这个建议:
所以我相信为 OSGi 实现一个 UrlType (例如
class BundleUrlType Implements UrlType {...}
) 并像这样注册它:应该使 Reflections API 可从包内部使用。反射依赖项应添加到 Eclipse 插件项目中,如下所述 此处。
这是我的示例 MANIFEST.MF 在添加所需的 jar 后的样子:
注意:使用了 Reflections v. 0.9.5
这是一个示例 UrlType 实现:
这就是我在 Activator 类中创建反射的方式:
最后一点非常令人困惑,但是仍然很重要:如果您在 Eclipse 中运行插件(运行为/OSGi 框架),您还必须将类输出目录添加到反射路径模式(即“bin”或“target/classes”)。尽管如此,发布的插件不需要它(要构建插件/捆绑包,请执行“导出”->“可部署插件和片段”)。
I assume you already know how to create bundles (otherwise, check this).
After some debuging and exploration of Reflections API I have realised that the problem is that Reflections simply fails to read OSGi URLs (bundleresource://...) resulting in an exception:
and this suggestion:
So I believe implementing a UrlType for OSGi (e.g.
class BundleUrlType implements UrlType {...}
) and registering it like this:should make Reflections API usable from inside a bundle. Reflections dependencies should be added to the Eclipse Plugin project as described here.
This is how my sample MANIFEST.MF looked like after adding needed jars:
Note: Used Reflections v. 0.9.5
Here's a sample UrlType implementation:
And this is how I create reflections in the Activator class:
The last bit is very confusing, but still important: if you run your plugin inside of Eclipse (Run As / OSGi Framework) you have to add also your classes output directory to the Reflections path patterns (i.e. "bin" or "target/classes"). Although, it's not needed for a released plugin (to build a plugin/bundle do "Export"->"Deployable plug-ins and fragments").
仅供记录,以防其他人遇到同样的问题。
这里对 Vlad 的答案进行了一个小修改,以避免必须将输出目录添加到 Reflections 路径模式中。
区别仅在于 BundleDir 类。在我的所有测试中它似乎工作正常:
Just for the records in case someone else has the same problem.
Here a small modification to the answer of Vlad in order to avoid having to add the output directory to the Reflections path patterns.
The difference is only in the BundleDir class. It seems to work fine in all my tests:
Eclipse 是构建在 OSGi 之上的,而您面临着 OSGi 类加载……这不是一场容易获胜的战斗。
看看 Neil Bartlett 的这篇文章: OSGi 准备 — 加载类。您也可以通过 google 搜索“OSGi 好友策略”。
Eclipse is build on top of OSGi and you are up against OSGi class loading... and that is not an easy battle to win.
Have a look at this article of Neil Bartlett: OSGi Readiness — Loading Classes. Also you can google for "OSGi buddy policy".