`
snoopy7713
  • 浏览: 1170018 次
  • 性别: Icon_minigender_2
  • 来自: 火星郊区
博客专栏
Group-logo
OSGi
浏览量:0
社区版块
存档分类
最新评论

OSGi尝试

    博客分类:
  • OSGi
阅读更多

最好的入门材料:

OSGI 实战 ,真的要感谢BlueDavy


这里还有用Webex产品录制的OSGi 的简单培训 OSGiInAction


当前的开源社区对OSGi 支持的基本情况是:

1. OSGi

 R4 core framework specification


2. Equinox latest Release3.2.2

 
3. Spring-OSGi



 1.0 M2
4. The Felix 0.8.0-incubator

 release is now available in Apache.
5. Knopflerfish 2.0.1

 released

OSGi 的特别适用于对于热插拨有强烈需求的系统,同时适合经常有系统模块的增加和删除的系统。如果你的系统没有上面的两种需求的一种,建议当前不要用OSGi 。当然这个不是定论,只是我的个人研究结果,原因如下:

 

1. OSGi 还没有成熟到象Spring那样,出现问题后,社区支持没有Spring那么多。

2. OSGi 因为要做到热插拨,所以采用了每个Bundle用自己的ClassLoader

在其Spec中有专门的章节讲述其ClassLoader的实现原理。但是当涉及到ClassLoader,我们必须面对一些我们不愿看到的事实, 实际上Java中ClassLoader的策略和管理上比较混乱。导致当前Java开源很多的Framwork和lib都有自己的 ClassLoader。如果我们的系统不用Spring,Log4J之类的框架,全部是自己的代码的话,是没有太多的问题。可以当你要引用第三方的库之 后,就要面对因为ClassLoader不同,而资源不能共享的问题。 Apache Commons Logging的Thread classloader的本来的目的是想在不同的线程能用不同的log4j配置文件,但是把Apache Commons Logging 引入OSGi 中就出现了问题,所以才有网上热烈讨论的SLF4j的解决方案。

仅管Spring-OSGi 已经提出了针对ClassLoader问题的解决方案,但是并没有纳入到OSGi 的标准中。就当前形势看OSGi 更倾向于实现自己的一套Bundles的解决方案,包括log, IoC,http, servlet。至今还没有考虑怎么兼容其它已经存在的类库的问题。

3. OSGi R4的Declare Service还不够强

OSGi R4的提出了一个Declare Service的Bundle,类似于Spring IoC的机制,目的是为了减少OSGi 的 侵入性,因为在R3时,用户必须用代码的方式注册Service和引用Service。 R4只要编写一个component的xml文件将现有的类声明为Service。而且不需要强制性实现接口,这是一个很好的趋势。只是还没有做到更好。 因为没有做到象Spring IoC那么强大,DS所支持的properites只是基本类型,还不能象spring那样直接注入bean。 <property name=”domain” ref=”domainBean”/>。不过希望总是有的,Spring-OSGi 的提出就是为了解决这些问题的。只是一个正式项目用Spring-OSGi 的M2版,似乎有些不可控的风险。这些项目都在发展...

4. Eclipse对OSGi 的开发还有些小问题

Eclipse本身尽管是用OSGi 作核心的,但是对OSGi 的开发的支持还是有一些小问题的。比如对封闭 jar包 的bundle,在IDE的工程中其它的bundle就不能识别。只能将jar包 解开为classes,然后再放到bundle中才行。

问题虽小,便是却很烦人。

但是上面的问题现在都已经有一定的解决方案,而且OSGi 在发展中,所以在OSGi R5中可能都会得到很好解决

下面和大家分享一下尝试的成功心得和失败经验:

因为当时是想在正式项目中应用OSGi ,所以不是写几个Test的那种尝试,愿能给大家一点帮助

1. 环境准备

我选择的环境比较大众化。

Eclipse3.3M6(使用最新的,是想看看对OSGi 的支持有没有更好一点,其实用Eclipse3.2.2也是一样的), Equinox OSGi R4

2. 最好的入门资料

OSGI 实战 ,真的要感谢BlueDavy

3. 了解Eclipse的OSGi 的开发环境

1) 先建立自己的我们的OSGi 运行环境。建立根目录,且定为D:\osgi \ 建立如下图的目录和文件。startup.jar是从Eclipse安装目录copy过来的。其实这个目录结构和Eclipse的安装目录结构是一样的。

Image001.png

Backup.bat是在windows下的启动脚本,其内容是: java -jar startup.jar –console

然后在Eclipse安装目录plugin子目录中copy下列OSGi 运行的基本jar包 到D:\osgi \plugins

org.eclipse.osgi _3.2.2.R32x_v20070118.jar

org.eclipse.osgi .services_3.1.100.v20060601.jar

再到http://download.eclipse.org/eclipse/equinox/drops/R-3.2.2-200702121330/index.php

去下载declare service bundle实现以及log实现。

org.eclipse.equinox.log_1.0.1.R32x_v20060717.jar

org.eclipse.equinox.ds_1.0.0.v20060601a.jar

同样copy到D:\osgi \plugins

接下来我们来配置文件。

配置文件为D:\osgi \configuration\config.ini

将其内容写为

#Configuration File
#Mon Apr 23 09:17:19 CST 2007
osgi

.clean=true
osgi

.console=
osgi

.noShutdown=true
osgi

.bundles=org.eclipse.osgi

.services_3.1.100.v20060601.jar@start, \
 org.eclipse.equinox.ds_1.0.0.v20060601a.jar@start, \
 org.eclipse.equinox.log_1.0.1.R32x_v20060717.jar @start
osgi

.bundles.defaultStartLevel=4
osgi

.framework=plugins/org.eclipse.osgi

_3.2.2.R32x_v20070118.jar
osgi

.configuration.cascaded=false
eclipse.ignoreApp=true
eof=eof

针对这个配置文件需要说明几点:

1. 每个key的含义网上已经有资料说明
2. osgi

.bundles中声明多个jar的时候,如果需要换行要加 “\”。这个网上一些资料没有说明,害我折腾了老半天。
3. osgi

.console,一般情况下空着,表示启动后就进入console模式。
如果填入一个prot号,表示是telnet的port。这个时候OSGi

进入telnet服务模式,用户可以用telnet来进行访问。
网上有人说用Equinox不能进入后台模式,而改用了Knopflerfish,
可能是不知道这种配置的作用吧,我已经在Linux下做过测试,用nohup ./backup.sh &


可以正常运行。
4. 还有一点就是对orgi.bundles配置时,bundle的声明顺序要注意。在同一级别的起动情况下,
请将越基础的bundle越声明在前面。因为我们不可能将启动顺序完全依赖于startLevel。

OK,运行backup.bat你应该会进入OSGi 的控制台。我们的自己的OSGi 环境已经搭建好了。

2) 将OSGi 运行目录配置到Eclipse中 Eclipse默认的OSGi 工作目录是Eclipse安装目录,所以我们需要配置Eclipse使其指向我们自己的OSGi 目录(D:\osgi \) 菜单Window/Preferences

Image005.png

Eclipse会自动将D:\osgi \plugins下的bundles都加载过来。下次在plugins下的jar有增减的话,打开该页面按Relod即可。

3) 建立一个OSGi Project 不建议用Eclipse的向导来建立Project,我们的工程路径一般是cvs或是svn目录,而不是eclipse workspace。所以我摸索出的建立工程的方法如下:先用向导建一个空的bundle工程

Image007.png

Image009.png

Image011.png

将这个在Eclipse workspace目录下建立的工程目录copy到你工程目录下,以后作为模板目录。

且定我们的工程目录如下

D:\cvs\myproject\
              \bundles\
                     \bundle_proejct_template\build.properties
                                         \src\
                                         \test\
                                         \bin\
                                         \META-INF\MANIFEST.MF
                                         \OSGI

-INF\

下次我们建立自己的项目时,第一步先copy一份bundle_proejct_template目录,

(如果有CVS目录,请将所有CVS目录清除),再将目录更名为你project的name

比如我们建了一个bundle工程起名为famework,

D:\cvs\myproject\bundles\framework\

Image013.png

Image015.png

Image017.png


这样一个Bundle工程就建立好了如果Eclipse没有将工程自动识别为OSGi bundle工程的话,可以在Eclipse package Explorer 中右键后如下图。

Image019.png

4) 我们的项目经常会用到log包,可是Apache common logging的ClassLoader机制和OSGi 的不兼容,所以在正式项目之前,我们必须解决这个难题。我用的网上是SLF4j的解决方案。在解决之前我们必须了解一些背景,首先我们打Log,经常会用到两个jar包 , 一个是commons-loggin包,另一个是log4j包。本质上我们是可以直接用log4j包来打log的,但是为了做到兼容其它的log,比如 Jdklog,simple log等等。其实个人觉得这个在具体的一个项目内都没什么大的意义。可是一个类库,比如spring,他就不能定死为log4j。所以spring内部的 logger都是用的commons-logging的LogFactory.getLog()。来作为log的接口,而没有直接用log4j。我们可以 在设置java环境变量 “org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger” 来指定commons logging 的实现为log4j. 而SLF4j呢,又更高一层地兼容commons logging(也是就JCL),同时兼容log4j,并且没有ClassLoader问题。

5) 建立slf4j-osgi bundle project 我们没有必要写代码,只是简单地将slf4j的jar包 做一层bundle的封装,再重新打包成jar包 ,并且作为bundle发布。先按上面介绍的方法建立slf4j-osgi bundle proejct 再download slf4j,将 slf4j-api-1.3.1.jar jcl104-over-slf4j-1.3.1.jar log4j-1.2.14.jar slf4j-log4j12-1.3.1.jar copy到 D:\cvs\myproject\bundles\slf4j-osgi \lib\ 下

D:\cvs\myproject\bundles\slf4j-osgi \META-INF\ MANIFEST.MF文件内容如下

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: slflog4josgi
Bundle-SymbolicName: slf.commons.logging.osgi


Bundle-Version: 1.1.0
Bundle-Vendor: slf
Bundle-Localization: plugin
Bundle-ClassPath: bin/, lib/jcl104-over-slf4j-1.3.1.jar, lib/slf4j-api-1.3.1.jar, lib/log4j-1.2.14.jar, lib/slf4j-log4j12-1.3.1.jar
Export-Package: org.apache.commons.logging, org.apache.log4j, org.apache.log4j.spi, org.apache.log4j.xml, org.slf4j
Import-Package: org.osgi

.framework;version="1.3.0"

D:\cvs\myproject\bundles\slf4j-osgi \build.properites文件内容如下

source.. = src/
bin.includes = bin/,\
               META-INF/,\
               lib/jcl104-over-slf4j-1.3.1.jar,\
               lib/slf4j-api-1.3.1.jar,\
               lib/log4j-1.2.14.jar,\
               lib/slf4j-log4j12-1.3.1.jar

6) 将OSGi bundle工程导出为jar包 在Eclipse Project Exploer工作区,右键选择”Export…”

Image021.png

Image023.png

Image025.png

7) 建立一个new bundle project,以测试slf4j-osgi ,为了使这个例子有一定的意义,

我们让这个bundle可以为控制台输出一个简单命令hello。

工程目录且为

D:\cvs\myproject\bundles\test-slf4j\

 
package

 gsb.service

.console

;
 
import org.eclipse.osgi

.framework.console.CommandInterpreter;


import org.eclipse.osgi

.framework.console.CommandProvider;


 
import org.apache.commons.logging.Log;


import org.apache.commons.logging.LogFactory;


 
public

 class

 SitesProviderConsole implements

 CommandProvider {


 private

 Log logger = LogFactory.getLog

(

CommandProvider.class

)

;
 public

 String

 getHelp(

)

 {


  StringBuffer

 buffer = new

 StringBuffer

(

)

;
  buffer.append

(

"\t

 sayHello – Just a test\n

"

)

;
  return

 buffer.toString

(

)

;
 }


 
 public

 void

 _sayHello(

CommandInterpreter ci)

 throws

 Exception

 {


  logger.warn

(

"logger.class="

+logger.getClass

(

)

.getName

(

)

)

;
        logger.warn

(

"This is a debug log from commons log!"

)

;
  System

.out

.println

(

"Hello, world!"

)

;
 }


}


 

META-INF/MANIFEST.MF

…
Service-Component: OSGI

-INF/console.xml
…

Import-Package: org.apache.log4j, org.apache.commons.logging, …
…

OSGI -INF/console.xml

 


<?xml

 version

="1.0"

 encoding

="UTF-8"

?>




<component

 name

="SiteProviderConsoleActivator"

>




 <implementation

 class

="gsb.service.console.SitesProviderConsole"

/>




 <service>






  <provide

 interface

="org.eclipse.

osgi

.fram

ework.console.CommandProvider"

/>




 </service>






</component>





分享到:
评论

相关推荐

    osgi学习笔记(一)

    状态的变化是由框架控制的,例如,当启动一个bundle时,框架会解析其依赖并尝试启动所有依赖的bundle。 在实际开发中,使用OSGi工具可以简化工作流程。例如,Eclipse IDE提供了对OSGi的支持,允许开发者在集成开发...

    基于osgi构建小例子

    你可以尝试修改`osgi.impl` Bundle中的代码,然后在不关闭框架的情况下更新Bundle,看看如何反映到运行的应用中。 8. **打包与部署** 最后,了解如何将这些Bundle打包成可部署的格式,如BND或ZIP文件,以便在不同...

    OSGI入门和例子

    OSGI(Open Services Gateway Initiative)是一种开放标准的Java模块化系统,它允许开发人员将应用程序...实践是检验理论的最好方式,所以动手尝试创建和管理自己的OSGI bundle,将会极大地提升你对这个框架的理解。

    OSGI参考例子程序

    OSGI(Open Services Gateway Initiative)是一种开放的标准框架,主要用于创建模块化、动态和可扩展的Java应用程序。...记住,实践是检验理论的最好方式,动手尝试这些例子,你将更深入地理解OSGI的魅力。

    OSGI 经典实例,入门

    实践是学习OSGI的最佳途径,尝试创建自己的bundle并与其他bundle通信,将会使你对OSGI有更深入的理解。 总的来说,OSGI提供了一种强大的方式来组织和管理Java应用程序,使其更加灵活和可维护。通过本教程中的实例,...

    org.osgi.framework.BundleException-glassfish

    2. **分析源码**:如果日志没有提供足够的线索,可以尝试查看OSGi框架和Glassfish的相关源代码,理解异常的具体原因。 3. **检查捆绑包**:确认所有依赖的捆绑包都已正确安装且符合版本要求,确保它们的元数据...

    java ClassLoader机制及其在OSGi中的应用

    在该模型下,当一个ClassLoader收到加载类的请求时,它首先会委托父加载器去尝试加载,只有当父加载器无法加载时,当前加载器才会尝试自己加载。这样设计避免了类的重复加载,并确保了核心类库的唯一性。 四、...

    osgi例子(用户登陆)

    当用户尝试登录时,这个bundle会与LDAP服务器通信,查询用户提供的用户名和密码是否匹配存在于目录服务中的记录。这种方式适用于大型组织,因为它可以集成到现有的用户管理系统中,提供集中化的身份验证。 3. **...

    OSGI错误分析解决

    还可能遇到权限问题,如"AccessControlException",因为尝试访问受保护的MBean操作而没有足够的权限。 解决OSGI错误通常涉及以下几个步骤: 1. **日志分析**:查看OSGI容器的日志,如Equinox或Felix的日志,找出...

    carrot-osgi-anno-scr-make-2.0.1.zip

    《Carrot-OSGi-Annotation-SCR-Make:探索开源项目的OSGI...对于那些涉及OSGi服务组件开发的项目,它无疑是一个值得尝试的利器。同时,该项目的开源性质也鼓励了社区的参与和共享,进一步推动了OSGi技术的普及和发展。

    OSGi理论与实战

    当需要加载类时,会遵循经典的委托模型,即先尝试从父ClassLoader加载,若未找到再在当前ClassLoader中查找。 #### Bundle类共享机制 类的共享通过在`MANIFEST.MF`文件中定义`Require-Bundle`、`Import-Package`、...

    Linux下OSGi框架实现笔记

    - 完成以上步骤后,可以尝试编译 CVM。 #### 三、CVM 的使用与测试 完成 CVM 的编译后,接下来可以将其部署到 ARM Linux 上,并进行简单的测试。 **部署步骤**: 1. 将编译好的 `phonemejavacvmbin` 目录复制到...

    OSGI-ROOT.rar

    标题中的"OSGI-ROOT.rar"表明这是一个与OSGi(Open Service Gateway Initiative)相关的压缩文件,通常包含了OSGi框架...如果需要更深入的了解,可以尝试下载并解压文件,查看其中的源码和工具,结合博客文章进行学习。

    osgi规范4.3.0

    最后,实践是最好的老师,尝试编写一些简单的OSGi应用,亲自动手实现服务注册、查找等功能,这将极大地加深对OSGi的理解。 通过以上介绍,我们可以看到OSGi 4.3.0规范不仅为Java开发者提供了一个强大且灵活的模块化...

    Getting Started with OSGi_ Part1

    在提供的部分内容中,我们得以窥见文章详细介绍了如何搭建一个基础的OSGi工作环境,这对于初次尝试OSGi的开发者来说是至关重要的。 文章首先提到,建立OSGi环境的首要步骤是选择一个OSGi框架。目前有三个开源实现可...

    Eclipse-OSGi内核源码分析.pdf

    在处理Bundle时,开发者需要注意异常处理,例如,当尝试启动或停止一个Bundle时,可能会遇到IOException或BundleException等异常情况。因此,合理地管理这些异常情况对于开发稳定的模块化应用至关重要。 Eclipse ...

    Getting Started with OSGi_ Part3

    当多个Bundle依赖于不同版本的同一包时,OSGi会尝试解决冲突。默认策略是使用最高版本的包,但开发者也可以自定义策略,如使用最低版本或者指定特定版本。 八、工具支持 在实际开发中,工具的使用可以极大地简化...

    kamon-osgi:尝试让 kamon 和 osgi 彼此喜欢

    "kamon-osgi"项目正是为了解决这个问题,尝试使Kamon与OSGI能够和谐共存。 该项目由两个主要插件组成: 1. **extKamon**:这是一个关键组件,它的任务是持有Kamon库,并负责导出Kamon所需的所有包。在OSGI环境中,...

Global site tag (gtag.js) - Google Analytics