本范例主要演示如下技术点:
1、从OSGi外部启动OSGi容器
2、在OSGi容器内访问外部的资源文件
3、在OSGi容器内访问外部的类方法(通过反射机制)
关键点:
开发一个单独的Bundle,提供一个供外部访问的OSGi服务,外部程序在启动OSGi容器时通过反射的方式将外部的ClassLoader设置到该Bundle中,供其他Bundle访问外部资源用。
一、开发单独Bundle
1、接口及实现类
public interface ClassLoaderService {
public ClassLoader getClassLoader();
}
public class ClassLoaderServiceImpl implements com.cjm.osgi.common.service.ClassLoaderService {
private ClassLoader classLoader;
public ClassLoader getClassLoader() {
return classLoader;
}
public void setClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
//## 以下代码仅供参考,在实际的应用中不应该出现在此方法中 ##
try{
//读取OSGi容器外的资源文件
BufferedInputStream stream = new BufferedInputStream(classLoader.getResourceAsStream("readme.txt"));
byte[] b = new byte[1024];
int i;
while((i=stream.read(b))!=-1){
System.out.println(new String(b, 0, i));
}
//通过反射调用OSGi容器外的类方法
Class clazz = classLoader.loadClass("OuterService");
Object obj = clazz.newInstance();
Method method = clazz.getMethod("sayHello", String.class);
Object result = method.invoke(obj, "cjm");
System.out.println("sayHello result: " + result);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
2、Activator类
public class ClassLoaderBundleActivator implements BundleActivator {
private ServiceRegistration serviceRegistration;
public void start(BundleContext context) throws Exception {
//注册服务
serviceRegistration = context.registerService(ClassLoaderService.class.getName(), new ClassLoaderServiceImpl(), null);
System.out.println(">>>>> start " + context.getBundle().getSymbolicName());
}
public void stop(BundleContext context) throws Exception {
//注销服务
serviceRegistration.unregister();
}
}
二、外部程序启动OSGi容器
public class Test {
public void run(){
try{
//要加载的bundles
String osgiBundles = "org.eclipse.osgi_3.3.0.v20070530.jar@1:start,com.cjm.osgi.common.ClassLoaderBundle_1.0.0.jar@2:start";
//## 启动Equinox的配置 ##
//重要:缺省情况下,Equinox启动后马上shutdown,通过该参数配置Equinox启动后不关闭
FrameworkProperties.setProperty("osgi.noShutdown", "true");
//重要:让Equinox不检查eclipse.product和eclipse.application配置
FrameworkProperties.setProperty("eclipse.ignoreApp", "true");
FrameworkProperties.setProperty("osgi.bundles.defaultStartLevel", "4");
FrameworkProperties.setProperty("osgi.bundles", osgiBundles);
//bundles所在路径
String bundlePath = "./lib";
FrameworkProperties.setProperty("osgi.syspath", bundlePath);
//启动OSGi容器
EclipseStarter.run(new String[]{"-configuration", "configuration", "-console"}, null);
//取得BundleContext
BundleContext bundleContext = EclipseStarter.getSystemBundleContext();
if(bundleContext!=null){
for(int i=0;i<bundleContext.getBundles().length;i++){
Bundle bundle = bundleContext.getBundles()[i];
//通过反射将OSGi外部的ClassLoader对象设置到ClassLoaderBundle Bundle中
//这样,就可以在OSGi容器内部加载OSGi外部的资源了
if(bundle.getSymbolicName().equalsIgnoreCase("com.cjm.osgi.common.ClassLoaderBundle")){
Class clazz = bundle.loadClass(ClassLoaderServiceImpl.class.getName());
Object obj = clazz.newInstance();
Method method = clazz.getMethod("setClassLoader", ClassLoader.class);
method.invoke(obj, this.getClass().getClassLoader());
}
}
}else{
System.out.println("bundleContext is null");
}
while(true){
Thread.sleep(10000);
}
}catch(Exception ex){
ex.printStackTrace();
}finally{
try{
EclipseStarter.shutdown();
}catch(Exception e){
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Test t = new Test();
t.run();
}
}
Equinox的启动参数:
http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html
分享到:
相关推荐
BundleActivator接口允许开发者捕捉和响应bundle的启动和停止事件。BundleContext提供了与OSGi框架交互的执行时上下文环境,它用于访问框架提供的各种服务。而Bundle接口则代表了OSGi框架中的一个逻辑bundle。 6. ...
- **服务导向**:OSGi框架基于服务模型,促进了组件间的松耦合,使得服务消费者和提供者之间可以灵活地进行交互,而不必关心具体实现细节。 ##### 2.3 开发工具与参考实现 为了帮助开发者更好地利用OSGi技术,OSGi...
生命周期层是OSGi架构中位于模块层之上的层次,它允许开发者从外部管理应用或者构建能够自我管理的应用,赋予应用极大的动态性。在OSGi中,模块化应用的各个部分,即各个bundle,都可以独立地进行生命周期管理,而...
描述中的“NULL”意味着没有具体的描述内容提供,但我们可以从标签“源码”和“工具”中推测,这篇整理可能包含了OSGi框架的源代码解析和如何将其作为开发工具来使用的实践指导。 标签“源码”提示我们,文章可能...
FIPA是一个国际标准,旨在促进智能物理代理之间的交互和通信。它定义了一系列协议和服务,如对话管理、会话控制、消息传递等,以确保不同代理系统之间的互操作性。在Pando项目中,OSGi被用作实现FIPA规范的基础架构...
- **服务发布**:Spring-DM支持自动发布ApplicationContext中的bean为OSGi服务,简化了服务发现和交互的过程。 - **束生命周期管理**:Spring-DM提供了一系列API来控制束的启动、停止等操作。 - **资源抽象**:提供...
从开放系统的角度来看,一个开放系统是由相互交互的软件、硬件和人类组件组成的集合,旨在满足既定需求,并且其组件的接口规范是完全公开的,公众可以获得这些规范,并按照群体共识进行维护,组件的实现必须符合这些...
书中通过不同的食谱,展示了在Karaf中如何展示Camel的上下文信息,启动和停止Camel上下文,列出Camel上下文以及路由,这都是Camel开发中的基础操作。 对于Camel的路由操作,本书讲解了如何在Karaf中列出路由,展示...
- 独立集群(Standalone Cluster)是Flink最基础的部署方式,它不依赖外部资源管理框架,集群管理和资源分配由Flink自行处理。 - YARN(Yet Another Resource Negotiator)是Hadoop资源管理器,Flink可以通过YARN...
2. OSGi框架:Eclipse基于OSGi运行,了解OSGi的概念和它在插件中的作用。 3. PDE(Plugin Development Environment):Eclipse内置的插件开发工具,用于创建、编辑和调试插件项目。 4. Manifest.MF:每个插件的核心...
OSGi是一种模块化系统,用于管理Java应用程序的生命周期和服务,使得组件可以独立更新和交互,这对于大型复杂系统或嵌入式环境特别有用。 "barchart-wrap-jgit-master" 这个压缩包子文件名表明它是"Barchart Wrap ...
首先,安装Apache ServiceMix 7需要下载最新版本的二进制包,并按照官方文档的步骤进行解压、配置环境变量、启动服务器等操作。过程中需要注意的是,确保JDK版本与ServiceMix兼容,以及正确设置JAVA_HOME和PATH环境...
通过阅读源码,开发者可以深入了解CXF如何处理服务生命周期,消息传递,以及如何与外部系统的交互。此外,源码还包含了丰富的注释和测试用例,有助于理解代码逻辑和功能实现。 **学习和使用CXF源码:** 1. **熟悉...
此外,书中还会涵盖关键主题,如事件模型、扩展点、服务导向架构,以及如何与其他Eclipse组件和外部系统进行交互。这些技术是构建高效、可维护插件的关键,使开发者能够创建能够无缝集成到Eclipse工作台中的解决方案...
这一部分介绍了如何将 Drools 应用程序部署到 Drools Server 上,包括基本的部署流程、所需的配置文件以及如何确保应用程序正确启动和运行。 ##### 3.3 配置 - **REST/Camel 服务配置**:详细说明了如何配置 REST ...
5. `jna-platform-4.5.2.jar` 和 `jna-4.5.2.jar`:Java Native Access库,用于与本地操作系统进行交互,这里可能是为了某些特定操作系统的兼容性。 6. `httpclient-cache-4.5.13.jar`:提供了HTTP缓存功能,可以...
1. **Apache Servicemix基础**:Servicemix是基于OSGi容器的开源企业服务总线(ESB),它提供了一个灵活的平台来整合不同的系统和应用,通过各种协议和服务标准进行通信。它支持多种服务标准,如JMS、HTTP、FTP、...
在Java开发中,插件机制是一种常见的设计模式,它允许应用程序动态加载和卸载功能模块,从而提高了软件的可扩展性和灵活性。`JARCONNECTION`可能是某种自定义的或特定场景下的插件加载机制。虽然没有具体描述,但从...