Manually uninstall OSGi bundle in the runtime

Sometimes in a RCP application, you may need to uninstall OSGi bundle in the runtime. With BundleContext, it’s doable. Here is a sample.

As you can see, you need to specify the bundle/plugin name.

不要放过SWT里的Resource Leak

最近出了几个奇怪的问题,打开时间的GUI会莫名的抛Exception,报“no more SWT handle”. 句柄(Handle)资源以前做Win32/MFC接触的比较多,转到Java/SWT之后就很少接触到。

出错原因很清楚,Resource不够了!SWT和Swing的实现方法不同,它还是使用了Native的资源,所以句柄资源不会被GC回收。Eclipse提供了一个叫Sleak的工具来检查Leak的情况。情况果然非常严重,主要原因是我们生成了大量的Image。不仅仅是Image,在使用Font,Color,GC的时候也要非常注意,遵循“谁生成谁销毁”的原因。

在RCP中加入Sleak的方法是–Application.java的start方法中加入:

之后,Sleak的界面会随着RCP启动。

Reference

使用nexus unzip repository plugin实现Eclipse p2代码仓库

使用RCP的同学们应该都知道,p2仓库管理软件包的Layout和maven自身的不同的。当使用Export Product时, 就可以看到repository文件夹里,软件包的放置是完全不同的。

Sonatype Nexus OSS可以部署p2的proxy repository, 但不能部署host repository (当然可以出银子买Professional版). 如何在OSS版里实现呢?大家可以通过unzip repository plugin来实现。

原理

unzip repository plugin的工作原理就是:

  • 指定某个Host Repository做为目标仓库
  • 解压Host仓库里的Zip文件,形成可以访问的且保留了原压缩包中文件夹结构的Virtual仓库

利用这个功能,就间接的做出p2的仓库,主要步骤:

  • 含有p2 layout的仓库做成zip
  • 上传或安装到某Host Repository
  • 设置Virtual Repository并指向Host Repository

Plugin安装

点这下载unzip repository plugin bundle file. 解压到Nexus的Plugin文件夹中,重启Nexus Server。

 配置Virtual Repository

以Eclipse Nebula 1.0为例,配置Virtual Repository。

2014-04-17_20-55-38

Eclipse Nebula Project提供了很多SWT的高级控件,很好的补充了原有的控件集。但它自身的Repository一直处于Snapshot状态,所以经常变动,很容易把持续集成搞挂。我们就遇到了两次。

有了Unzip virtual repository,这个情况就可以改变了。先下载Nebula 1.0的zip包,上传至一个Host Repo里。

2014-04-18_11-56-01

 

再新建一个Virtual Repository,Provider选择为“Unzip Repository Template”.

2014-04-17_21-34-01

2014-04-17_21-34-31

再去查看Virtual Repo,就可以看到Zip文件被解开成p2 layout的文件夹了。

2014-04-18_12-20-51

使用Virtual Repository

在Target Platform中使用我们定义的Virtual Repository,和普通的p2 repository一样。

2014-04-18_12-23-43

总结

unzip repository plugin很大程度上提高了Nexus的灵活性,不单单只是支持Maven的layout,还可以支持p2或其他layout. 我们的项目也可以向Nexus提交Eclipse RCP的代码仓库。

好东西,与大伙分享!

在Eclipse RCP中集成HTML/CSS/Javascript (Integrate HTML/CSS/Javascript in Eclipse RCP)

新项目对UI的要求很高,产品负责人常常要求实现比较Fancy的功能。基于Eclipse RCP平台,用SWT/JFace实现起来比较麻烦,而且组里人手也不够,逼得我们常常要找替代方案。

Eclipse RCP虽然在Look & Feel上有所提高,但它的强项且不是前端,而是在于代码组织(模块,服务),功能扩展等方面。但如果能在RCP环境中集成Web前端的技术(HTML/CSS/Javascript),那实现这些Fancy的功能就容易的多。顺着这个思路我做了些实践,做了一个小页面,可以选择本地图片,再做PS处理。

webkit_sample

基本方案 – 使用Browser控件

SWT支持Browser控件,到3.7M2之后开始支持各平台下WebKit。各平台对WebKit要求不同,要参考SWT FAQ。我的体会是Mac(Safari),Linux平台(GTK+ WebKit)很好,Windows比较差。此控件也支持MOZILLA(比较旧的版本),但效果很差,很多CSS库无法运行。(本文多在Linux下WebKit的实践。)

首先要嵌入Browser,

之后,Browser就会显示Google主页的内容。

本地的HTML/CSS/JS文件

当然我们不是要做真正的浏览器,目标是使用本地的文件。实现思路也很清楚,就是要访问RCP Bundle里的文件。RCP也是支持的,可以用如下代码。

假设有如下目录结构:

web_folder

但这里要注意一个问题,我们的HTML常常会用到JS或CSS等外部文件。如果这些文件全都打包在Jar文件里,HTML文件内容可以被正常访问,但CSS等就无法被引用了。

解决的方法也很简单,就是不打包这部分文件,可以使用Feature加Fragment的方法。

code_structure

webkit_test是Host Plugin, webkit_test_webfiles是它的Fragment,webkit_test_feature是包括这两个Plugin的Feature。在Feature的设置中,打开“Unpack这个Fragment在安装时”。这样就可以得到一个Folder而不是Jar。

feature_setup

如何和Java代码互通呢?

这是个大问题。用了HTML,那我们要不要写个Server或者某个嵌入式的Server呢?如果需要,方案就会比较复杂,毕竟RCP还是专注于桌面端的(虽然有RAP,那是后话)。但当我发现BrowserFunction后,这个问题就简单了。

假如,HTML想通过一个函数得到RGB中红、绿、蓝的值,这些值却是在SWT的Text中输入的。函数分别是r(), g(), b().

在RCP的Java代码中,

BrowserFunction构造的第一个入参是Browser Instance,第二个是函数名。这可以大大扩展JS的能力。

那SWT可以控制Brower吗?比如调用JS里的Function。答案也是可以的。首先Browser提供了很多的Listener,让SWT捕获各种事件,此外可以直接用Browse.excute()来执行JS Function。

比如JS中定义了draw()函数,Java代码就可以用如下代码来调用 。

总结

在Sample中,我集成了Two.js,jquery, jquery-ui和AlloyImage.js, 实现了一些图片选择处理的功能,Webkit都能工作良好,让我惊艳,也让我坚信这个方向探索的潜力。但也遇到了不少问题,如Resize时页面的刷新问题,如何调试HTML页面,跨平台问题等,还需要更多时间的探索。Sample的代码在GitHub上,在Ubuntu 13.04, Mac OS X 10.8上都可以工作良好。

JPDA调试Eclipse RCP程序

当你已经有了一个打包好的Eclipse RCP程序,如何利用JPDA调试呢?其实方法和《使用JPDA进行Java程序的Debug》中说的基本一样。有几点不同。

如何设置JPDA的参数?

RCP程序在打包完成之后,会同时生成.ini文件。JPDA的参数是不能放在这个文件里的,因为这是为OSGi Runtime准备的参数。我们需要在Java命令行里做,所以要手动启动RCP程序,不能用打包好的exe文件。

其实也就是手动把Equinox Launcher运行起来,然后Eclipse IDE就可以和RCP程序连接了。

导入源码

在设置Remote Java Application时,可以直接加入Source。