从 V3.0 开始,Eclipse 经过选择开放服务网关协议(Open Services Gateway Initiative,OSGi)来替换先前版本中不稳定的 Eclipse 插件技术,从而实现了一次巨大飞跃。此次转变对于用户来讲几乎是透明的,由于如今所使用的插件的安装和操做看上去和之前的插件没有什么不一样。 shell
由 于 Eclipse 如今是在 OSGi 上构建的,所以咱们在图 1 中看到的插件是功能完整的 OSGi 包。(图 2 显示了使用 OSGi 控制台运行 Eclipse 实例内的包。)经过使用 OSGi,Eclipse 支持业内承认的开放标准而且如今能够利用 OSGi 提供的功能,包括安全性、HTTP 服务、用户管理和其余功能。Eclipse 对 OSGi 的使用已经见到成效,由于咱们看到插件间报告的冲突在减小而 Eclipse 的应用在持续增长。 apache
OSGi Alliance 是一个独立的、非盈利性组织,负责 OSGi 技术,相似于 Eclipse Foundation 的职能。OSGi Alliance 负责制定描述 OSGi 技术的规范。简言之,OSGI 技术为应用程序开发提供了一种面向服务的基于组件的平台。各类实现都是基于这些规范的。最多见的一个实现是 Equinox,它是 Eclipse 的规范实现。OSGi 的另外一个常见实现是 Apache 的 Felix 项目。 安全
在咱们继续以前,本文假定您具备 Eclipse 和 OSGi 方面的工做经验。若是不具有的话,建议先阅读 Scott Delap 的文章 “了解 Eclipse 插件如何使用 OSGi”,而后再来研究 OSGi 控制台。 app
此次冒险的第一步是使用 插件开发环境(Plug-in Development Environment,PDE)在 Eclipse 中建立一个简单的 OSGi 包。为此,须要使用 PDE 建立一个新的插件项目(File > New > Project > Plug-in Project)。在建立新的插件项目的过程当中,确保设定正确的选项。首先,选择插件目标平台做为 OSGi Framework,具体来讲就是 Equinox。最后,为了简短起见,使用 PDE 提供的 Hello OSGi Bundle 模板(参见图 3)。咱们如今建立好了将在本文中使用的包。 框架
回页首 eclipse
如今咱们已经有了本身的 Hello 包,能够继续并启动框架以得到 OSGi 控制台。要启动框架,咱们能够利用 PDE 的 OSGi Framework 启动配置。首先,转至启动配置菜单(Run > Run ...)并为 Hello 包建立一个 OSGi Framework 启动配置(参见图 4)。此外,确保仅选择运行 Hello 包所需的必要的包。完成此操做的一种简单方法是在启动配置中按 Deselect All 键并选中 Hello 包,接下来按 Add Required Plug-ins 键。 ide
每当走过 Eclipse 开发人员的汇集地,您总会听到人们在谈论着两个有魔力般的字眼:插件 和 包。 二者有区别么?在营销副总裁看来,两个术语是同义的。包是插件,插件就是包。咱们彷佛一直在交替地使用这两个术语。可是,从专业的视角来看,事情并不是如 此。准确地说,Eclipse 插件是利用扩展注册表的 OSGi 包(即,包的根目录中有 plug-in.xml)。而 OSGi 包就是 OSGi 包。 测试
完成启动配置并准备就绪以后,可使用启动配置对话框中的 Run 按钮来启动咱们的包。完成后,应当会看到相似图 5 的结果。 ui
在图 5 中,咱们看到 Hello 包已启动(使用控制台中打印的 HelloWorld 消息,表示包已被启动)而且看到osgi>提示符。OSGi 提示符相似于 DOS 或者 Bash 提示符,能够在提示符处输入对 OSGi 实例起做用的命令。在本例中,发出ss命令,该命令将快速显示全部内容的状态。建议您在普通的 Eclipse 实例中尝试此命令,将发现全部内容只不过是隐藏着的一个 OSGi 包。要得到普通 Eclipse 实例的 OSGi 控制台,只需用-console参数启动 Eclipse。 this
在 OSGi 动态环境中,能够轻松地启动和中止包。要测试此操做,让咱们使用简单的 Hello 包。只需用stop命令便可中止包,而后用start命令启动包。您应当会看到相似图 6 的结果。
OSGi 系统的另外一个强大的方面是可以在运行的 OSGi 实例中添加、删除和更新包 —— 全部操做均无需从新启动 Java™ 虚拟机。图 7 演示了包的安装和卸载。
有时在包或插件尝试启动的初始化过程当中会发生错误。OSGi 控制台提供了一个有用的命令 ——diag—— 能够帮助您调试与包初始化相关的问题。例如,让咱们来检验一下图 8,在尝试启动 Hello 包时,得到一个错误。为了帮助诊断错误,对包运行diag命令并将看到运行时环境中缺乏一个导入包。
命令 | 描述 |
---|---|
start | 启动给定了 ID 或符号名称的包 |
stop | 中止给定了 ID 或符号名称的包 |
install | 为当前实例添加一个给定了 URL 的包 |
uninstall | 删除当前实例的具备给定 URL 的包 |
update | 为当前实例更新给定 URL 的包 |
active | 列出当前实例中全部活动的包 |
headers | 列出具备给定 ID 或符号名称的包的标头 |
ss | 列出在当前实例中注册的全部包的简短状态 |
services <filter> | 列出给定了正确过滤器的服务 |
diag | 在给定 ID 或符号名称的包上运行诊断程序 |
还有不少其余 OSGi 命令可用。这里列出的命令是我认为最有用的命令。要得到全部命令的列表,只需在控制台中键入help。
人们说 Eclipse 的绝妙之处就在于它的可扩展性。控制台是以相似方式扩展的。这是十分重要的,由于做为一名开发人员,您可能向用户提供某种服务。经过扩展控制台,您可使高级用户或管理员可以调试关于服务的问题。
控制台不使用熟悉的扩展点,它具备一种简单的可扩展性机制。让咱们经过几个示例来讲明控制台的可扩展性。
使用过 UNIX® 风格的系统的人都会熟悉uname命令,该命令将打印关于运行的操做系统的名称、版本和其余信息。在 OSGi 上下文中,有各类不一样风格的 UNIX 的方法就能够有 OSGi 控制台的不一样实现(例如 Apache Felix、Knopflerfish 等等)。
扩展 OSGi 控制台的最重要部分是CommandProvider接口。但愿扩展控制台的客户机必须实现此接口。实现此接口后,下一步是启动带有"_"的方法名称。这些方法将表示控制台中可用的命令。就这么简单!参见清单 1 中的示例。
public class Activator implements BundleActivator, CommandProvider { private BundleContext context; public void start(BundleContext context) throws Exception { this.context = context; Hashtable properties = new Hashtable(); context.registerService\ (CommandProvider.class.getName(), this, properties); } public String getHelp() { StringBuffer buffer = new StringBuffer(); buffer.append("\tuname - returns framework information\n"); return buffer.toString(); } public void stop(BundleContext context) throws Exception {} public void _uname(CommandInterpreter ci) throws Exception { String vendor = context.getProperty(Constants.FRAMEWORK_VENDOR); String version = context.getProperty(Constants.FRAMEWORK_VERSION); String osName = context.getProperty(Constants.FRAMEWORK_OS_NAME); String osVersion = context.getProperty(Constants.FRAMEWORK_OS_VERSION); System.out.println("\n " + vendor + " " + version + " (" + osName + " " + osVersion + ")"); } }
包自己可能从未质疑过本身的存在,这里提供了一个简单示例,它将打印出一个包是 vanilla 包仍是 Eclipse 插件。(记住,二者都仍是包!)清单 2 经过添加新方法并修改getHelp()方法来构建先前的示例。
... public String getHelp() { StringBuffer buffer = new StringBuffer(); buffer.append("\twhatami - \ returns whether the bundle is a plug-in or not\n"); buffer.append("\tuname - returns framework information\n"); return buffer.toString(); } public void _whatami(CommandInterpreter ci) throws Exception { try { long id = Long.parseLong(ci.nextArgument()); Bundle bundle = context.getBundle(id); URL url = bundle.getEntry("plugin.xml"); if(url != null) { System.out.println("\n I'm \ (" + bundle.getSymbolicName() + ") a plug-in"); } else { System.out.println("\n I'm \ (" + bundle.getSymbolicName() + ") not a plug-in"); } } catch (NumberFormatException nfe) { System.out.println("\n Error processing command"); } } ...
图 9 中显示了咱们的工做结果。
本 文演示了如何使用 OSGi 控制台以及如何扩展控制台。在此过程当中,咱们查看了控制台以及如何扩展控制台的几个示例。您如今已经更加熟悉控制台而且知道了如何在平常的 Eclipse 开发中使用控制台。使用控制台可能甚至会让您回想起玩 Doom and Quake 时的情景。