RCP Fragment

        最近业务上遇到了这样的一个需求:之前基于RCP开发的桌面客户端都是仅针对Windows平台的,但是Java本身是个跨平台的语言,而Tycho插件也支持同时打包出多个不同平台的Product,因此希望能够在项目编译打包时同时打包出多个平台下的可执行程序。然而,面临的问题在于,为了在客户端中嵌入浏览器的功能,我们使用到了第三方的jxbrowser库,这个库是平台相关的,分不同的平台版本(当然也有一个cross-platform的发布版本,但是我们还是不希望这样做,因为会引入多余的lib,这个库的体积也是比较大的),我们需要解决的问题是在打包时指导选择相对应的jar包版本,如Windows平台就选择Windows版本jar,Linux平台选择Linux版本的jar。

        问题比较清晰明了,乍一看解决起来应该也会比较轻松,但是网上关于RCP这个方面的内容实在太少,昨天各种Google、百度查了一天,才算弄出一个能够实现要求的方案,所以在这里记录一下。

        首先说说查找过程中都找到的一些可能的方案吧,最开始是在StackOverflow找到的一个相关的回答https://stackoverflow.com/a/20881028,这里说的方案简单来说就是为每一个平台建一个平台对应的fragment,然后通过feature将全部的这些fragment包含起来,借助feature中提供的平台过滤功能实现按需的插件选择安装。当时因为不清楚fragment和plugin的区别,以为是一样的,就想着将当前项目中的browser插件按平台分成多个,再到feature.xml中进行过滤选择。不过很快意识到这个做法有点问题,因为browser插件在另一个插件项目中有引用到,如果分成了browser-win32,browser-linux,browser-mac三个插件的话,那应该引用哪一个?当时真是希望有一个类似于接口一样的插件,由它对外提供服务,而分不同平台对其功能进行实现,后来发现fragment可以用来做这个。

        之后是找到了Bundle-NativeCode这个Header,但是网上找到的更多是用它将.dll,.so引入RCP的例子,感觉使用场景是这样的:我有些平台相关的共享库,在RCP应用里需要用到,我就可以通过Bundle-Native这个头定义在不同的平台环境下选择哪个库使用,然后代码里面的话通过System.loadLibrary()进行加载。不过因为我们平台相关的库是通过jar包形式进行引入的(即classpath),不是根据路径名这样动态加载的,因此感觉这种方法可能并不很适用我们的情况(当然没有深入了解Bundle-Native的功能,可能通过提供的一些配置选项能够实现)。

        最后就找到了fragment,觉得可行性很大,因为关于fragment的介绍中就有提供平台相关代码的功能,下面是官方wiki上的一点介绍:

Sometimes it is useful to make part of a plug-in optional, allowing it to be installed, uninstalled, or updated independently from the rest of the plug-in. For example, a plug-in may have a library that is specific to a particular operating system or windowing system or a language pack that adds translations for the plug-in's messages. In these situations, you can create a fragment that is associated with a particular host plug-in.

就开始搜fragment相关的内容,还是很少,几篇感觉比较有用的:OSGi – bundles / fragments / dependenciesEclipse fragment projects - Tutorial,和Steps to use Fragments to patch a plug-in。不过看完之后仍然觉得不很清楚,中间也考虑过各种使用方式,如通过fragment覆盖掉host plugin的build.properties文件,让实际使用的jar被打包进去,不过最终还是选择通过接口实现分离的方式,将接口性质的代码放在host plugin里,实现部分分散在各个平台相关的fragment中,最后通过feature进行fragment的平台过滤(其实插件MANIFEST.MF文件中有一个可用的头Eclipse-PlatformFilter控制平台过滤,但是使用这个头编译的时候总是报错,说环境不匹配,暂时也没有继续深究)。

        说说中间遇到的一些问题吧。一个是因为代码结构的问题,在使用到browser插件的工程中(称作consumer插件),还是会引用到fragment里提供的方法,所以在consumer的build.properties里添加了extra.. = platform:/fragment/[fragmentId]来告诉tycho注意解析fragment依赖,否则会编译报错。其实这里也可以在host plugin里提供一个空的实现,然后按照Steps to use Fragments to patch a plug-in中的方法,借助classpath查找顺序,使得运行时用fragment里面的实现替换掉host plugin里的实现,不过感觉太过麻烦暂时没有这样做。第二个就是host plugin的MANIFEST.MF中需要添加Eclipse-ExtensibleAPI: true这一条,说明本插件是支持对类和接口进行扩展的,不然也会报错。

        最终是成功编译出了win32 x86/x86_64和linux x86/x86_64版本的RCP Product,看了看具体的插件,确实是用的正确的jar包,Windows上试了试,程序没有什么问题。后来在Ubuntu14.04上测试linux版本的的可执行文件,开始一直是出现启动页面后就报错,最后是在.ini配置文件中添加了

--launcher.GTK_version 

2

这样一个配置之后问题解决,可以正常打开使用了,应该是gtk版本问题。所以这个问题算是解决了。

        后续可能会加一个实际的Demo展示如何使用fragment,这篇文章的话就先到这里吧,感谢阅读,文中说的有问题的地方也欢迎批评指正。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值