写点什么

《精通 Eclipse 插件开发》书评及采访

2015 年 3 月 09 日

InfoQ Java 的定期撰稿人 Alex Blewitt 博士最近出版了《精通Eclipse 插件开发》,该书是去年出版的《 Eclipse 4 插件开发实例》的续写。与其前任类似,这本书本质上来说也是一本教程,不过它假设读者对构建 Eclipse 集成开发环境插件的基础已经比较熟悉,可以快速深入更高级的主题。

该书的前两章主要探究开发者如何针对 Eclipse 框架的各个部分进行插件开发,以构建一个可以读取 RSS 和 Atom 源的新闻阅读器示例。第一章使用 JFace——用于构建 Eclipse 用户界面的基于标准窗口工具包(SWT)的组件库——来创建基础的新闻摘要向导。这个向导会被整合到通用导航框架(Common Navigator Framework)中,然后包浏览器调用该框架,为用户提供项目内容的树状视图。

第二章介绍了 Eclipse 扩展的注册机制。这一机制已经广泛应用于 OSGi 运行时环境中,不过本书作者向读者展示了如何在该环境外使用这一机制构建一个可以让其他插件在 OSGi 或 Eclipse 运行时环境之外提供功能的插件。

本书剩余部分的注意力则主要集中于 OSGi 框架之上。第三章为读者提供了关于 OSGi 服务的精彩介绍,这是在其他 Eclipse 插件开发书籍中很少提及的。OSGi 服务可以有多个不同版本在运行时环境同时共存并且还可以在其他的 OSGi 环境(如 Felix)中正常运行。本章中还包含了声明式服务(Declarative Services)和 Blueprint 的详细对比,声明式服务是在 OSGi 运行时环境中以声明的形式实例化服务的原有机制,而 Blueprint 则是在几个小版本之后引入的另外一种机制,本质上是为了完成了同样的工作。

第四章介绍了内嵌于 Eclipse 4 并且 Felix 和 Equinox 均已采用的 Gogo shell。在探究了包括变量、字面值和函数在内的语法之后,作者继续介绍如何通过使用 Gogo 自带的 osgi:addCommand 命令和编写自定义的 Java 类并将其注册为 OSGi 服务,扩展控制台的能力。第五章介绍了如何将原生代码加载到 OSGi 或 Eclipse 应用中,除此之外还介绍了如何利用片段包(fragment bundles)扩展框架的能力。

第六章详细介绍了类加载器(ClassLoader),以及 OSGi 如何利用类加载器支持包的分离。由于许多类库错误地假设每个 JVM 只有一个类加载器,Blewitt 还调查了这些类库的升级策略,以便它们可以在 OSGi 环境中正常运行。

构建 Eclipse 插件或任何基于 OSGi 的应用都需要将组件分割成更小的高内聚低耦合的模块,这个过程有时可能比较困难。在第七章中,作者为读者展示了一些通用技术、设计模式和当前最佳实践以帮助这部分工作的完成。

最后几章覆盖了如下主题:使用 OSGi 事件总线构建反应式应用,用 Eclipse P2 生成升级站点以及如何为 Eclipse 编制帮助文件。

本书的编写思路简明清晰,并且辅以精心选择的实例,能够帮助读者真正理解讨论中涉及的各种概念。本书的大部分内容针对模块化做了详细阐述,特别是 Eclipse 自身所使用的 OSGi 框架。此外,本书还提供了关于类加载的精彩介绍。

InfoQ 采访了本书作者 Alex,尝试挖掘出更多关于本书的信息。

InfoQ:你是否早就打算为您的第一本书编写续集,如果没有,那是什么促使您这样做呢?

Alex在编写完《Eclipse 4 插件开发实例》之后,我原计划休息一段时间不再编写新的书籍;写书是件十分耗费精力的事情,特别是当你还有全职工作要做的时候。不过因为第一本书销量相当不错,出版商询问我是否有兴趣编写一本更加深入一些的书籍。而我确实有一些想法想要写出来,特别是关于 OSGi 模式这方面,而且这次续写的机会太好了,也让人难以割舍。

而且由于篇幅和所面向的受众群体等原因,在第一本书里有些主题并没有覆盖到;譬如说,简单的插件并不需要创建向导、更新站点和帮助文档。不过,如果要构建一个稍大一些的 Eclipse 插件集合或者希望其他人也能够在这些框架之上继续构建,那就需要理解扩展注册机制是如何工作的以及如何创建定制化的扩展点。在进阶书籍中,在类加载机制和 OSGi 服务层等方面还可以走得更加深入一些。

InfoQ**:这本书为读者提供了关于 OSGi和类加载器的相当精彩的介绍。除了 Eclipse插件开发者之外,你认为还有哪些开发人员会从中受益?**

Alex:OSGi 是过去十年中最未被充分重视的技术之一。对于大型的 Java 服务来说,OSGi 无处不在,更不用说各种 IDE。Adobe 有许多工具是构建在 OSGi 之上的,诸如 Liferay 和 Paremus 之类的大规模系统也使用 OSGi 驱动它们的平台。对于上面这些案例来说,其主要的关注点都在于模块化和低耦合的服务。现在我们看到其他的平台上逐渐出现这些特征;向不同的 REST 服务迁移的一般趋势就是这样一个例子。通过模块化管理代码复杂性的理念是最终的必然选择——就在我们谈话的时候,即使是 JDK 都正在被模块化。不过与模块化密不可分则是向后兼容,或者版本兼容。大部分开发人员默认会遵循语义化的版本控制(Semantic Versioning)(更多详情参见 http://www.semver.org )而其中的核心理念是不要破坏向后兼容的客户端。不论你正在构建 Java 服务或者用 REST 服务联结多种不同的语言,这一点仍然适用;如果你不能控制整个单元的部署,那就必须要考虑兼容性问题。像 Scala 这类语言,认为向后兼容性的代价太高而没有必要这么做,这也就是为什么通常在这些语言中见不到像 Java 那么多样的类库生态系统。

回到之前关于 OSGi 章节的问题——我觉得 Eclipse 正在朝更多 OSGi 服务的方向发展而不是静态工厂访问方法。领会 Eclipse 未来发展方向而非过去发展历史的关键在于理解 OSGi 的服务模型,因此应该是 Eclipse 插件开发作者的必读书目。然而,更大范围的 Java 世界也正在朝模块化的方向转移,因此向后兼容就变得愈发重要。从 OSGi 模型中我们可以学到很多经验,即使是对于那些以前没有了解过 OSGi 的 Java 开发者来说也会受益良多。我希望我所写的这本书可以让读者了解到如何用 OSGi 完成工作,而不是自以为是地向读者介绍为什么其他人数十年来一直使用它。

关于类加载器,虽然 Java 开发人员无形中一直在使用它,但很少有人能完全理解它。一个类加载器提供两类服务;一个服务是从(加载自某一来源;可能是本地或远程的 URL,也可能是一个数据库,甚至还可能是动态生成的)字节序列中创建一个类,另一个服务则是将这个类的空间划分到不同的区段。例如,如果你部署了两个使用 Log4J 的 Web 应用到一个 Tomcat 或 Jetty 服务器上,每个 Web 应用都会分别加载 Log4J 的类。这样,在运行时就会有两个 LogFactory 类被加载到 JVM 中;其中一个对第一个 Web 应用可见,而另外一个则只对第二个 Web 应用可见。即使是一个静态的引用——例如 LoggerFactory.getLogger(Example.class) 返回的引用——也会有两个 Logger 类的实例,每个实例只对一个类加载器可见。尽管 Java 语言让它看起来像一个单例,实际上只有幼稚的 Java 开发人员才会认为一个 JVM 只有一个实例。这样,不同的 Web 应用就可以有不同的日志级别,这对于在一个共享实例的服务器上调试单个应用的场景来说非常实用。撰写类加载器介绍的一部分原因是为了解释它们的工作机制,因为类加载器是所有的 Java 应用和应用服务器运转的基础,虽然这一点并不那么显而易见。

InfoQ**:对我而言,从来也没有弄清楚为什么 OSGi既有声明式服务(从版本 4开始引入)又有 Blueprint**(从版本 4.2开始引入)——看起来这两种服务所起到的作用基本上是一致的。为什么最终会同时存在两个服务呢?

**Alex****** 声明式服务和 Blueprint 两者都提供了一种执行服务和服务依赖自动组装的方法,从这个角度来说他们是相似的。在底层实现上,这两种服务都使用 OSGi 服务模型;他们寻找不断变化的服务并基于此动态地重新配置系统。

声明式服务更加接近于服务运行时的本质;声明式服务一直处于等待状态,直到发现对某个服务的需求,并且在发布这个服务之前,它所有的依赖都是可用的。所以,假设你正在查找一个 CacheService,只有这个 CacheService 的所有依赖都满足要求,这个服务才会存在。这可以解决应用启动时可能会出现的诸多排序问题;在它的支持层存在之前,即使有了 CacheService 服务也没有任何意义,所以你根本就不需要看到它。

而 Blueprint 则会在服务实现可用之前发布服务代理。他们大胆假设在将来的某个时间点这个服务必然会存在,所以将 CacheService 提前发布出来。当客户端第一次尝试使用这个服务时,它会尝试实例化并满足全部的依赖关系,如果依赖关系无法满足,就会抛出一个运行时异常。

Blueprint 与声明式服务的另一个区别在于获取到的代理可以被分发给各种不同的对象并且可以被持久化成某个类的最终成员变量;一旦分配了一个代理,你将一直使用这个代理,即使底层的服务不断地发生变化。这样对于不熟悉 OSGi 动态特性的开发者,可以更加容易地将那些不期望服务不断变化的 Java 代码与服务集成。Blueprint 的配置严重也依赖于 Spring 的 Bean 配置文件,这样从 Spring 迁移到更加动态的 OSGi 模型时,会更加容易理解。

正如我在书中所提到的,如果迁移之前的环境是 Spring,那么用 Blueprint 上手会更加容易一些,只需要简单地复制粘贴 Spring 的配置文件就可以完成迁移工作。如果你之前没有 Spring 的经验,那么声明式服务可能会更简单一些。不过这两种情况下,你只需要基于一个服务的依赖表达这个服务即可,系统将会帮你完成实例化和组装的工作,而不需要手动完成所有的工作。最终,这两种服务在底层都使用了 OSGi 的服务模型,像 REST 一样,如何获取服务并不重要,当服务准备就绪后,只需要用标准 API 与其交互即可。

InfoQ**:在关于 Blueprint的讨论中,你好像对 Gemini持批评态度,考虑到其对 Spring的依赖,同时注意到在 Spring应用开发者向 OSGi迁移时这一点可能会很有用。我在想关于这一点你是否能稍微展开说一下。OSGi是否提供与 Spring类似的能力?你是否认为 OSGi环境中遗留的 Spring**内核是必要的?

Alex:Gemini 和 Aries 都提供 Blueprint 服务,就像 Jetty 和 Tomcat 都支持 Servlet 一样。就像你即可以将一个 WAR 包部署到 Jetty 也可以部署到 Tomcat 一样,如果一个 OSGi 应用使用了 Blueprint 服务,你即可以将其部署到包含 Gemini 的 OSGi 容器中也可以将其部署在包含 Aries 的 OSGi 容器中。考虑等价的包(bundles)时,(在充分考虑其他情况前提下)这两种情况的差异之一就是它们所需要的依赖关系集。Aries 需要 5 个包(其中 2 个是 SLF4J 日志包)。Gemini 则需要安装 9 个包,其中 6 个是 Spring 包。此外,Spring 不再与 OSGi 的元数据一起构建,如果想要使用它,就必须要从资源库中后置处理这些包。

关于 Spring 是不是必须遗留在 OSGi 环境中……,有许多基于 Spring 的好项目完成了很好的工作,其中的大部分都以某种方式与 Spring 上下文进行交互。Spring 的确普及了依赖注入技术,并且将目标从‘如何实例化 Bean’变成了‘请给我这个 Bean’。通过服务 OSGi 也可以完成相同的工作;关键的区别在于服务可以被动态的移除、重启、升级甚至是在线替换。当然,并不是每个应用都需要这种层次的动态性而且 Spring 应用通常会以整体的方式进行构建和部署,因此要根据不同的目标采用不同的方案。尽管 OSGi 很好地实现了动态特性,可能有些读者已经发现分区化和模块化应用的能力会带来更大的收益。总结一下,Spring 能够将应用开发提升到一定层次——松耦合的 Bean——不过在应用部署和配置方面仍然需要将其作为一个整体看待。OSGi 则接手了 Spring 遗留的问题,能够动态地更新应用配置并且可以在线替换应用,而不需要停机时间来重新启动应用。这在分布式服务能够发挥作用的云端环境或网络环境下特别有用。

我想最终一旦你迁移到一个 OSGi 平台,Spring 容器可能会不再适用,不过在这个过程中 Spring 还是有很多用处。Blueprint 可以帮助完成从 Spring 到 OSGi 的转化。在平台即服务和云端部署方面很可能会看到 OSGi 的大幅增长;可以将单个 OSGi 应用在重复的分布式服务集合启动。

书中示例的源代码可以从此处下载,这里是一个试读章节。

关于本书作者

Alex Blewitt**** 博士在伦敦的一家投资银行工作,业余时间跟踪 OSGi 和 Eclipse 相关的最新资讯。尽管之前曾经作为 EclipseZone 的编辑和 2007 年 Eclipse 大使的提名者,他的日常工作与 Java 和 Eclipse 都没关系。他剩下的很有限的时间主要用来陪伴他年轻的家庭成员,如果天气好,会带他们去飞行。

查看英文原文: Book Review and Interview: Mastering Eclipse Plug-in Development

2015 年 3 月 09 日 07:292229
用户头像

发布了 75 篇内容, 共 58.1 次阅读, 收获喜欢 4 次。

关注

评论

发布
暂无评论
  • 实战:纯手工打造和运行一个 Servlet

    今天我们抛弃IDE、拒绝框架,自己纯手工编写一个Servlet,并在Tomcat中运行起来。

    2019 年 5 月 18 日

  • WebShpere 7 支持基于 OSGi 的应用部署和 SCA 集成

    WebShpere应用服务器V7的功能包针对OSGi应用和Java持久化API2.0提供了标准实现,该实现遵循OSGi Blueprint Container和Java EE 6 JPA 2.0规范。该版本还提供了一个可选功能,可以把Java应用作为版本化的OSGi Bundle的一个集合来装配、部署和管理。IBM WebSphere团队最近宣布正式发布的功能包是基于Apache的项目Aries和OpenJPA。

  • 模块化编程和 Jigsaw 项目最新早期访问版本使用教程

    Jigsaw项目是Java下一个主要版本Java 9的一个标志性特性,定会让模块化编程成为Java编程的主流。经过多年的讨论和数不清的JSR和JEP,Jigsaw的最终形式已经基本确定。本教程将讨论模块化编程的各个方面以及向Jigsaw项目的迁移。

  • 模块化 Java:静态模块化

    模块化是大型Java系统的一个重要特征。在这些项目中构建脚本和项目通常被划分为多个模块,以便改进构建过程,但是在运行时却很少考虑划分模块的问题。本文是“模块化Java”系列文章的第二篇,讨论静态模块化的相关内容,包括如何创建bundle、将其安装到OSG引擎以及怎样建立bundle之间的版本依赖。

  • 唯有套路得人心:谈谈 Java EE 的那些模式

    这些模式,就是我们在搭建全栈架构、设计的工作过程中,不断总结和应用的“套路”。

    2019 年 10 月 7 日

  • 第 6 讲 | 动态代理是基于什么原理?

    如何分类Java语言呢?通常认为,Java是静态的强类型语言,但是因为提供了类似反射等机制,也具备了部分动态类型语言的能力。

    2018 年 5 月 17 日

  • GlassFish OSGi-JavaEE (一): GlassFish 与企业级 OSGi 开发

    欢迎进入GlassFish OSGi-JavaEE专题!自从GlassFish v3开始,一个新的特性被加入到GlassFish中,那就是GlassFish OSGi-JavaEE。本专题将分为九个部分向大家介绍GlassFish OSGi-Java EE相关的知识,本文对GlassFish OSGi-JavaEE做简单的介绍并简要叙述企业级的OSGi开发的现状。

  • Peter Kriens 重返 OSGi 联盟

    Peter Kriens是OSGi的推动者之一,日前宣布重返OSGi联盟,到2012年初为止他一直在这里担任总监长达11年。InfoQ联系到了Peter,与他讨论了重返OSGi及其jpm4j项目的最新情况。

  • 构建 Java API 的艺术:Do's and Don'ts(英文演讲)

    演讲嘉宾Jonathan Giles,微软资深云开发者布道师。内容介绍作为Java开发者,我们都是站在巨人的肩膀上,使用其他人开发的API,从而走的更远。有时我们也要提供自己的API供其他人使用。构建Java API也不是没有风险的,我们必须非常熟悉语言特性,必须理解破坏兼容性的影响,必须担负起创建完美的文档等责任,还有最重要的,我们必须保持克制。Jonathan Giles将带来的这场演讲,将向开发者分享如何构建自己的API,不管是内部使用、开源项目还是商用库。重点谈的也是构建Java API,而不是REST API或其他内容。Jonathan有十多年的Java API构建经验,他最初在Sun和Oracle的Java团队,参与了 Java 7、8、9和10等版本的开发工作;最近他加入微软担任云开发者布道师,和工程师团队紧密协作,改进Azure上的Java API。演讲将分享开发者应该遵循的技巧,以及应该避免的问题。

    2018 年 11 月 8 日

  • 程序员怎么学习运维知识?

    每个程序员都应该学习运维知识,保证我们对软件的运行有更清楚地认识,而且部署工作是非常适合自动化的。

    2019 年 3 月 22 日

  • 模块化 Java:动态模块化

    模块化是大型Java系统的一个重要特点。建立脚本和项目时通常都将其劈成若干模块以便改善构建过程,但是这种模块化思想在运行时却很少被考虑到。本文是 “模块化Java”系列文章的第三篇,讨论动态模块化,内容涉及如何解析bundle类、bundle如何变化、以及bundle之间如何通信。

  • 2008 EclipseCon 综述

    上周的EclipseCon大会给超过1400个与会人员带来了300份演讲资料和教程。Infoq注意到这一精采会议文献选辑包括了新宣布的Eclipse Runtime以及EclipseLink和OSGi的进展。

  • SpringSource 新应用服务器发布 摒弃 Java EE

    今天SpringSource摇身一变,踏入应用服务器提供商的行列,并且举着SpringSource应用平台(SpringSource Application Platform)的黄钺白旄对现有的Java EE服务器阵营发起挑战。SpringSource应用平台是构建在Spring、OSGi和Apache Tomcat之上的应用服务器,这个新的应用服务器摒弃了原有的Java EE服务器标准,自然而然地将Spring编程模型展现其中,随之而来的还有一套基于OSGi内核构建的全新部署和打包(非EAR文件)系统。

  • Java 9、OSGi 以及模块化的未来(第二部分)

    The flagship feature of Java 9 will be the new Java Platform Module System (JPMS). Given the maturity of OSGi there were technical, political and commercial reasons why another Java module system will soon exist. In this article we compare the two from a technical perspective and see how JPMS and OSGi can work together.

  • 比较 Eclipse 扩展和 OSGi 服务

    最近,Neil Bartlett在其博客上重新发布了一篇文章,对Eclipse扩展及多种用途的OSGi服务进行了比较分析。

  • 模块化 Java:声明式模块化

    本文是模块化Java系列文章的第4篇,介绍的是声明式模块化。文中描述了组件如何以声明的方式来定义并组织在一起,而无需让代码依赖于OSGI API。声明式服务将被用来动态地把POJO们联系在一起,这样代码就再也不需要显式地注册或使用OSGi服务了,也无需任何启动顺序依赖。

  • Neil Bartlett 访谈:关于 OSGi 与新发布的 Bndtools 2.0

    Neil Bartlett目前是流行的OSGi Eclipse插件工具Bndtools的维护者,他宣布Bndtools 2.0已经释放。InfoQ采访了Neil Bartlett,以了解Bndtools和OSGi的一些基本知识。

  • 第 184 讲 | 狼叔:2019 年前端和 Node 的未来—大前端篇(上)

    狼叔谈2019年对大前端现状及未来发展趋势的理解。

    2019 年 3 月 11 日

  • Struts 2 试验热部署插件

    Apache Struts这个已被广泛应用的Java Web应用框架纳入了一个很有价值的新特性,该特性对热部署插件提供了支持。Struts的开发成员Don Brown在上星期宣布,他们已经开始动手开发Struts 2的OSGi插件,当这项工作完成以后,就可以实时的添加、移除或是升级插件,而无需重启整个应用。

发现更多内容

架构师训练营-食堂就餐卡系统设计

彭灵俊

极客大学架构师训练营

食堂就餐卡系统设计

Acker飏

极客大学架构师训练营

第一课 架构师的自我修养

Geek_bobo

架构文档编写

金桔🍊

架构师训练营 Week 01 学习总结

Kun

极客大学架构师训练营

架构师训练营第0期-第1周-作业一

极客大学架构师训练营

什么是架构师?

呆呆栋

作业1:食堂就餐卡系统设计(UML)

蒜泥精英

什么叫架构师

平淡人生

极客大学架构师训练营

聊聊架构师

Jerry Tse

随笔杂谈 极客大学架构师训练营 作业

作业2-学习心得

蒜泥精英

作业一:食堂就餐卡系统设计

独孤魂

极客大学架构师训练营

食堂就餐卡系统架构设计

~就这样~

架构师训练营第01周——UML练习

李伟

极客大学架构师训练营

架构师训练营-学习总结

~就这样~

食堂就餐卡系统架构视图

行下一首歌

极客大学架构师训练营

食堂就餐卡系统设计

八两

就餐卡系统(时间太紧张,阅读了很多,我转载的这篇)

王锟

Lesson 1 架构师如何做架构 心得笔记

edd

编程好习惯 极客大学架构师训练营 架构总结

食堂就餐卡系统设计(第一周)

架构方法学习小结

行下一首歌

极客大学架构师训练营

【第一周】学习总结——架构方法、软件建模与设计文档

三尾鱼

极客大学架构师训练营

就餐卡设计文档

chengjing

就餐卡系统设计

平淡人生

极客大学架构师训练营

第一次课作业

lai

架构师训练营第0期-第1周-作业二

极客大学架构师训练营

编译运行Zookeeper源码

CoderLi

Java zookeeper 程序员 源码分析 后端

就餐卡系统架构设计

祝好

第一节课的总结

王锟

实例学习绘画UML图

张瑞浩

关于架构师这个角色的感悟

祝好

《精通Eclipse插件开发》书评及采访-InfoQ