Eclipse机制以及OSGI的体会

来源:互联网 发布:淘宝有名的好的饰品店 编辑:程序博客网 时间:2024/05/16 07:05

 

此文档是总结性文档,较宽泛,适合对Eclipse插件开发有一定了解的同事查阅。

始终忙于插件开发,对eclipse得本质并未深入研究,在这段时间的studio技术总结期间,梳理代码时,对已底层的机制认识不清,借此机会深入研究了一下。

 

在网上google了下,对OSGI的定义如下:

OSGi是什么,OSGi是一种服务运行平台。通过实现能够提供服务的符合OSGi规范的组件,用户可以将其组件发布到OSGi运行平台,供用户和其他组件使用。OSGi组件提供的服务具有两个层面的含义:系统层面,即一个组件为其他组件提供服务,这些服务体现为Java接口的实现;业务层面,即一个组件为外部系统或用户提供某种业务服务实现。

 

这种解释比较抽象不太好理解,我总结下了粗浅得概念以及好处:

OSGi可以控制访问范围,这方面Java本身控制得不够细,比如我某个类只希望供某些指定的类使用,Java是无法做到的(Proptected只能供同包和子类用)。一句话:osgi其实就是个classloader(刘成帮语)。

J2EE来说,一个web应用通常只由一个project来完成,所有得实现均在此project中完成,web应用发布后,若以后新增功能,那么只能在此工程下添加包、类等等,然后再编译打包发布。

OSGI框架是由多个project组成,此projectOSGI命名为Bundle(包),每个bundle有具体的服务或者功能,如果想增加一个全新的功能,那么你只需再开发一个bundle并部署上就可以了(OSGI支持热插拔),Eclipse的插件化概念就是基于OSGI的理念。

OSGI理念,我认为是未来的一个方向,把软件开发转向模块块开发(构件化)的方向,同时这也是一种软件设计理念,OSGI告诉我们,写软件的时候要把职责划分清楚,这是合理划分接口、类、包甚至是服务,组件的基础。以R1Studio为例,我们在软件设计划分时从大块上划分为Platform,以及各产品插件。Platform是运行得基础,主要包括运行的核心包,例如core包,model包,ui包等等。各产品插件包依赖于platform,各个bundle各司其职,职责清楚,如果想修改DE-I的业务,那么只需到DE-Ibundle去修改。如果在底层新增个通用的功能,例如调用消息格式,那么只需在platform里修改,其他产品插件就获得了这个调用功能。若新增了XX产品插件,就需要再创建一个bundle

 

EclipseOSGI的关系以及实现

    Eclipse插件开发在OSGI的显现表现方式是,每个插件(bundle)里有个META-INF\MANIFEST.MF文件,此文件的定义是符合OSGI规范的,以com.icss.ro.studio.xprocess为例,打开MANIFEST.MF,节选一个片段,如下所示:

 

Manifest-Version: 1.0

Bundle-ManifestVersion: 2

Bundle-Name: R1 DE-Integration Designer

Bundle-SymbolicName: com.icss.ro.studio.xprocess;singleton:=true

Bundle-Version: 4.1.0

Bundle-Activator: com.icss.ro.studio.xprocess.DeDesignPlugin

Bundle-Vendor: ChinaSoft International

Bundle-Localization: plugin

Require-Bundle: org.eclipse.ui,

 org.eclipse.core.runtime,

 org.eclipse.ui.views,

 org.eclipse.ui.ide,

 org.eclipse.gef,

 org.eclipse.ui.workbench.texteditor,

 org.eclipse.debug.core,

 org.eclipse.ui.forms,

 com.icss.ro.studio.core,

 com.icss.ro.eclipse.ui,

 com.icss.ro.studio.debug,

 com.icss.ro.studio.flowcore,

 com.icss.ro.studio.model,

 com.icss.ro.studio.schema,

....

Eclipse-LazyStart: true

....

Bundle-ClassPath: lib/freemarker.jar,

 lib/rodebase3.5.5.jar,

 lib/ant.jar,

 lib/rodebase4.0.5.jar,

 lib/deCommonCode4.0.8.jar,

 .

Import-Package: com.icss.ro.gr,

 com.icss.ro.gr.client,

....

Export-Package: com.icss.ro.studio.schema.wsdl.parse,

 com.icss.ro.studio.schema.wsdl.parse.bean,

 com.icss.ro.studio.schema.wsdl.parse.exception,

 com.icss.ro.studio.schema.wsdl.parse.handle,

....

 

通过上例可以看到分为几个部分:

1,基础描述部分

Bundle-ManifestVersion: 2

Bundle-Name: R1 DE-Integration Designer

Bundle-SymbolicName: com.icss.ro.studio.xprocess;singleton:=true

Bundle-Version: 4.1.0

Bundle-Activator: com.icss.ro.studio.xprocess.DeDesignPlugin

Bundle-Vendor: ChinaSoft International

 

这些项描述了此bundle的基本属性,注意Bundle-Activator描述的是此bundle的启动/停止类。

 

2,依赖关系管理

Require-Bundle:

Import-Package

这两个描述了此插件需要依赖于那些插件,osgi会根据此项描述去查找依赖插件,并启动依赖插件。其中Import-Package指定要从必需插件中显式导入的所有包。默认情况下,必须为要启动的绑定包解析所有包。还可以将包导入指定为可选项,以支持包不存在的情况。显式导入的类在 Require-Bundle 插件中的包之前解析

 

 

3,导出关系管理

Export-Package

如果别得插件依赖于本插件才能运行,那么我们需要把本插件暴露出去供其他插件调用。

 

4,其他项

Bundle-ClassPath classpath路径管理,用来管理所依赖的第三方jar包。

Eclipse-LazyStart: 是否懒加载项,true表示当需要调用时才加载。

 

这些皆可通过Eclipse PDE来实现可视化编辑,可通过可视化得操作注册到MANIFEST.MF中。

关于OSGI的规范还有很多,以上几个是最常见的规范,如果继续学习请参考OSGI R4规范。在Eclipse中,EquinoxOSGI规范的一个具体实现。打开Eclipse的安装包会注意到以下一些jar包(部分):

这些jar包就是osgi/Equniox的实现包,我们通过调用或者扩展来实现OSGI框架。关于Equinox的介绍请看最后部分

 

Eclipse 中的Plugin之间通常存在两种关系,一种为依赖,一种为扩展,对于依赖可通过OSIG中元描述(即上文降到MANIFEST.MF)信息中加入引用的plugin即可实现。但是OSGI是没有定义扩展的,Eclipse采用了一个Extension Point方式来实现Plugin的扩展功能,相当于在eclipse上又包装了一层,各插件可通过Extension Point以及Extension 来联系。

对于扩展,Eclipse采用Extension Point的方式来实现,每个Plugin可定义自己的Extension Point,同时也可实现其他PluginExtension Point,由于这个在OSGI中是未定义的,在Eclipse中通过在plugin.xml中进行描述,描述的方法为通过<extension-point id="" name="" schema="">的形式来定义Plugin的扩展点,通过<extension point="">的形式来定义实现的其他Plugin的扩展点,所提供的扩展点通过schema的方式进行描述,详细见eclipse extension-point schema规范。

关于Extension Point可举个场景,如工具栏就是工具栏Plugin提供的一个扩展点,其他的Plugin可通过此扩展点添加按钮至工具栏中,并可相应的添加按钮所对应的事件(当然,此事件必须实现工具栏Plugin此扩展点所要求的接口),工具栏的Plugin将通过 callback的方式来相应的响应按钮的动作。可见通过Extension Point的方式可以很好的提供Plugin的扩展方式以及实现扩展的方式。

以下是摘抄技术论坛的章节,简要通俗,把Eclipse的基本机制说得很清楚,供参考。若深入再需看相关代码

Eclipse的实现机制以及过程

架构上来讲Eclipse基本采用的是Kernel+Core Plugins+Custom Plugins的结构体系,除了Kernel部分外均为PluginEclipseOSGI概念中主要分为了Bundle Service,可以认为Bundle是一个模块的管理器,主要是通过BundleActivator管理模块的生命周期,而Service则是这个模块可暴露对外的服务对象,这里体现了OSGI和传统的Plugin Framework不同的一个地方,管理和静态结构分开,在OSGI中通过在manifest.mf文件中增加一些内容来发布Bundle,在其中描述了 Bundle的提供商、版本、唯一IDclasspath、暴露对外的包、所依赖的包;每个Bundle拥有自己的ClassLoader以及 context,通过context可进行服务的注册、卸载等,这些操作都会通过事件机制广播给相应的其他的Bundle;一般来说都为通过在 Bundle中编写初始需要注册的服务的方法来完成Bundle可供外部使用的服务的暴露功能;如需要调用其他Plugin提供的服务可通过 contextgetServiceReference先获取Service的句柄,再通过 context.getService(ServiceReference)的方法获取Service的实体。

遵循OSGIEclipse首先是实现了一个OSGI Impl,这个主要通过它的FrameWorkBundleHostServiceRegistryBundleContextImpl等对象来实现,实现了Bundle的安装、触发、卸载以及Service的注册、卸载、调用,在Plugin机制上 Eclipse采用的为lazy load的方式,即在调用时才进行实际的启动,采用的为句柄/实体的方式来实现,外部则通过OSGI进行启动、停止等动作,各Plugin则通过 BundleContext来进行服务的注册、卸载和调用。

那么Extension Point方面Eclipse是如何实现的呢,在加载Plugin时,Eclipse通过对plugin.xml的解析获取其中的<extension-point>节点和<extension>节点,并相应的注册到ExtensionRegistry 中,而各个提供扩展点的Plugin在提供扩展点的地方进行处理,如工具栏Plugin提供了工具栏的扩展点,那么在构成工具栏时Plugin将通过 Platform.getPluginRegistry().getExtensionPoint(扩展点ID)的方法获取所有实现此扩展点的集合 IExtensionPoint[],通过此集合可获取IConfigurationElement[],而通过这个就可以获取<extension point="">其中的配置,同时还可通过IConfigurationElement创建回调对象的实例,通过这样的方法Eclipse也就实现了对于Plugin的扩展以及扩展的功能的回调。在Plugin Framework中还涉及很多事件机制的使用,比如Framework的事件机制,以便在Bundle注册、Service注册的时候进行通知。

通过对Eclipse启动过程的分析,可清晰的看到Eclipse Kernel+Core Plugins+Application Plugins的方式,在代码中分别对应为loadBasicBundles registerApplicationServicesloadBasicBundles通过加载config.ini中的osgi.bundles 完成基本的bundles的加载,去看看这个配置会发现是org.eclipse.core.runtime还有一个 updatecore.runtime又会通过IDEApplication来完成整个Eclipse的启动,同时会注册所有与workbench相关的plugin

 

Equinox介绍

1.背景信息

Equinox项目是Eclipse开源组织提供的OSGi框架的实现。Eclipse 3.0版本开始,其内核移植到OSGi框架上。通过OSGi框架强大的组件控制,交互和管理能力,再加上Eclipse插件的自有特点,Eclipse开 源框架得到了跳跃式的发展。同时,OSGi规范得益于Eclipse IDE环境庞大的使用者,OSGi联盟也进入了快速发展时期。

OSGi的本质是将Java面向对象的开发转向面向组件和服务的开发。OSGi框架提供了一套完善的机制用于管理和控制组件(Bundle)、服务(Service)的生命周期,以及组件和服务在其生命周期内的交互。

本文及后续系列文章将以Equinox项目为基础,讲述如何实现基于OSGi的应用。

2.Equinox项目概述

Equinox项目包括OSGi R4版本规范核心框架的实现,一系列OSGi标准服务Bundle及运行基于OSGi的系统的一些基础构件。用户可以直接访问该项目在Eclipse的网 址Equinox获取概括性的信息。目前,关于Equinox的进展大部分资料及项目进展存在于Eclipse Wiki上。

目前,Equinox项目包括OSGi核心框架的实现,OSGi标准服务Bundle实现,OSGi的服务器端(J2EE实现)应用,Equinox部署更新框架及一些研究方向(未成熟发布的构想如JMX管理,安全管理,面向方面的设计与应用等)。

2.1OSGi核心框架的实现

EquinoxOSGi核心实现由三部分组成,包括:

Ø OSGi核心规范的实现(org.eclipse.osgi

该项目是OSGi核心框架标准规范的实现。由于Eclipse3.0版本之前未采用 OSGi作为系统内核,所以,为了重用Eclipse3.0以前核心系统的代码,EquinoxOSGi实现在一定程度上显得比较繁冗。用户如果想研究 开源的OSGi框架实现的源代码,可以从Oscar(目前为ApacheFelix项目)或Knopflerfish项目着手。ObjectWeb上的 Oscar项目最初实现OSGi R2版本框架时,整个核心的源代码不超过40个类文件。现在,Oscar项目转由Apache维护,项目称之为Felix,目前已发布1.0版本。 Knopflerfish也是很早实现OSGi的一个开源项目,该项目的网站上提供了很多关于OSGi编程的注意事项。

Ø OSGi框架启动支持(org.eclipse.equinox.launcher

OSGi 框架启动支持对于Eclipse IDE开发环境熟悉的开发用户来说并不算陌生。使用Eclipse以前版本的用户会发现在Eclipse安装目录下有一个startup.jar的文件, 该文件是Eclipse开发环境的入口程序封装。Equinox将该Jar文件的实现迁移为一个独立的OSGi Fragment。该Fragment主要是帮助Equinox建立起运行环境,如类加载路径,运行配置参数等等。

Ø Equinox启动可执行程序

Equinox启动可执行程序即为eclipse.exe文件,该执行程序并不是 Eclipse以前版本的exe可执行文件,而是由原来的eclipse.exe程序拆分而来,该执行文件的一部分功能拆分为一个共享DLL,放置在 OSGi框架启动支持段项目(org.eclipse.equinox.launcher)中,与原来的Eclipse根目录下的startup.jar 文件功能合并。

2.2OSGi标准服务Bundle实现

OSGi在提出核心框架规范的同时为一些常用的服务如日志服务(LogService),配 置管理服务(Config Admin),事件管理服务(Event Admin),HTTP服务(HTTP Service)等。Equinox提供了大部分OSGi标准服务的bundle的实现,同时,借助于Eclipse环境的一些自身的特 点,Equinox在实现这些OSGi标准服务的同时,提供了很多功能扩展服务(如org.eclipse.equinox.common)。

Equinox项目目前提供的OSGi标准服务实现如下所示:

Equinox实现项目

服务名称

服务说明

org.eclipse.equinox.app

Application Container

该项目实现了OSGi R4 MEG中的应用程序容器服务

org.eclipse.equinox.common

Common Utility Bundle

由一组Eclipse工具类(如IStatusAssertIAdaptable等)组成的实用程序Bundle。该Bundle也可以在非OSGi环境中独立使用。

org.eclipse.equinox.device

Device Access Service

OSGi R4规范中的Device Access Service标准服务的实现,该组件由Prosyst公司提供实现。

org.eclipse.equinox.ds

Declarative Services

OSGi R4规范中的Declarative Service标准服务的实现,该组件由Prosyst公司提供实现

org.eclipse.equinox.event

Event Admin Service

OSGi R4规范中的事件管理服务的实现。

org.eclipse.equinox.http

HTTP Service

OSGi R4规范中的HTTP服务实现

org.eclipse.equinox.log

Log Service

OSGi R4规范中的日志服务实现

org.eclipse.equinox.metatype

Metatype Service

OSGi R4规范中的Metatype服务的实现

org.eclipse.equinox.preferences

Preferences Service

OSGi R4规范中的Preferences服务的实现

org.eclipse.equinox.registry

Extension Registry

Equinox提供的Ecipse扩展点(extension point)注册表服务

org.eclipse.equinox.supplement

Supplemental Bundle/JAR

Equinox提供的一组Equinox实现所使用的类型库

org.eclipse.equinox.useradmin

User Admin Service

OSGi R4规范中的用户管理服务实现

org.eclipse.equinox.wireadmin

Wire Admin Service

OSGi R4规范中的服务通信拓扑管理服务

org.eclipse.osgi.services

OSGi Services API

OSGi R4规范中的服务接口定义,该BundleOSGi联盟定义的服务API接口组成

org.eclipse.osgi.util

OSGi Utilities

OSGi R4规范中的工具类接口及接口实现Bundle

 

2.3OSGi的服务器端(J2EE实现)应用

Equinox实现了OSGiJ2MEJ2SE方面的应用的同时,也推动了OSGi J2EE方面的应用。Equinox提供了一组基础的Bundle,使得使用JSPServletStrutsJ2EE技术的Web应用项目可以运 行于Equinox OSGi环境中。同样的,Equinox通过一组Bundle,可以将Equinox OSGi应用嵌入到现有的Web服务器(如TomcatJetty等)和应用服务器(如WebsphereWeblogic等)中。

下面是EquinoxJ2EE应用方面的一组Bundle列表:

Equinox J2EE实现项目

服务名称

服务说明

org.eclipse.equinox.http

HTTP service

BundleOSGi R4规范中的HTTP服务的标准实现。目前该实现只支持Servlet 2.3

org.eclipse.equinox.http.registry

HTTP registry

Bundle支持使用Eclipse的扩展注册表注册servlet,文件资源和JSP而不是使用OSGi中的代码注册机制。

org.eclipse.equinox.servletbridge

Servlet Bridge

Bundle提供一个底层的Hook servlet,使得Equinox可以嵌入到现有的应用服务器中运行。该Bundle中的servlet启动嵌入的Equinox并使其可以处理来自底层应用服务器接收的HTTP请求。

org.eclipse.equinox.http.servlet

HTTP Servlet

Bundle为在Equinox中发布其他servlet处理引擎(如传统的应用服务器)为OSGi HTTP服务提供支持。

org.eclipse.equinox.http.servletbridge

HTTP ServletBridge

Bundle为底层的应用服务器(如TomcatJetty等)发布为OSGi HTTP服务提供一层封装。封装的应用服务器必须安装该servlet bridge

javax.servlet

Servlet API

Servlet规范标准接口APIBundle封装。

javax.servlet.jsp

Servlet JSP API

Servlet JSP API接口的Bundle封装。

org.mortbay.jetty

Jetty

嵌入式Jetty实现的Bundle封装。目前Equinox提供的Jetty实现版本为5.x

org.eclipse.equinox.http.jetty

HTTP Jetty

Bundle封装Jetty为标准的OSGI HTTP服务。目前该服务只能使用Jetty 5.x版本;如果用户希望使用Jetty 6.x版本的Bundle封装,可以参考ops4j上的实现。

 

关于如何在Equinox环境中部署Web应用(JSPServletStruts等),请参考Equinox网站相关资料。我会在本系列后续文档中给出详细介绍。

2.4Equinox部署更新框架(Provisioning

Eclipse提供为插件的分组,更新及远程维护提供了一套完善的机制。用户可以通过远程更 新站点安装或升级所需功能的插件。为了适应OSGi环境的特点,Equinox项目组为基于OSGi的系统的部署更新提供了一套全新的框架,称为 “equinox p2”。目前该框架还在第一个发布版本的最后阶段,该功能预计将在Eclipse 3.4版本中集成发布。

2.5Equinox的最新研究方向

Ø 资源管理(Resource Monitoring

该方向致力于为基于OSGi的系统提供一个轻量级的资源监控管理基础框架,该框架基于JMX技术。目前该研究方向已经提供了一套可供展示的基本实现。

Ø 安全管理

该方向致力于将Java安全机制(JCA/JAAS框架)集成到Eclipse中。为 Eclipse/Equinox环境提供诸如消息摘要,数字签名,密钥存储,证书存储等基础安全机制。此外,该方向还为Eclipse提供JAVA包签 名,Bundle加载时的签名校验,代码权限等机制的实现。

Ø 面向方面的开发

该方向致力于解决在OSGi环境中面向方面编程的一些技术问题,如加载编排和模块化等。

3.       结论与参考

本文简要概述了EquinoxOSGi规范方面的实现以及它为OSGi在其他领域的应用所做的研究。后续文档中,我们将会将上述各个方面展开进行详细的描述。OSGi的广泛应用将大大推动JAVA由面向对象的编程向面向组件和服务的编程转变。

目前,JCP组织提出JSR-291OSGi纳入JAVA标准规范。如果该JSR最终被集成到J2SE实现中,开发人员可以在JAVA基础编程中直接采用OSGi提供动态的模块化应用。

Equinox项目源代码的位置位于CVS服务器 上::pserver:anonymous:dev.eclipse.org/cvsroot/eclipse路径下,以 org.eclipse.equinox.*命名的项目以及该位置下的equinox-incubator目录下。

4.       插曲

SUN公司提出了一个类似于OSGi的模块化系统规范称之为“HK2”HK2的全称为 “Hundred Kilobytes Kernel”,包括Modules SubsytemComponent Model两部分。据称,该内核将在JDK 7中集成,同时,SUN在其开源的GlassFish J2EE应用服务器项目V3版本中将HK2作为其系统内核实现。 

 

0 0
原创粉丝点击