精华内容
下载资源
问答
  • 计算机体系结构试题及答案

    热门讨论 2009-11-18 14:15:01
    5.6.2 提高主存性能存储器组织结构 5.7 虚拟存储器 5.7.1 虚拟存储器基本原理 5.7.2 快表(TLB) 5.7.3 页面大小选择 5.8 进程保护和虚存实例 5.8.1 进程保护 5.8.2 页式虚存举例:Alpha AXP...
  • (3)形成计算机网络体系结构:为了使不同体系结构的计算机网络都能互联,国际标准 化组织ISO 提出了一个能使各种计算机在世界范围内互联成网的标准框架—开放系统互连基 本参考模型OSI.。这样,只要遵循OSI 标准,...
  • (3)形成计算机网络体系结构:为了使不同体系结构的计算机网络都能互联,国际标准 化组织ISO 提出了一个能使各种计算机在世界范围内互联成网的标准框架—开放系统互连基 本参考模型OSI.。这样,只要遵循OSI 标准,...
  • 3.1 TCP/IP的优点 20 3.2 TCP/IP的层和协议 21 3.2.1 体系结构 21 3.2.2 传输控制协议 21 3.2.3 IP协议 23 3.2.4 应用层 25 3.2.5 传输层 25 3.2.6 网络层 25 3.2.7 链路层 25 3.3 远程登录(Telnet) 25 3.4 文件传输...
  • 一. OSGi 简史 OSGi 是由 1999 年成立的 OSGi 联盟提出的一个开放的服务规范,最初的目的...后来 Eclipse 组织注意到了 OSGi 的优点,决定将 Eclipse3.0 及后续版本的插件体系结构基于 OSGi 来实现,并专门成立了一...

    一. OSGi 简史

    OSGi 是由 1999 年成立的 OSGi 联盟提出的一个开放的服务规范,最初的目的是为嵌入式设备,确切地说是为可以通过网络访问的设备提供一个通用的软件运行平台,屏蔽不同设备之间的硬件和操作系统差异,使软件可以动态地部署和更新。后来 Eclipse 组织注意到了 OSGi 的优点,决定将 Eclipse3.0 及后续版本的插件体系结构基于 OSGi 来实现,并专门成立了一个子项目 Equinox 来实现 OSGi R4 规范,把 Equinox 作为 Eclipse 的底层运行平台。Eclipse 组织的这一决定带来了双赢的局面,今天的 Eclipse 由于其出色的可扩展的体系结构,已经不再是一个单纯的 Java IDE,而是一个开放的开发平台,一个通用的可扩展的软件框架,OSGi 也不再局限于嵌入式领域,而是成为了一个通用的动态组件开发环境,在桌面,服务器端等领域得到了大量应用。

    对模块化的支持是 Java 的一个重要的发展方向,目前 Java 的模块化标准还存在着JSR 277:Java Module Systems 和 JSR 291:Dynamic Component Support for Java 之争论,其中JSR291 的主要目的就要将 OSGi 引入到 Java 标准中去,JSR277 则是 SUN 发起的一个Java 模块化标准。但 OSGi 事实上已经得到了许多国际IT大企业的支持,并且已经有许多商业软件产品基于 OSGi 来开发,如 IBM 包括 Websphere Application Server(WAS), Rational Software Architecture(RSA) 在内的许多重量级软件产品均已基于 OSGi 来实现,著名的 IoC 框架 Spring 正在整合 OSGi 技术,现在基于 Eclipse 开发 RCP,插件程序也非常流行,可以预见基于OSGi 的 Java 应用程序将会越来越多,也将会有越来越多的软件开发组织改变其软件设计思想和开发方式,拥抱 OSGi 并开始享受 OSGi 带来的好处。

    二. 使用 Eclipse 开发 OSGi 应用

    本文假设读者已经了解 OSGi 编程的基本概念以及如何在 Eclipse 环境中来开发OSGi Bundle。如果您还不了解这些知识,可以先阅读相关资料如: http://www.eclipse.org/equinox网站以及 developerworks 网站上的文章: 利用 Eclipse 开发基于 OSGi 的 Bundle 应用

    Eclipse 开发平台中对基于 OSGi 开发应用程序已经提供了较为完善的支持,在 Eclipse 集成开发环境中可以轻松地完成对一个或多个 bundle 的开发、调试、部署、测试等工作。本文将基于 Equinox OSGi 框架,使用 Eclipse 开发平台来开发一个示例性的系统管理程序,主要目的是给读者演示基于 OSGi 开发一个应用程序的过程并让读者体会基于OSGi 编程带来的模块化,动态性,扩展性等优点。为了便于读者理解,本文会尽可能的保持代码简单易懂,本文中的代码在 WindowsXP,Eclipse3.2,Sun JDK1.5 环境下测试通过。

    三. 需求分析与模块划分

    OSGi 带来了规范化的模块划分,低耦合的模块间关系,统一的模块开发方式,可动态插拔的模块管理环境。开发 OSGi 应用程序的第一步是在需求分析的基础上进行精心的模块划分,模块划分的原则是尽量保持单个模块的独立性,使模块与模块之间的耦合降到最小,每一个模块暴露给其它模块的信息最少,尽量让模块之间使用 OSGi 框架提供的服务注册机制来通信。一般可采用一个模块一个 Bundle 的方式,并为每一个 Bundle 在 Eclipse 环境中建立一个 Project 来进行开发,由于模块与模块之间的耦合很小,各个 Bundle 之间并不会象传统的开发方式中的各模块之间那样存在纠缠不清的包和类的引用关系,因此大部分Bundle的开发工作可以并行进行而不会互相影响。

    本文实现的系统管理程序,可以提供一系列的系统管理服务来管理计算机内的各类设备。为简便起见,我们首先只实现一项管理服务:Monitor,此项服务可以监视计算机内各类设备的运行状态,我们可以将整个软件划分为如下的一些Bundle:

    • Services Bundle:在OSGi中,服务是通过Java的接口来定义的,我们可以把定义服务的Java接口集中一个Services Bundle中,并由这个Bundle向其它Bundle提供接口。
    • 服务提供者Bundle:实现Services Bundle提供的接口并向OSGi框架注册服务。在本例中,我们要实现对各类设备的监视,对于每一个需要监视的设备,均可以实现一个单独的服务提供者Bundle来提供相应的监视功能。
    • 服务使用者Bundle:引用Services Bundle提供的接口向OSGi框架请求相应的服务,本例中主要实现一个服务使用者Bundle,它是一个控制台程序,用于执行相应的系统管理服务,并在控制台中向用户显示相应的系统管理信息。

    整个程序是由OSGi框架以及运行于OSGi框架内的一批Bundles组成,Bundle之间的协作关系见下图:

    图1 程序的总体架构图

    程序的总体架构图

    四. 实现Bundle

    1. 实现Services Bundle

    新建一个Eclipse plugin-in project,将其命名为com.systemmanagement.services,注意创建OSGi Bundle工程时,一定要选中“an OSGi framework”做为工程的目标平台,并选择Equinox或standard,这两个选项的区别是:Equinox对OSGi 规范第4版进行了一些扩展,如果开发出来的Bundle希望能够在其它的OSGi实现框架如Oscar,Knopflerfish上顺利运行,此处最好选择standard。这个Bundle的实现很简单,它无需实现BundleActivator类,只需定义一个接口即可:

    代码清单1: MonitorService.java

    1

    2

    3

    4

    5

    package com.systemmanagement.services.monitor;

     

    public interface MonitorService {

      public String getMonitorMessage();

    }

    同时勿忘在此Bundle的MANIFEST.MF文件中将相应的package导出:

    代码清单2:MANIFEST.MF

    1

    2

    3

    4

    5

    6

    7

    8

    Manifest-Version: 1.0

    Bundle-ManifestVersion: 2

    Bundle-Name: Services Plug-in

    Bundle-SymbolicName: com.systemmanagement.services

    Bundle-Version: 1.0.0

    Bundle-Vendor: cyz

    Bundle-Localization: plugin

    Export-Package: com.systemmanagement.services.monitor

    如果将来需要扩充新的系统管理服务,需在此Bundle中增加新的接口并将其所属的package在MANIFEST.MF文件中导出。

    2. 实现服务提供者Bundle

    新建一个Eclipse plugin-in project,将其命名为com.systemmanagement.cpumonitor,此Bundle负责监视CPU,提供相应的监视信息,它需要实现services bundle提供的MonitorService接口,同时它需要向OSGi框架注册服务,因此首先需要在其MANIFEST.MF文件中导入相应的包:

    代码清单3:MANIFEST.MF

    1

    2

    3

    4

    5

    6

    7

    8

    9

    Manifest-Version: 1.0

    Bundle-ManifestVersion: 2

    Bundle-Name: Cpumonitor Plug-in

    Bundle-SymbolicName: com.systemmanagement.cpumonitor

    Bundle-Version: 1.0.0

    Bundle-Activator: com.systemmanagement.cpumonitor.CpuMonitorActivator

    Bundle-Vendor: cyz

    Bundle-Localization: plugin

    Import-Package: com.systemmanagement.services.monitor, org.osgi.framework;version="1.3.0"

    此Bundle的实现主要包括两部分工作:一个实现MonitorService的类,用于提供CPU的监视信息(如代码清单4所示)。一个BundleActivator类用于在Bundle启动时向OSGi框架注册服务,在Bundle停止时将服务注销(如代码清单5所示)。

    代码清单4:CpuMonitor.java

    1

    2

    3

    4

    5

    6

    7

    8

    Package com.systemmanagement.cpumonitor.impl;

    import com.systemmanagement.services.monitor.MonitorService;

     

    public class CpuMonitor implements MonitorService {

      public String getMonitorMessage() {

            return "CPU--温度:40度,电压:1.4v";

      }

    }

    代码清单4仅为演示之用途,在真正开发应用时,可以在此处实现真实的CPU监视功能,例如你可以使用Java的JNI机制来调用一些操作系统底层的或第三方的API获得相关的CPU信息,这些技术与本文的主题OSGi关系不大,在此略过。

    代码清单5:CpuMonitorActivator.java

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    Package com.systemmanagement.cpumonitor;

     

    import java.util.Hashtable;

    import org.osgi.framework.BundleActivator;

    import org.osgi.framework.BundleContext;

    import org.osgi.framework.ServiceRegistration;

    import com.systemmanagement.cpumonitor.impl.CpuMonitor;

    import com.systemmanagement.services.monitor.MonitorService;

     

    public class CpuMonitorActivator implements BundleActivator {

        private BundleContext context=null;

        private ServiceRegistration serviceRegistration=null;

         

        public void start(BundleContext context) throws Exception {

            this.context=context;

            MonitorService monitor=new CpuMonitor();

            Properties properties = new Properties();

            properties.put("device", "cpu");

            serviceRegistration=this.context.registerService(

                MonitorService.class.getName(), monitor, properties); 

        }

     

        public void stop(BundleContext context) throws Exception {

            serviceRegistration.unregister();

            context=null;

        }

    }

    代码清单5中最重要的功能就是向OSGi框架注册了一个Monitor服务,注册服务时使用了一个Properties容器,容器中的key-value对说明了当前这个Monitor服务针对的是CPU,利用这个Properties容器,服务使用者Bundle就能够判断一个Monitor服务所针对的具体设备是什么。

    针对其它需监视的设备如内存,网卡,电源,风扇等,我们可以分别实现一个Bundle来提供相应的监视服务,其实现过程与com.systemmanagement.cpumonitor这个Bundle是完全类似的,在此不再赘述。

    3. 实现服务使用者Bundle

    新建一个Eclipse plugin-in project,将其命名为com.systemmanagement.console,此Bundle是一个控制台程序,它通过调用其它服务提供者Bundle提供的系统管理服务,向用户提供系统管理信息。同样首先需要在其MANIFEST.MF文件中导入相应的包:

    代码清单6:MANIFEST.MF

    1

    2

    3

    4

    5

    6

    7

    8

    9

    Manifest-Version: 1.0

    Bundle-ManifestVersion: 2

    Bundle-Name: Console Plug-in

    Bundle-SymbolicName: com.systemmanagement.console

    Bundle-Version: 1.0.0

    Bundle-Activator: com.systemmanagement.console.ConsoleActivator

    Bundle-Vendor: cyz

    Bundle-Localization: plugin

    Import-Package: com.systemmanagement.services.monitor, org.osgi.framework;version="1.3.0", org.osgi.util.tracker;version="1.3.1"

    代码清单6中导入的包org.osgi.util.tracker是OSGi框架提供的监视Bundle提供的服务是否可用的机制,下文将会详述。

    此Bundle的实现主要包括三部分工作:一个ServiceTracker类,用于监视服务提供者Bundle注册的各类系统管理服务是否可用,并根据服务是否可用,采取相应的动作(如代码清单7所示)。一个控制台线程类,用于执行各类系统管理服务并向用户提供相应的信息(如代码清单8所示)。一个BundleActivator类用于在Bundle启动时启动Service Tracker服务监视系统管理服务是否可用,启动控制台线程类开始执行各类系统管理服务并显示信息,在Bundle停止时停止Service Tracker服务和控制台线程类。(如代码清单9所示)。

    代码清单7: MonitorServiceTracker.java

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    package com.systemmanagement.console;

     

    import org.osgi.framework.BundleContext;

    import org.osgi.framework.ServiceReference;

    import org.osgi.util.tracker.ServiceTrackerCustomizer;

    import com.systemmanagement.services.monitor.MonitorService;

     

    public class MonitorServiceTracker implements ServiceTrackerCustomizer {

      private ConsoleThread thread;

      private BundleContext bc;

       

      public MonitorServiceTracker(BundleContext bc,ConsoleThread thread) {

        this.thread = thread;

        this.bc = bc;

      }

      public Object addingService(ServiceReference reference) {

        MonitorService service = (MonitorService)bc.getService(reference);

        thread.addService(service);

        return service;

      }

      public void modifiedService(ServiceReference reference, Object serviceObject) {

        MonitorService service = (MonitorService)bc.getService(reference);

        thread.addService(service);

      }

      public void removedService(ServiceReference reference, Object serviceObject) {

        MonitorService service = (MonitorService)bc.getService(reference);

        thread.removeService(service);

      }

    }

    注意,在本文中只实现了Monitor一项服务,将来如需扩充到支持多项系统管理服务,可以为每一项或某一类服务各自实现一个ServiceTracker类来监视相应服务的可用性。

    代码清单8:ConsoleThread.java

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    package com.systemmanagement.console;

     

    import java.util.HashSet;

    import java.util.Iterator;

    import com.systemmanagement.services.monitor.MonitorService;

     

    public class ConsoleThread extends Thread {

      private HashSet<MonitorService> monitorServices=

        new HashSet<MonitorService>();

      private boolean running = true;

      public ConsoleThread(){};

       

      public void addService(MonitorService service){

        this.monitorServices.add(service);

      }

      public void removeService(MonitorService service){

        this.monitorServices.remove(service);

      }

      public void run() {

        while (running) {

            for(Iterator<MonitorService> it=this.monitorServices.iterator();

            it.hasNext();){

            MonitorService service=it.next();

            System.out.println(service.getMonitorMessage());

          }

          try {

            Thread.sleep(5000);

          } catch (InterruptedException e) {

            System.out.println("ManagementThread ERROR: " + e);

          }

        }

      }

      public void stopThread() {

        this.running = false;

        try {

          this.join();

        } catch (InterruptedException e) {

          e.printStackTrace();

        }

      }

    }

    代码清单8是一个多线程程序,为演示之简便,在此例中它只是用一个HashSet持有当前可用的系统管理服务,并无限循环,依次执行各项系统管理服务。在实际情况中,完全可以与用户交互,根据用户的指令来执行相应的系统管理服务。

    代码清单9:ConsoleActivator.java

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    package com.systemmanagement.console;

     

    import org.osgi.framework.BundleActivator;

    import org.osgi.framework.BundleContext;

    import org.osgi.util.tracker.ServiceTracker;

    import org.osgi.util.tracker.ServiceTrackerCustomizer;

    import com.systemmanagement.services.monitor.MonitorService;

     

    public class ConsoleActivator implements BundleActivator {

       

      private BundleContext context = null;

      private ServiceTracker tracker = null;

      private ConsoleThread thread=new ConsoleThread();

       

      public void start(BundleContext context) throws Exception {

        this.context = context;

        tracker = new ServiceTracker(context, MonitorService.class.getName(),

            new MonitorServiceTracker(context,thread));

        tracker.open();

         

        this.thread.start();

      }

     

      public void stop(BundleContext context) throws Exception {

        tracker.close();

        this.thread.stopThread();

      }

    }

    五.运行和测试基于OSGi的应用程序

    一个基于OSGi的应用程序是由OSGi框架本身以及若干个Bundle组成,为了对其进行运行和测试,通常需要将各个Bundle Project一一打包成Bundle(jar文件),并部署到一个OSGi框架中,还是比较麻烦的。幸运的是,Eclipse已经对此提供了很好的支持,Eclipse本身是基于OSGi框架Equinox的,在Eclipse环境中可直接将各Bundle部署到Equinox框架中并运行之,对开发者来说十分便利,其具体步骤如下:

    在Eclipse中选择Run-->Run...菜单,在弹出的Run配置面板的左侧选中“Equinox OSGi Framework”,然后再选择其上方的“New”按钮创建一个新的运行配置,将其命名为“systemmanagement”,再选择右侧的Deselect All按钮,然后只选择我们想要运行的4个Bundles:包括我们前面开发的3个Bundle以及OSGi框架本身org.eclipse.osgi,其中还可以设置各个Bundle的Start Level, Start Level可用于控制各Bundle的启动顺序,Start Level低的Bundle会优先启动,例如我们可以将服务提供者Bundle cpumonitor的Start Level设为1,而将服务使用者Bundle console的Start Level设为2,如下图所示:

    图2 Bundle的运行配置

    Bundle的运行配置

    在Eclipse环境中的运行结果如下图,在控制台中会不断的显示一些系统管理信息,同时也可在控制台中运行各种OSGi控制台命令,如ss命令可用于显示各Bundle的状态,读者可以通过help命令了解更多的OSGi控制台命令。

    图3 在Eclipse中的运行结果

    在Eclipse中的运行结果

    我们也需要了解如何让这些Bundle脱离Eclipse环境来运行,首先需要将各个Bundle Project打包成一个Bundle(即一个jar文件),其步骤如下:

    在Eclipse主菜单中选File->Export,再在弹出窗口中选择Deployable plug-ins and fragments,再选下一步,在弹出窗口中选择我们上面开发的三个Bundle project,并指定Bundle的输出目录,点Finish即可,如下图所示:

    图4 导出Bundle

    导出Bundle

    然后可以在e:\system_management\plugins目录下找到三个jar文件,现在我们需要一个OSGi框架来运行它们。Equinox是目前最流行的OSGi框架,Equinox本身也被打包成一个Bundle,在Eclipse安装目录的plugins目录下即可找到它,如org.eclipse.osgi_3.2.0.v20060601.jar,将这个文件拷到e:\system_management目录下。在命令提示符下进入e:\system_management目录下,运行如下命令启动Equinox:

    java –jar org.eclipse.osgi_3.2.0.v20060601.jar –console

    启动之后会出现一个OSGi控制台,并且已经启动一个system bundle,这个bundle就是OSGi框架本身。现在我们可以在OSGi控制台中手工安装我们开发的三个Bundle,如下图所示:

    图5 安装Bundle

    安装Bundle

    随后,可以依次启动三个Bundle,这样整个应用就运行起来了,如下图所示:

    图6 运行Bundle

    运行Bundle

    请保留这个OSGi控制台并让应用继续运行,接下来我们还会在这个控制台中进行一些操作来体验OSGi的动态性。

    六. 体验OSGi的动态性

    除了模块化以及面向服务编程之外,OSGi的另一个重要特点是其动态性,Bundle以及Bundle提供的服务可以随时消失或者重新加入,而其它使用服务的Bundle可以感知服务是否可用,并动态地改变自己的行为。应用程序在运行过程中,可以随时增加新的Bundle,停止或卸载已有的Bundle,如果有新的服务加入进来,这个服务也能立即被其它Bundle使用并由此动态地改变整个应用程序的行为,在整个动态改变的过程中,OSGi框架本身是稳定的,无需重启。以下我们将通过一些示例来体验OSGi的动态性:

    我们现在想给应用增加一个监视内存运行状态的功能,新建一个Eclipse plugin-in project,将其命名为com.systemmanagement.memorymonitor,这个Bundle的实现过程与com.systemmanagement.cpumonitor基本类似,最主要的不同是实现MonitorService服务的那个类,如以下代码所示,其它代码可参见本文所附的代码清单。

    代码清单10:MemoryMonitor.java

    1

    2

    3

    4

    5

    6

    7

    8

    package com.systemmanagement.memorymonitor.impl;

    import com.systemmanagement.services.monitor.MonitorService;

     

    public class MemoryMonitor implements MonitorService {

      public String getMonitorMessage() {

        return "内存--物理内存总数:1G,可用数:300M";

      }

    }

    同样,将这个Bundle export成一个jar文件到e:\system_management\plugins目录下,安装以及启动这个Bundle,这时我们发现输出的系统管理信息马上改变了,如下图所示:

    图7 安装以及启动一个新的Bundle

    安装以及启动一个新的Bundle

    再假定我们需要增强com.systemmanagement.cpumonitor这个Bundle的功能,让其提供更多的CPU信息,我们可以修改其中的CpuMonitor.java类,如下所示:

    代码清单11:CpuMonitor.java

    1

    2

    3

    4

    5

    6

    7

    8

    package com.systemmanagement.cpumonitor.impl;

    import com.systemmanagement.services.monitor.MonitorService;

     

    public class CpuMonitor implements MonitorService {

      public String getMonitorMessage() {

        return "CPU--温度:40度,电压:1.4v,CPU占用率:20%";

      }

    }

    再将这个Bundle export成一个jar文件,放到e:\system_management\plugins目录下,并在OSGi控制台中使用update命令更新这个Bundle,我们发现输出的CPU监视信息马上改变了,如下图所示:

    图8 更新Bundle

    更新Bundle

    读者还可以在OSGi控制台中尝试使用start,stop等命令启动和停止一些Bundle,观察输出信息的改变,由此来体验一下OSGi的动态性。

    由于基于OSGi的应用程序具有高度的模块化和动态性的特点,使得要对其进行扩展也变得非常的方便:一般来说,扩展就是增加新的Bundle,对其它Bundle基本无影响,如上面的例子所示,我们很方便地为应用程序增加了新的功能,更新了它已有的功能,而整个应用程序甚至都不需要重启。Equinox同时还借用了Eclipse中的扩展点的机制,利用扩展点,可以方便的为已有的Bundle扩展功能,但扩展点这一套机制目前还不是OSGi规范中定义的特性,仅是Equinox这一实现平台扩展出来的功能,使用了扩展点的Bundle将有可能不能在其它的OSGi实现框架中正常运行,这需要开发者权衡选择。

    七.发布应用程序

    在上一节中我们在OSGi控制台中运行我们的系统管理程序,其中还需要手工install, start各个Bundle,显然这很麻烦,不太象一个真正的应用程序,本节将介绍如何构造出一个完整的基于OSGi的应用程序。

    首先,Equinox提供了在启动框架时自动安装Bundle以及启动Bundle的功能,这是通过定义config.ini文件来实现的,应用程序的目录结构如下:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    E:\SYSMGT_APP1

    │  run.bat

    │  org.eclipse.osgi_3.2.0.v20060601.jar

    ├─configuration

    │      config.ini

    └─plugins

           com.systemmanagement.console_1.0.0.jar

           com.systemmanagement.cpumonitor_1.0.0.jar

           com.systemmanagement.services_1.0.0.jar

    config.ini文件的内容如下:

    1

    2

    3

    osgi.bundles=plugins/com.systemmanagement.cpumonitor_1.0.0.jar@1:start,

     plugins/com.systemmanagement.console_1.0.0.jar@2:start,

     plugins/com.systemmanagement.services_1.0.0.jar

    其中的@1,@2用于指定Bundle的Start Level, start表示当OSGi框架启动后即自动启动此Bundle。而run.bat是一个批处理程序,其内容如下:

    java –jar org.eclipse.osgi_3.2.0.v20060601.jar -console

    现在只需运行run.bat即可运行我们的系统管理应用程序了。

    Eclipse中还提供了两个Bundle, org.eclipse.equinox.common和org.eclipse.update.configurator,可用于自动发现和安装指定目录下新增加的Bundle。 我们同样可以在Eclipse的plugins目录中找到这两个Bundle并将它们拷到E:\SYSMGT_APP1\plugins目录下,并修改config.ini文件的内容如下所示:

    1

    2

    3

    4

    osgi.bundles=plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar@1:start,

     plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar@2:start,

     plugins/com.systemmanagement.cpumonitor_1.0.0.jar@2:start,

     plugins/com.systemmanagement.console_1.0.0.jar@3:start

    这样,当org.eclipse.update.configurator Bundle启动时,它会去自动发现和安装plugins目录新增的Bundle,但需注意, 它并不能自动启动这些Bundle,OSGi协议目前也没有提供这样的标准服务来自动安装,管理和启动Bundle, 我们可以使用如下的一些解决方案来更好地管理和分发Bundle:

    • 利用Eclipse的Update Manager:Eclipse Update Manager提供了一批API用于管理,下载,升级,安装Feature,一个Feature是一批Bundle的集合, 是下载和安装的最小单位。但Feature是Eclipse定义的,不是OSGi协议中定义的特性。
    • 使用FileInstall Bundle,这个Bundle可以监视某一个目录,如果这个目录中新增加了Bundle,它会自动将其install,如果有Bundle被更新了, 它会自动将其update,如果有Bundle从此目录被移走,它会自动将其uninstall。可到 http://www.aqute.biz/Code/FileInstall下载这个Bundle,它可以运行于任何OSGi框架中。
    • 在Equinox孵化器(incubator)中有一个org.eclipse.equinox.simpleconfigurator,可用于管理和控制已安装的Bundle, 包括设置启动级别并自动启动它们。可访问http://www.eclipse.org/equinox/incubator并到其CVS库中下载

    八. 小结

    本文介绍了基于OSGi开发一个应用程序的完整流程,包括模块划分,Bundle的设计与开发,部署与测试,发布应用程序等,并演示了基于OSGi编程所具有的模块化,面向服务,动态性,易扩展等优点。基于组件或构件编程是学术界提了多年的思想,笔者认为OSGi是一个比较彻底地体现这种思想的编程模型,基于OSGi编程将带来软件设计以及开发方式的改变并由此带来软件生产效率的极大提升。

    申明:本文仅代表笔者个人的观点,不代表IBM公司的观点。

    下载资源

    相关主题

    from: https://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-osgi/index.html 

    展开全文
  • 一. OSGi 简史OSGi 是由 1999 年成立的 OSGi 联盟提出的一个开放的服务规范,最初的目的是为...后来 Eclipse 组织注意到了 OSGi 的优点,决定将 Eclipse3.0 及后续版本的插件体系结构基于 OSGi 来实现,并专门成立了一

    一. OSGi 简史

    OSGi 是由 1999 年成立的 OSGi 联盟提出的一个开放的服务规范,最初的目的是为嵌入式设备,确切地说是为可以通过网络访问的设备提供一个通用的软件运行平台,屏蔽不同设备之间的硬件和操作系统差异,使软件可以动态地部署和更新。后来 Eclipse 组织注意到了 OSGi 的优点,决定将 Eclipse3.0 及后续版本的插件体系结构基于 OSGi 来实现,并专门成立了一个子项目 Equinox 来实现 OSGi R4 规范,把 Equinox 作为 Eclipse 的底层运行平台。Eclipse 组织的这一决定带来了双赢的局面,今天的 Eclipse 由于其出色的可扩展的体系结构,已经不再是一个单纯的 Java IDE,而是一个开放的开发平台,一个通用的可扩展的软件框架,OSGi 也不再局限于嵌入式领域,而是成为了一个通用的动态组件开发环境,在桌面,服务器端等领域得到了大量应用。

    对模块化的支持是 Java 的一个重要的发展方向,目前 Java 的模块化标准还存在着JSR 277:Java Module Systems 和 JSR 291:Dynamic Component Support for Java 之争论,其中JSR291 的主要目的就要将 OSGi 引入到 Java 标准中去,JSR277 则是 SUN 发起的一个Java 模块化标准。但 OSGi 事实上已经得到了许多国际IT大企业的支持,并且已经有许多商业软件产品基于 OSGi 来开发,如 IBM 包括 Websphere Application Server(WAS), Rational Software Architecture(RSA) 在内的许多重量级软件产品均已基于 OSGi 来实现,著名的 IoC 框架 Spring 正在整合 OSGi 技术,现在基于 Eclipse 开发 RCP,插件程序也非常流行,可以预见基于OSGi 的 Java 应用程序将会越来越多,也将会有越来越多的软件开发组织改变其软件设计思想和开发方式,拥抱 OSGi 并开始享受 OSGi 带来的好处。





    回页首


    二. 使用 Eclipse 开发 OSGi 应用

    本文假设读者已经了解 OSGi 编程的基本概念以及如何在 Eclipse 环境中来开发OSGi Bundle。如果您还不了解这些知识,可以先阅读相关资料如: http://www.eclipse.org/equinox网站以及 developerworks 网站上的文章: 利用 Eclipse 开发基于 OSGi 的 Bundle 应用

    Eclipse 开发平台中对基于 OSGi 开发应用程序已经提供了较为完善的支持,在 Eclipse 集成开发环境中可以轻松地完成对一个或多个 bundle 的开发、调试、部署、测试等工作。本文将基于 Equinox OSGi 框架,使用 Eclipse 开发平台来开发一个示例性的系统管理程序,主要目的是给读者演示基于 OSGi 开发一个应用程序的过程并让读者体会基于OSGi 编程带来的模块化,动态性,扩展性等优点。为了便于读者理解,本文会尽可能的保持代码简单易懂,本文中的代码在 WindowsXP,Eclipse3.2,Sun JDK1.5 环境下测试通过。





    回页首


    三. 需求分析与模块划分

    OSGi 带来了规范化的模块划分,低耦合的模块间关系,统一的模块开发方式,可动态插拔的模块管理环境。开发 OSGi 应用程序的第一步是在需求分析的基础上进行精心的模块划分,模块划分的原则是尽量保持单个模块的独立性,使模块与模块之间的耦合降到最小,每一个模块暴露给其它模块的信息最少,尽量让模块之间使用 OSGi 框架提供的服务注册机制来通信。一般可采用一个模块一个 Bundle 的方式,并为每一个 Bundle 在 Eclipse 环境中建立一个 Project 来进行开发,由于模块与模块之间的耦合很小,各个 Bundle 之间并不会象传统的开发方式中的各模块之间那样存在纠缠不清的包和类的引用关系,因此大部分Bundle的开发工作可以并行进行而不会互相影响。

    本文实现的系统管理程序,可以提供一系列的系统管理服务来管理计算机内的各类设备。为简便起见,我们首先只实现一项管理服务:Monitor,此项服务可以监视计算机内各类设备的运行状态,我们可以将整个软件划分为如下的一些Bundle:

     

    • Services Bundle:在OSGi中,服务是通过Java的接口来定义的,我们可以把定义服务的Java接口集中一个Services Bundle中,并由这个Bundle向其它Bundle提供接口。
    • 服务提供者Bundle:实现Services Bundle提供的接口并向OSGi框架注册服务。在本例中,我们要实现对各类设备的监视,对于每一个需要监视的设备,均可以实现一个单独的服务提供者Bundle来提供相应的监视功能。
    • 服务使用者Bundle:引用Services Bundle提供的接口向OSGi框架请求相应的服务,本例中主要实现一个服务使用者Bundle,它是一个控制台程序,用于执行相应的系统管理服务,并在控制台中向用户显示相应的系统管理信息。

     

    整个程序是由OSGi框架以及运行于OSGi框架内的一批Bundles组成,Bundle之间的协作关系见下图:


    图1 程序的总体架构图
    程序的总体架构图




    回页首


    四. 实现Bundle

    1. 实现Services Bundle

    新建一个Eclipse plugin-in project,将其命名为com.systemmanagement.services,注意创建OSGi Bundle工程时,一定要选中“an OSGi framework”做为工程的目标平台,并选择Equinox或standard,这两个选项的区别是:Equinox对OSGi 规范第4版进行了一些扩展,如果开发出来的Bundle希望能够在其它的OSGi实现框架如Oscar,Knopflerfish上顺利运行,此处最好选择standard。这个Bundle的实现很简单,它无需实现BundleActivator类,只需定义一个接口即可:


    代码清单1: MonitorService.java
                    
    package com.systemmanagement.services.monitor;
    
    public interface MonitorService {
    	public String getMonitorMessage();
    }
    

    同时勿忘在此Bundle的MANIFEST.MF文件中将相应的package导出:


    代码清单2:MANIFEST.MF
                    
    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: Services Plug-in
    Bundle-SymbolicName: com.systemmanagement.services
    Bundle-Version: 1.0.0
    Bundle-Vendor: cyz
    Bundle-Localization: plugin
    Export-Package: com.systemmanagement.services.monitor
                

    如果将来需要扩充新的系统管理服务,需在此Bundle中增加新的接口并将其所属的package在MANIFEST.MF文件中导出。

    2. 实现服务提供者Bundle

    新建一个Eclipse plugin-in project,将其命名为com.systemmanagement.cpumonitor,此Bundle负责监视CPU,提供相应的监视信息,它需要实现services bundle提供的MonitorService接口,同时它需要向OSGi框架注册服务,因此首先需要在其MANIFEST.MF文件中导入相应的包:


    代码清单3:MANIFEST.MF
                    
    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: Cpumonitor Plug-in
    Bundle-SymbolicName: com.systemmanagement.cpumonitor
    Bundle-Version: 1.0.0
    Bundle-Activator: com.systemmanagement.cpumonitor.CpuMonitorActivator
    Bundle-Vendor: cyz
    Bundle-Localization: plugin
    Import-Package: com.systemmanagement.services.monitor,
                     org.osgi.framework;version="1.3.0"
                

    此Bundle的实现主要包括两部分工作:一个实现MonitorService的类,用于提供CPU的监视信息(如代码清单4所示)。一个BundleActivator类用于在Bundle启动时向OSGi框架注册服务,在Bundle停止时将服务注销(如代码清单5所示)。


    代码清单4:CpuMonitor.java
                    
    Package com.systemmanagement.cpumonitor.impl;
    import com.systemmanagement.services.monitor.MonitorService;
    
    public class CpuMonitor implements MonitorService {
    	public String getMonitorMessage() {
            return "CPU--温度:40度,电压:1.4v";
    	}
    }
    

    代码清单4仅为演示之用途,在真正开发应用时,可以在此处实现真实的CPU监视功能,例如你可以使用Java的JNI机制来调用一些操作系统底层的或第三方的API获得相关的CPU信息,这些技术与本文的主题OSGi关系不大,在此略过。


    代码清单5:CpuMonitorActivator.java
                    
    Package com.systemmanagement.cpumonitor;
    
    import java.util.Hashtable;
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceRegistration;
    import com.systemmanagement.cpumonitor.impl.CpuMonitor;
    import com.systemmanagement.services.monitor.MonitorService;
    
    public class CpuMonitorActivator implements BundleActivator {
        private BundleContext context=null;
        private ServiceRegistration serviceRegistration=null;
        
        public void start(BundleContext context) throws Exception {
            this.context=context;
            MonitorService monitor=new CpuMonitor();
            Properties properties = new Properties();
            properties.put("device", "cpu");
            serviceRegistration=this.context.registerService(
                MonitorService.class.getName(), monitor, properties);	
        }
    
        public void stop(BundleContext context) throws Exception {
            serviceRegistration.unregister();
            context=null;
        }
    }
    

    代码清单5中最重要的功能就是向OSGi框架注册了一个Monitor服务,注册服务时使用了一个Properties容器,容器中的key-value对说明了当前这个Monitor服务针对的是CPU,利用这个Properties容器,服务使用者Bundle就能够判断一个Monitor服务所针对的具体设备是什么。

    针对其它需监视的设备如内存,网卡,电源,风扇等,我们可以分别实现一个Bundle来提供相应的监视服务,其实现过程与com.systemmanagement.cpumonitor这个Bundle是完全类似的,在此不再赘述。

    3. 实现服务使用者Bundle

    新建一个Eclipse plugin-in project,将其命名为com.systemmanagement.console,此Bundle是一个控制台程序,它通过调用其它服务提供者Bundle提供的系统管理服务,向用户提供系统管理信息。同样首先需要在其MANIFEST.MF文件中导入相应的包:


    代码清单6:MANIFEST.MF
                    
    Manifest-Version: 1.0
    Bundle-ManifestVersion: 2
    Bundle-Name: Console Plug-in
    Bundle-SymbolicName: com.systemmanagement.console
    Bundle-Version: 1.0.0
    Bundle-Activator: com.systemmanagement.console.ConsoleActivator
    Bundle-Vendor: cyz
    Bundle-Localization: plugin
    Import-Package: com.systemmanagement.services.monitor,
                     org.osgi.framework;version="1.3.0",
                     org.osgi.util.tracker;version="1.3.1"
                

    代码清单6中导入的包org.osgi.util.tracker是OSGi框架提供的监视Bundle提供的服务是否可用的机制,下文将会详述。

    此Bundle的实现主要包括三部分工作:一个ServiceTracker类,用于监视服务提供者Bundle注册的各类系统管理服务是否可用,并根据服务是否可用,采取相应的动作(如代码清单7所示)。一个控制台线程类,用于执行各类系统管理服务并向用户提供相应的信息(如代码清单8所示)。一个BundleActivator类用于在Bundle启动时启动Service Tracker服务监视系统管理服务是否可用,启动控制台线程类开始执行各类系统管理服务并显示信息,在Bundle停止时停止Service Tracker服务和控制台线程类。(如代码清单9所示)。


    代码清单7: MonitorServiceTracker.java
                    
    package com.systemmanagement.console;
    
    import org.osgi.framework.BundleContext;
    import org.osgi.framework.ServiceReference;
    import org.osgi.util.tracker.ServiceTrackerCustomizer;
    import com.systemmanagement.services.monitor.MonitorService;
    
    public class MonitorServiceTracker implements ServiceTrackerCustomizer {
    	private ConsoleThread thread;
    	private BundleContext bc;
    	
    	public MonitorServiceTracker(BundleContext bc,ConsoleThread thread) {
    		this.thread = thread;
    		this.bc = bc;
    	}
    	public Object addingService(ServiceReference reference) {
    		MonitorService service = (MonitorService)bc.getService(reference);
    		thread.addService(service);
    		return service;
    	}
    	public void modifiedService(ServiceReference reference, Object serviceObject) {
    		MonitorService service = (MonitorService)bc.getService(reference);
    		thread.addService(service);
    	}
    	public void removedService(ServiceReference reference, Object serviceObject) {
    		MonitorService service = (MonitorService)bc.getService(reference);
    		thread.removeService(service);
    	}
    }
    

    注意,在本文中只实现了Monitor一项服务,将来如需扩充到支持多项系统管理服务,可以为每一项或某一类服务各自实现一个ServiceTracker类来监视相应服务的可用性。


    代码清单8:ConsoleThread.java
                    
    package com.systemmanagement.console;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import com.systemmanagement.services.monitor.MonitorService;
    
    public class ConsoleThread extends Thread {
    	private HashSet<MonitorService> monitorServices=new HashSet<MonitorService>();
    	private boolean running = true;
    	public ConsoleThread(){};
    	
    	public void addService(MonitorService service){
    		this.monitorServices.add(service);
    	}
    	public void removeService(MonitorService service){
    		this.monitorServices.remove(service);
    	}
    	public void run() {
    		while (running) {
    		    for(Iterator<MonitorService> it=this.monitorServices.iterator();it.hasNext();){
    				MonitorService service=it.next();
    				System.out.println(service.getMonitorMessage());
    			}
    			try {
    				Thread.sleep(5000);
    			} catch (InterruptedException e) {
    				System.out.println("ManagementThread ERROR: " + e);
    			}
    		}
    	}
    	public void stopThread() {
    		this.running = false;
    		try {
    			this.join();
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    代码清单8是一个多线程程序,为演示之简便,在此例中它只是用一个HashSet持有当前可用的系统管理服务,并无限循环,依次执行各项系统管理服务。在实际情况中,完全可以与用户交互,根据用户的指令来执行相应的系统管理服务。


    代码清单9:ConsoleActivator.java
                    
    package com.systemmanagement.console;
    
    import org.osgi.framework.BundleActivator;
    import org.osgi.framework.BundleContext;
    import org.osgi.util.tracker.ServiceTracker;
    import org.osgi.util.tracker.ServiceTrackerCustomizer;
    import com.systemmanagement.services.monitor.MonitorService;
    
    public class ConsoleActivator implements BundleActivator {
    	
    	private BundleContext context = null;
    	private ServiceTracker tracker = null;
    	private ConsoleThread thread=new ConsoleThread();
    	
    	public void start(BundleContext context) throws Exception {
    		this.context = context;
    		tracker = new ServiceTracker(context, MonitorService.class.getName(),
    				new MonitorServiceTracker(context,thread));
    		tracker.open();
    		
    		this.thread.start();
    	}
    
    	public void stop(BundleContext context) throws Exception {
    		tracker.close();
    		this.thread.stopThread();
    	}
    }
    





    回页首


    五.运行和测试基于OSGi的应用程序

    一个基于OSGi的应用程序是由OSGi框架本身以及若干个Bundle组成,为了对其进行运行和测试,通常需要将各个Bundle Project一一打包成Bundle(jar文件),并部署到一个OSGi框架中,还是比较麻烦的。幸运的是,Eclipse已经对此提供了很好的支持,Eclipse本身是基于OSGi框架Equinox的,在Eclipse环境中可直接将各Bundle部署到Equinox框架中并运行之,对开发者来说十分便利,其具体步骤如下:

    在Eclipse中选择Run-->Run...菜单,在弹出的Run配置面板的左侧选中“Equinox OSGi Framework”,然后再选择其上方的“New”按钮创建一个新的运行配置,将其命名为“systemmanagement”,再选择右侧的Deselect All按钮,然后只选择我们想要运行的4个Bundles:包括我们前面开发的3个Bundle以及OSGi框架本身org.eclipse.osgi,其中还可以设置各个Bundle的Start Level, Start Level可用于控制各Bundle的启动顺序,Start Level低的Bundle会优先启动,例如我们可以将服务提供者Bundle cpumonitor的Start Level设为1,而将服务使用者Bundle console的Start Level设为2,如下图所示:


    图2 Bundle的运行配置
    Bundle的运行配置

    在Eclipse环境中的运行结果如下图,在控制台中会不断的显示一些系统管理信息,同时也可在控制台中运行各种OSGi控制台命令,如ss命令可用于显示各Bundle的状态,读者可以通过help命令了解更多的OSGi控制台命令。


    图3 在Eclipse中的运行结果
    在Eclipse中的运行结果

    我们也需要了解如何让这些Bundle脱离Eclipse环境来运行,首先需要将各个Bundle Project打包成一个Bundle(即一个jar文件),其步骤如下:

    在Eclipse主菜单中选File->Export,再在弹出窗口中选择Deployable plug-ins and fragments,再选下一步,在弹出窗口中选择我们上面开发的三个Bundle project,并指定Bundle的输出目录,点Finish即可,如下图所示:


    图4 导出Bundle
    导出Bundle

    然后可以在e:/system_management/plugins目录下找到三个jar文件,现在我们需要一个OSGi框架来运行它们。Equinox是目前最流行的OSGi框架,Equinox本身也被打包成一个Bundle,在Eclipse安装目录的plugins目录下即可找到它,如org.eclipse.osgi_3.2.0.v20060601.jar,将这个文件拷到e:/system_management目录下。在命令提示符下进入e:/system_management目录下,运行如下命令启动Equinox:

    java –jar org.eclipse.osgi_3.2.0.v20060601.jar –console

    启动之后会出现一个OSGi控制台,并且已经启动一个system bundle,这个bundle就是OSGi框架本身。现在我们可以在OSGi控制台中手工安装我们开发的三个Bundle,如下图所示:


    图5 安装Bundle
    安装Bundle

    随后,可以依次启动三个Bundle,这样整个应用就运行起来了,如下图所示:


    图6 运行Bundle
    运行Bundle

    请保留这个OSGi控制台并让应用继续运行,接下来我们还会在这个控制台中进行一些操作来体验OSGi的动态性。





    回页首


    六. 体验OSGi的动态性

    除了模块化以及面向服务编程之外,OSGi的另一个重要特点是其动态性,Bundle以及Bundle提供的服务可以随时消失或者重新加入,而其它使用服务的Bundle可以感知服务是否可用,并动态地改变自己的行为。应用程序在运行过程中,可以随时增加新的Bundle,停止或卸载已有的Bundle,如果有新的服务加入进来,这个服务也能立即被其它Bundle使用并由此动态地改变整个应用程序的行为,在整个动态改变的过程中,OSGi框架本身是稳定的,无需重启。以下我们将通过一些示例来体验OSGi的动态性:

    我们现在想给应用增加一个监视内存运行状态的功能,新建一个Eclipse plugin-in project,将其命名为com.systemmanagement.memorymonitor,这个Bundle的实现过程与com.systemmanagement.cpumonitor基本类似,最主要的不同是实现MonitorService服务的那个类,如以下代码所示,其它代码可参见本文所附的代码清单。


    代码清单10:MemoryMonitor.java
                    
    package com.systemmanagement.memorymonitor.impl;
    import com.systemmanagement.services.monitor.MonitorService;
    
    public class MemoryMonitor implements MonitorService {
    	public String getMonitorMessage() {
    		return "内存--物理内存总数:1G,可用数:300M";
    	}
    }
    

    同样,将这个Bundle export成一个jar文件到e:/system_management/plugins目录下,安装以及启动这个Bundle,这时我们发现输出的系统管理信息马上改变了,如下图所示:


    图7 安装以及启动一个新的Bundle
    安装以及启动一个新的Bundle

    再假定我们需要增强com.systemmanagement.cpumonitor这个Bundle的功能,让其提供更多的CPU信息,我们可以修改其中的CpuMonitor.java类,如下所示:


    代码清单11:CpuMonitor.java
                    
    package com.systemmanagement.cpumonitor.impl;
    import com.systemmanagement.services.monitor.MonitorService;
    
    public class CpuMonitor implements MonitorService {
    	public String getMonitorMessage() {
    		return "CPU--温度:40度,电压:1.4v,CPU占用率:20%";
    	}
    }
    

    再将这个Bundle export成一个jar文件,放到e:/system_management/plugins目录下,并在OSGi控制台中使用update命令更新这个Bundle,我们发现输出的CPU监视信息马上改变了,如下图所示:


    图8 更新Bundle
    更新Bundle

    读者还可以在OSGi控制台中尝试使用start,stop等命令启动和停止一些Bundle,观察输出信息的改变,由此来体验一下OSGi的动态性。

    由于基于OSGi的应用程序具有高度的模块化和动态性的特点,使得要对其进行扩展也变得非常的方便:一般来说,扩展就是增加新的Bundle,对其它Bundle基本无影响,如上面的例子所示,我们很方便地为应用程序增加了新的功能,更新了它已有的功能,而整个应用程序甚至都不需要重启。Equinox同时还借用了Eclipse中的扩展点的机制,利用扩展点,可以方便的为已有的Bundle扩展功能,但扩展点这一套机制目前还不是OSGi规范中定义的特性,仅是Equinox这一实现平台扩展出来的功能,使用了扩展点的Bundle将有可能不能在其它的OSGi实现框架中正常运行,这需要开发者权衡选择。





    回页首


    七.发布应用程序

    在上一节中我们在OSGi控制台中运行我们的系统管理程序,其中还需要手工install, start各个Bundle,显然这很麻烦,不太象一个真正的应用程序,本节将介绍如何构造出一个完整的基于OSGi的应用程序。

    首先,Equinox提供了在启动框架时自动安装Bundle以及启动Bundle的功能,这是通过定义config.ini文件来实现的,应用程序的目录结构如下:

    E:/SYSMGT_APP1
    │  run.bat
    │  org.eclipse.osgi_3.2.0.v20060601.jar
    ├─configuration
    │      config.ini
    └─plugins
           com.systemmanagement.console_1.0.0.jar
           com.systemmanagement.cpumonitor_1.0.0.jar
           com.systemmanagement.services_1.0.0.jar
    

    config.ini文件的内容如下:

    osgi.bundles=plugins/com.systemmanagement.cpumonitor_1.0.0.jar@1:start, 
     plugins/com.systemmanagement.console_1.0.0.jar@2:start, 
     plugins/com.systemmanagement.services_1.0.0.jar
    

    其中的@1,@2用于指定Bundle的Start Level, start表示当OSGi框架启动后即自动启动此Bundle。而run.bat是一个批处理程序,其内容如下:

    java –jar org.eclipse.osgi_3.2.0.v20060601.jar -console

    现在只需运行run.bat即可运行我们的系统管理应用程序了。

    Eclipse中还提供了两个Bundle, org.eclipse.equinox.common和org.eclipse.update.configurator,可用于自动发现和安装指定目录下新增加的Bundle。我们同样可以在Eclipse的plugins目录中找到这两个Bundle并将它们拷到E:/SYSMGT_APP1/plugins目录下,并修改config.ini文件的内容如下所示:

    osgi.bundles=plugins/org.eclipse.equinox.common_3.2.0.v20060603.jar@1:start,
     plugins/org.eclipse.update.configurator_3.2.0.v20060605.jar@2:start,
     plugins/com.systemmanagement.cpumonitor_1.0.0.jar@2:start, 
     plugins/com.systemmanagement.console_1.0.0.jar@3:start
    

    这样,当org.eclipse.update.configurator Bundle启动时,它会去自动发现和安装plugins目录新增的Bundle,但需注意,它并不能自动启动这些Bundle,OSGi协议目前也没有提供这样的标准服务来自动安装,管理和启动Bundle,我们可以使用如下的一些解决方案来更好地管理和分发Bundle:

    • 利用Eclipse的Update Manager:Eclipse Update Manager提供了一批API用于管理,下载,升级,安装Feature,一个Feature是一批Bundle的集合, 是下载和安装的最小单位。但Feature是Eclipse定义的,不是OSGi协议中定义的特性。
    • 使用FileInstall Bundle,这个Bundle可以监视某一个目录,如果这个目录中新增加了Bundle,它会自动将其install,如果有Bundle被更新了,它会自动将其update,如果有Bundle从此目录被移走,它会自动将其uninstall。可到 http://www.aqute.biz/Code/FileInstall下载这个Bundle,它可以运行于任何OSGi框架中。
    • 在Equinox孵化器(incubator)中有一个org.eclipse.equinox.simpleconfigurator,可用于管理和控制已安装的Bundle, 包括设置启动级别并自动启动它们。可访问http://www.eclipse.org/equinox/incubator并到其CVS库中下载




    回页首


    八. 小结

    本文介绍了基于OSGi开发一个应用程序的完整流程,包括模块划分,Bundle的设计与开发,部署与测试,发布应用程序等,并演示了基于OSGi编程所具有的模块化,面向服务,动态性,易扩展等优点。基于组件或构件编程是学术界提了多年的思想,笔者认为OSGi是一个比较彻底地体现这种思想的编程模型,基于OSGi编程将带来软件设计以及开发方式的改变并由此带来软件生产效率的极大提升。

     
    展开全文
  • JSP具有以下的优点: 1、将业务层与表示层分离:使用JSP技术,网络开发人员可充分使用HTML来设计页面显示部分(如字体颜色等),并使用JSP指令或者JAVA程序片段来生成网页上的动态内容; 2、能够跨平台:JSP支持绝...
  • 二是数据库逻辑结构的设计。准确理解一个系统的业务逻辑,合理规划设计,开发出适应其应用的应用系统。正确理解实际应用中的业务逻辑需求,解决系统之间模块的科学划分与结构组织,更好更快的开发设计系统。 此外,...
  • 校园初恋网正是这么一个辅助大学生校内恋爱的网络平台,它吸收交友网和婚恋网的优点,经过提炼和创新的一个新型大学生专用社交网络。它具备信息完善、更新及时、安全靠谱、贴心服务等优点,是大学生告别单身的不二...
  • 二是数据库逻辑结构的设计。只要在准确理解一个系统的业务逻辑之后才可能开发出适应其应用的应用系统来,并且在系统之间模块的科学划分与结构组织都是在正确理解实际应用中的业务逻辑需求的前提下完成的。 此外、...
  • 二是数据库逻辑结构的设计。只要在准确理解一个系统的业务逻辑之后才可能开发出适应其应用的应用系统来,并且在系统之间模块的科学划分与结构组织都是在正确理解实际应用中的业务逻辑需求的前提下完成的。 此外、...
  • 建设展会的互联网商务平台,发布展会信息,有效利用网络优势进行展会推广、展会招商、展位预定、服务合作、服务预定、参展商信息发布、网上观众预定、网上调研等,建立包含多功能的大型数据库,采用三层结构的应用...
  • 5.4 描绘软件结构的图形工具102 5.4.1 层次图和HIPO图102 5.4.2 结构图103 5.5 面向数据流的设计方法104 5.5.1 概念104 5.5.2 变换分析105 5.5.3 事务分析111 5.5.4 设计优化112 5.6 小结113 习题5114 第6章 详细...
  • 目前他是田纳西州NashvilleChristian广播网络和NorthStar工作室数据架构师。对于Louis而言,他全部职业经验几乎都与微软SQL Server有关,从早期版本一直到当前最新版本Beta版。Louis是一本讲数据库设计...
  • 什么是VLAN

    2013-10-23 09:59:12
     VLAN除了能将网络划分为多个广播域,从而有效地控制广播风暴的发生,以及使网络的拓扑结构变得非常灵活的优点外,还可以用于控制网络中不同部门、不同站点之间的互相访问。  VLAN是为解决以太网的广播问题和安全...
  • 我也来玩OSGI(一)

    千次阅读 2008-02-04 13:15:00
    OSGI 是由 1999 年成立的 OSGI 联盟提出的一个开放的服务规范...后来 Eclipse 组织注意到了 OSGi 的优点,决定将 Eclipse3.0 及后续版本的插件体系结构基于 OSGi 来实现,并专门成立了一个子项目 Equinox

    OSGI 是由 1999 年成立的 OSGI 联盟提出的一个开放的服务规范,最初的目的是为嵌入式设备,确切地说是为可以通过网络访问的设备提供一个通用的软件运行平台,屏蔽不同设备之间的硬件和操作系统差异,使软件可以动态地部署和更新。后来 Eclipse 组织注意到了 OSGi 的优点,决定将 Eclipse3.0 及后续版本的插件体系结构基于 OSGi 来实现,并专门成立了一个子项目 Equinox 来实现 OSGi R4 规范,把 Equinox 作为 Eclipse 的底层运行平台。Eclipse 组织的这一决定带来了双赢的局面,今天的 Eclipse 由于其出色的可扩展的体系结构,已经不再是一个单纯的 Java IDE,而是一个开放的开发平台,一个通用的可扩展的软件框架,OSGi 也不再局限于嵌入式领域,而是成为了一个通用的动态组件开发环境,在桌面,服务器端等领域得到了大量应用。 

        对模块化的支持是 Java 的一个重要的发展方向,目前 Java 的模块化标准还存在着JSR 277:Java Module Systems 和 JSR 291:Dynamic Component Support for Java 之争论,其中JSR291 的主要目的就要将 OSGi 引入到 Java 标准中去,JSR277 则是 SUN 发起的一个Java 模块化标准。但 OSGi 事实上已经得到了许多国际IT大企业的支持,并且已经有许多商业软件产品基于 OSGi 来开发,如 IBM 包括 Websphere Application Server(WAS), Rational Software Architecture(RSA) 在内的许多重量级软件产品均已基于 OSGi 来实现,著名的 IoC 框架 Spring 正在整合 OSGi 技术,现在基于 Eclipse 开发 RCP,插件程序也非常流行,可以预见基于OSGi 的 Java 应用程序将会越来越多,也将会有越来越多的软件开发组织改变其软件设计思想和开发方式,拥抱 OSGi 并开始享受 OSGi 带来的好处

        Eclipse 开发平台中对基于 OSGi 开发应用程序已经提供了较为完善的支持,在 Eclipse 集成开发环境中可以轻松地完成对一个或多个 bundle 的开发、调试、部署、测试等工作

        OSGi 带来了规范化的模块划分,低耦合的模块间关系,统一的模块开发方式,可动态插拔的模块管理环境。开发 OSGi 应用程序的第一步是在需求分析的基础上进行精心的模块划分,模块划分的原则是尽量保持单个模块的独立性,使模块与模块之间的耦合降到最小,每一个模块暴露给其它模块的信息最少,尽量让模块之间使用 OSGi 框架提供的服务注册机制来通信。一般可采用一个模块一个 Bundle 的方式,并为每一个 Bundle 在 Eclipse 环境中建立一个 Project 来进行开发,由于模块与模块之间的耦合很小,各个 Bundle 之间并不会象传统的开发方式中的各模块之间那样存在纠缠不清的包和类的引用关系,因此大部分Bundle的开发工作可以并行进行而不会互相影响。 

       对于OSGi的成功应用,最有名的应该是Eclipse了,它就是基于OSGi service platform的产品,而且Eclipse组织有一个OSGI R4 的实现,非常不错,它就是Eclipse的底层核心部分,负责插件的加载和卸载,它的名称叫 Equinox (月食),名称挺有趣,一个叫Eclipse(日食),一个叫Equinox (月食),看来想遮住Sun(太阳)的光芒了,也许SUN 公司是受了这个名称的刺激,所以后来SUN公司的Java开发工具NetBeans进步了不少,不过还是能从这个工具看到Eclipse的影子.

      下面我想通过一个比较简单的例子来介绍OSGI的开发,因为我主要专注与C/S这方面,对RCP技术有浓厚的兴趣,所以我的例子的开发环境为 Eclipse 3.3.1 + Equinox 3.3.1 + SWT/JFace 操作系统为 Windows XP ,电脑是 ThinkPad ,不过这些都影响不大,

      这个例子的需求为用户登陆是要求能动态的切换登陆验证的方式,比如通过DB登录方式、ConfigFile登录方式、LDAP登录方式或其它登录方式,切换登录方式要求客户端不需要重启,我们来试验一下,看看效果,在这里启动OSGI,出现登录对话框,输入用户名和密码,然后点击登录,根据控制台的输出知道这里是用 LDAP 方式登录的,然后我们在卸载这个登录模块 ,它的Bundle ID 是815 ,在控制台输入 stop 815

    再在登录对话框中登录,这时发现登录的方式改成了DB登录方式,我们在 stop 499 ,在点击登录,发现登录方式又变成了ConfigFile 登录方式,如果我们在 stop 453,这时所有的登录方式模块都已经卸载了,控制台会打印 登录服务不可用! 的信息

     

    ,好了,现在开始来新建这样的项目: 打开Eclipse ,右键弹出选择 "新 建" -> "项目" -->"插件项目" --> 输入插件项目名称,比如LoginServices 

    这个插件项目的作用是放登陆验证接口的,我们这里的登陆验证接口是

    package org.vwpolo.services;

    /**

     * @author vwpolo

     *

     */

    public interface LoginService {

     /**

         * 判断是否登陆成功

      * @param userName

      * @param password

      * @return

      */

     public boolean login(String userName, String password);

    }

    然后在项目的 META-INF/MANIFEST.MF 文件的 Runtime 标签页中将这个类所在的包导出:

    这样的话其他的项目就可以通过依赖这个项目使用这个登陆服务接口了,这个项目到着就结束了,这个项目主要是定义模型

       我们再通过上面这种方式新建另一个项目,这个项目就是负责我们登陆的设置,和管理登陆方式的插件项目,项目名称为 StartLoginBundle, 在 META-INF/MANIFEST.MF 文件的依赖选项卡中的 Imported Packages 中添加 org.vwpolo.services 包,还有其他的一些依赖包

    OK,这样的话环境就基本搭建起来了。

    展开全文
  • finally是异常处理语句结构的一部分,表示总是执行。 finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。 16、sleep...
  • 判定表的优点是容易转换为计算机实现,缺点是不能够描述组合条件。(×) 7. 需求分析的主要方法有SD法、OOA法及HIPO法等。(×) 8. 分层的DFD图可以用于可行性分析阶段,描述系统的物理结构。(×) 9. 信息建模方法...
  • 遗传算法的优点是将问题参数编码成染色体后进行优化, 而不针对参数本身, 从而不受函数约束条件的限制; 搜索过程从问题解的一个集合开始, 而不是单个个体, 具有隐含并行搜索特性, 可大大减少陷入局部最小的可能...
  • 这种所谓授权服务可以提供高保真度第2、第3和第4层过滤功能,而且可以进行扩展,以获得动态自我配置数据包过滤防火墙。授权服务可以提供如下一些服务: ● 第2层协议过滤,去除了网络中不接受第2层协议...
  • 文件组织结构:文件、文件元素、文件系统 •文件系统 = 文件管理程序(文件和目录集合)+ 它所管理全部文件; •文件系统是用户与外存接口; •为用户提供统一方法(以数据记录逻辑单位)...
  • ASP.NET精品课程+源代码

    千次下载 热门讨论 2009-01-05 20:15:51
    ASP.NET是微软发展体系结构.NET重要一部分,其中全新技术架构会让每个人编程变得更简便。ASP.NET 是一种建立在通用语言上程序构架,能被用Web服务器来建立强大Web应用程序。ASP.NET提供许多比以往...
  • 12.3 线程的优点 106 12.4 线程的缺点 107 12.5 描述符、延迟和退出 107 12.6 线程退出 108 12.7 线程协调和同步 108 12.7.1 互斥 108 12.7.2 信号量 108 12.7.3 条件变量 109 12.8 使用线程的服务器实例 ...
  • 在线考试系统文献综述

    热门讨论 2010-05-28 14:57:16
    教育行业可以通过网络进行学生和教职工管理、组织学生在线考试、在网站上发布学校相关信息等活动。这样不仅能增加学校管理透明度,还提高了学校管理水平。在线考试还能充分利用学校现有资源,大大减轻教师...
  • 软件工程知识点

    2012-12-02 21:34:25
    •开发团队的组织结构,人员组成与分工。 •项目成本预算。 •项目对硬件、软件资源需求。 •项目任务分解和每项任务里程碑标志。 •基于里程碑进度计划和人员配备计划。 •项目风险计划。 •项目监督计划。 ...
  • 1.4.3 Oracle DBA资源和组织 10 1.4.4 Oracle示例 11 1.4.5 Oracle数据库两天DBA课程 11 1.4.6 Oracle MetaLink 11 1.4.7 Oracle Web Conference 12 1.5 普通Oracle DBA日常工作 12 1.6 几点...
  • 二是数据库逻辑结构的设计;三是服务器设计。只要在准确理解一个系统的业务逻辑之后才可能开发出适应其应用的应用系统来,并且在系统之间模块的科学划分与结构组织都是在正确理解实际应用中的业务逻辑需求的前提下...
  • 尹成JAVA快速入门

    2020-12-08 15:12:43
    Java是一门面向对象编程语言,不仅吸收了C++语言各种优点,还摒弃了C++里难以理解多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。 Java语言作为静态面向对象编程语言代表,极好地...
  • 3.1 TCP/IP的优点 20 3.2 TCP/IP的层和协议 21 3.2.1 体系结构 21 3.2.2 传输控制协议 21 3.2.3 IP协议 23 3.2.4 应用层 25 3.2.5 传输层 25 3.2.6 网络层 25 3.2.7 链路层 25 3.3 远程登录(Telnet) 25 3.4 文件传输...

空空如也

空空如也

1 2 3
收藏数 52
精华内容 20
关键字:

动态网络组织结构的优点