`
德安德鲁
  • 浏览: 43667 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

OSGI-自动发现,加载Bundle(jar包)

    博客分类:
  • OSGI
阅读更多

 

一、 创建Plug-in Project工程,名为“PluginMgrCenter”,主要实现定时监控给定文件夹下jar包,对未加载的jar包进行加载

1、创建工程

 

2、工程结构如下图示意:    


 3、实现Activator类的方法,Activator类的作用,说白了就是该Bundle启动,停止会调用该类覆写的start(),stop()方法。

 

 

 

Activator类的start()方法中,保存osgi框架传进来的BundleContext对象,并启动一个定时任务。

 

代码如下:

 

package pluginmgrcenter;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

import directwatcher.DirectWatcherTask;
import directwatcher.ScheduleTimerPool;

public class Activator implements BundleActivator
{
	
	private static BundleContext bundleContext;
	
	public static BundleContext getBundleContext()
	{
		return bundleContext;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
	 * )
	 */
	public void start(BundleContext context) throws Exception
	{
		bundleContext = context;
		try
		{
			DirectWatcherTask directWatcherTask = new DirectWatcherTask(
					bundleContext, "d:\\plugin\\");
			ScheduleTimerPool.getInstance().schedule(directWatcherTask, 10000,
					10000);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception
	{
		System.out.println("Bye World!");
	}
	
}
 4、ScheduleTimerPool.java类定义了一个简单的定时器。用于定时执行DirectWatcherTask.java中的jar包扫描任务。
package directwatcher;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

public class ScheduleTimerPool
{
	
	private static ScheduleTimerPool scheduleTimerPool;
	
	static BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
	
	public static final ScheduleTimerPool getInstance()
	{
		if (null == scheduleTimerPool)
		{
			scheduleTimerPool = new ScheduleTimerPool();
		}
		return scheduleTimerPool;
	}
	
	private static Timer timer;
	
	public void schedule(TimerTask task, long deplay, long interval)
	{
		if (null == timer)
		{
			timer = new Timer();
		}
		timer.schedule(task, deplay, interval);
	}
}

 5、DirectWatcherTask.java中run()方法实现了对指定路径的jar包进行扫描

      a、如果发现该jar未被加载,则安装启动该jar包

      b、如果该jar包版本有更新,则更新该jar包

    代码如下:

 * 
 */
package directwatcher;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.TimerTask;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.Version;

/**
 * @author Administrator
 * 
 */
public class DirectWatcherTask extends TimerTask
{
	
	private BundleContext bundleContext;
	public String bundleFolderPath;
	
	public DirectWatcherTask(BundleContext bundleContext,
			String bundleFolderPath)
	{
		super();
		this.bundleContext = bundleContext;
		this.bundleFolderPath = bundleFolderPath;
		System.out.println("插件目录:" + bundleFolderPath);
	}
	
	@Override
	public void run()
	{
		try
		{
			if (bundleContext == null)
			{
				System.out.println("bundleContext is null");
				return;
			}
			
			File folderInfo = new File(bundleFolderPath);
			// 如果目录不存在
			if (!folderInfo.exists() || !folderInfo.isDirectory())
			{
				System.out.println("bundleFloderPath is error!");
				return;
			}
			
			File[] files = folderInfo.listFiles(new FileFilter()
			{
				
				@Override
				public boolean accept(File pathname)
				{
					if (!pathname.isFile())
						return false;
					return pathname.getName().toLowerCase().endsWith(".jar");
				}
			});
			
			List<Bundle> newBundleList = new ArrayList<Bundle>();
			for (File file : files)
			{
				ZipFile zipFile = null;
				try
				{
					zipFile = new ZipFile(file);
					ZipEntry zipEntry = zipFile
							.getEntry("META-INF/MANIFEST.MF");
					if (zipEntry == null || zipEntry.isDirectory())
						continue;
					InputStream inputStream = zipFile.getInputStream(zipEntry);
					Properties prop = new Properties();
					prop.load(inputStream);
					
					// 得到插件的名称和版本
					String bundleName = prop.getProperty("Bundle-SymbolicName");
					Version bundleVersion = Version.parseVersion(prop
							.getProperty("Bundle-Version"));
					
					Bundle preBundle = null;
					Bundle[] bundles = bundleContext.getBundles();
					for (Bundle bundle : bundles)
					{
						if (bundle.getSymbolicName().equals(bundleName))
						{
							preBundle = bundle;
							break;
						}
					}
					
					Bundle newBundle = null;
					// 如果之前没有此插件,则安装
					if (preBundle == null)
					{
						System.out.println("自动安装新插件:" + bundleName + "  "
								+ bundleVersion);
						FileInputStream fileInputStream = new FileInputStream(
								file);
						newBundle = bundleContext.installBundle(file.getName(),
								fileInputStream);
						fileInputStream.close();
					}// 否则更新
					else
					{
						if (bundleVersion.compareTo(preBundle.getVersion()) > 0)
						{
							System.out.println("自动将插件:" + bundleName + " 由 "
									+ preBundle.getVersion() + "更新到"
									+ bundleVersion);
							FileInputStream fileInputStream = new FileInputStream(
									file);
							preBundle.update(fileInputStream);
							newBundle = preBundle;
							fileInputStream.close();
						}
					}
					// 尝试启动插件
					if (newBundle != null)
					{
						newBundleList.add(newBundle);
					}
				}
				catch (IllegalStateException ex)
				{
					continue;
				}
				catch (Exception ex)
				{
					ex.printStackTrace();
				}
				finally
				{
					if (zipFile != null)
					{
						try
						{
							zipFile.close();
						}
						catch (Exception ex)
						{
							ex.printStackTrace();
						}
					}
				}
			}
			
			// 尝试启动所有的插件
			boolean isAllBundleStartSuccess;
			for (int i = 0; i < newBundleList.size(); i++)
			{
				isAllBundleStartSuccess = true;
				for (Bundle newBundle : newBundleList)
				{
					if (newBundle.getState() != Bundle.ACTIVE
							&& newBundle.getState() != Bundle.STARTING)
					{
						try
						{
							newBundle.start();
						}
						catch (BundleException e)
						{
							isAllBundleStartSuccess = false;
						}
					}
				}
				if (isAllBundleStartSuccess)
				{
					break;
				}
			}
			
			// 启动尝试启动失败的插件以打印异常信息
			for (Bundle newBundle : newBundleList)
			{
				if (newBundle.getState() != Bundle.ACTIVE
						&& newBundle.getState() != Bundle.STARTING)
				{
					try
					{
						newBundle.start();
					}
					catch (BundleException e)
					{
						e.printStackTrace();
					}
				}
			}
		}
		catch (Exception e)
		{
			System.out.println("quickwebframework_web:插件自动管理线程接到线程中止命令,线程已终止!");
		}
	}
	
}

 这样bundle管理Bundle已经成型了。

 二:配置Myeclipse的“Run Configurations”

进入“Run Configurations”页面-->单击 OSGI Framework后点击“新建”图标-->选中新建的默认名称为“New_configuration”的Launch。

在“New_configuration”的Launch右侧的“Bundles”标签页,右方选择“Deselect ALL”后,在 Bundles选择框中选择“PluginMgrCenter” bundle,如下图示意:

 
 然后在搜索栏中搜索“*osgi”进行搜索,搜索结果中选择“org.eclipse.osgi(3.5.1.R35x_v20090827)”如下:


 3、创建Plug-In测试工程

1、创建工程名为“PluginAgent”的Plug-in工程,用于被Bundle管理Bundle管理,呵呵,是不是很拗口?本文的实验就是安装,启动,更新。

工程目录结构如下:

 2、其中Activator.java如下,start()方法在控制台打印“hello pluginAgent!”  stop()方法打印“bye pluginAgent!”

代码如下

package pluginagent;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class Activator implements BundleActivator
{
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
	 * )
	 */
	public void start(BundleContext context) throws Exception
	{
		System.out.println("hello pluginAgent!");
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception
	{
		System.out.println("bye pluginAgent!");
	}
	
}

 3、导出“PluginAgent”工程为“PluginAgent.jar”的jar包,路径为D:\plugin


 

 四、测试

1、以第二步骤配置的 “New_configuration” Launch 运行。

2、执行“ss”命令,查询当前只有两个Bundle运行

3、等待控制台打印出“自动安装新插件:PluginAgent  1.0.0.qualifier”,则表示系统已经检测到“D:\plugin”目录下的jar包,并识别后开始加载。

4、“Hello pluginAgent”则表示PluginAgent.jar已经加载成功。

5、再次执行“ss”命令,观察到已经有“PluginAgent_1.0.0.qualifier”Bundle安装并且启动成功,状态为ACTIVE。

 

测试结果图示:



 

 

 

    

 

  • 大小: 24.4 KB
  • 大小: 6.6 KB
  • 大小: 5 KB
  • 大小: 54.5 KB
  • 大小: 28.6 KB
  • 大小: 37 KB
  • 大小: 20.6 KB
分享到:
评论
4 楼 德安德鲁 2013-06-27  
牛人云小白 写道
TM的,过了两天一看,还是这一篇旧作,啥时候出新么。大神。
爷今天去面试,祝爷好运。

新作正在酝酿,周五必发
3 楼 牛人云小白 2013-06-27  
TM的,过了两天一看,还是这一篇旧作,啥时候出新么。大神。
爷今天去面试,祝爷好运。
2 楼 德安德鲁 2013-06-20  
牛人云小白 写道
这位大神,请问尊姓大名?
我只能说,我仰慕你。

=============
牛人旱地小牛牛
1 楼 牛人云小白 2013-06-20  
这位大神,请问尊姓大名?
我只能说,我仰慕你。

相关推荐

Global site tag (gtag.js) - Google Analytics