Eclipse SCADA+Nashorn调用Java类时触发ClassNotFoundException异常
你在Eclipse SCADA的Nashorn脚本里调用自定义Java类时遇到的类找不到问题,在OSGi环境里其实很常见——毕竟每个bundle都有独立的类加载器,默认情况下org.eclipse.scada.vi.ui.draw2d这个bundle没法直接访问你自定义的类。我给你一步步拆解解决:
核心原因
报错信息里明确指出countdown2.test2 cannot be found by org.eclipse.scada.vi.ui.draw2d_0.3.0.v20160226-1536,这说明运行脚本的bundle(org.eclipse.scada.vi.ui.draw2d)的类加载器找不到你的countdown2.test2类,本质是OSGi的依赖配置没做好。
解决方案
1. 配置Bundle的导入导出(最关键)
你需要在自定义类所在的bundle和org.eclipse.scada.vi.ui.draw2d之间建立正确的依赖关系:
- 导出自定义包:打开你的Java类所在bundle的
MANIFEST.MF,在Export-Package中添加countdown2;version="x.y.z"(替换成你的bundle实际版本号),把countdown2包暴露给其他bundle访问。 - 导入依赖包:找到
org.eclipse.scada.vi.ui.draw2d的MANIFEST.MF(如果是自定义项目可直接修改,第三方bundle则通过插件依赖配置),在Import-Package中添加countdown2;version="[x.y.z, x.y.z]",让它能加载你的自定义包。 - 添加运行依赖:在Eclipse的运行配置里,确保你的自定义bundle被添加到
Plug-ins列表中,并且状态为ACTIVE。
2. 验证类的部署与Bundle状态
- 确认
countdown2.test2类已经正确编译,存在于你的bundle的target/classes或bin目录下,打包时要确保这个类被包含在内。 - 打开OSGi控制台(运行Eclipse SCADA时添加
-console参数),执行ss命令查看你的自定义bundle是否处于ACTIVE状态;再执行bundle <你的bundleID>,检查Exported Packages里是否有countdown2。
3. 手动指定类加载器(备选方案)
如果没法修改org.eclipse.scada.vi.ui.draw2d的依赖配置(比如它是第三方bundle),可以在脚本里手动指定你的bundle的类加载器来加载类:
// 获取你的bundle的类加载器 var platform = Java.type("org.eclipse.core.runtime.Platform"); var bundle = platform.getBundle("你的bundle的symbolic name"); // 例如"com.yourcompany.countdown" var classLoader = bundle.getClassLoader(); // 用指定的类加载器加载你的类 var MyJavaClass = Java.type('countdown2.test2', classLoader);
注意:这种方式需要你的bundle已经被OSGi框架加载,并且你有访问org.eclipse.core.runtime.Platform的权限。
4. 检查脚本执行上下文
确保你的脚本是在正确的Symbol Controller中运行,有些UI组件的脚本执行上下文会有类加载器限制,比如可视化组件的脚本,要确认依赖的bundle已经被UI层的bundle正确引入。
内容的提问来源于stack exchange,提问作者Adrian Salinero

