Eclipse 插件之间互相依赖, 导出Jar包安装, 报错“java.lang.NoClassDefFoundError”
在开发 插件 A 与 插件 B 过程中, Plugin A 需要使用到 Plugin B 的某一个类 ClassB, 假设 ClassB 位于 Plugin B 的 PackageB 中,
那么需要在 Plugin B 的 manifest.mf 文件中添加:
Export-Package: PackageB
并在 Plugin A 的 manifest.mf 文件中添加:
Import-Package: PackageB
以此声明依赖关系。
分别导出两个插件的 Jar 包后,拷贝到 Eclipse 的 /plugin 目录下后, 运行 Eclipse, 发现两个插件能独立正常运转,但是当 PlugA 调用 ClassB 时,系统报错:
1 java.lang.NoClassDefFoundError: org/jboss/tools/vpe/browsersim/eclipse/launcher/BrowserSimLauncher
2 at org.ayound.js.debug.launch.JsLaunchConfigurationDelegate.launch(JsLaunchConfigurationDelegate.java:101)
3 at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:858)
4 at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:707)
5 at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:1018)
6 at org.eclipse.debug.internal.ui.DebugUIPlugin$8.run(DebugUIPlugin.java:1222)
7 at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
8 Caused by: java.lang.ClassNotFoundException: org.jboss.tools.vpe.browsersim.eclipse.launcher.BrowserSimLauncher cannot be found by org.ayound.js.debug.core_2.2.0
9 at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:501)
10 at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:421)
11 at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:412)
12 at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
13 at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
14 ... 6 more
PluginA(此例中是 org.ayound.js.debug.core_2.2.0) 找不到 PluginB(此例中是 org.jboss.tools.vpe.browsersim.eclipse) 的 ClassB(BrowserSimLauncher.class)!!
折腾了很久,找到了解决方法:启动 eclipse 的时候加“-clean”选项。
可以修改 eclipse.ini 文件 或者 命令行启动, 在 windows 平台下, 可以找到 eclipse.exe, 右键创建快捷方式,再针对所创建的快捷方式图标点击右键 -> 属性 -> 目标 一栏 "...eclipse.exe" 后面加上 "-clean", 双击快捷方式运行 eclipse 即可。
为什么要以 "-clean" 的选项方式启动?
因为这样指明 eclipse 启动时所有关于插件的依赖关系都要重建而不是使用之前的缓存内容。
eclipse 官方文档描述:
if set to "true", any cached data used by the OSGi framework and eclipse runtime will be wiped clean. This will clean the caches used to store bundle dependency resolution and eclipse extension registry data. Using this option will force eclipse to reinitialize these caches.