在RCP或者IDE的开发过过程中,有时我们需要利用一些第三方开源插件项目,但又不想改动其源码(方便后续的同步升级与该项目一致),这时fragment是个不错的选择。
最近我就遇到了这样的情况,然而凭着自己的一点理解,始终无法使fragment生效(不得不吐槽下eclipse插件开发确实小众,资料甚是难找),经过一天多的折磨,渐渐搞清了使用fragment的几个关键点,拿来分享。
先分享一个英文资料(http://wiki.eclipse.org/Steps_to_use_Fragments_to_patch_a_plug-in)
如果你照着做仍然不得其法,那么不妨继续看看我的理解和总结:
Step1:创建fragment
这个很简单,通过eclipse的新建向导,按照步骤创建即可,创建过程中需要指定fragment的ID、Version等信息(与plugin出奇一致),同时最重要的是指定该fragment对应的host插件,通过向导选择按钮配置即可。
进行到这一步,fragment创建完了,那么关键点来了,为了保证fragment中的配置文件(fragment.xml)和Java代码能够被host加载,并覆盖host对应的内容,需要做如下操作:
1)打开META-INF/MANIFEST.MF文件,点击MANIFEST.MF标签页,添加Eclipse-PatchFragment: true配置,按照我的理解,这个配置能够声明当前fragment为fragment(废话),host插件加载时需要同时加载该fragment,该配置能够保证fragment中的extension定义生效。
2)打开Runtime标签页,点击Classpath—>New,添加library.jar和“.”(完全按照向导默认即可),同时将library.jar上移到“.”之前
3)切换到build标签页,删掉“.”,然后保存。
Step2:Make Patch
在host插件中,找到你想修改的类,完完整整的复制到fragment源文件夹中(src),包路径及类名一定要一致,然后do what you want。
然而做完上述工作,启动后,你仍会发现,你改的代码不执行,仍然执行原host的代码,这是因为缺少如下重要的配置。
Step3:配置host插件
1)打开host插件(可以通过 Import—>Plug-ins and Fragment向导以Source Project或者Project with source folder方式导入)
2)打开META-INF/MANIFEST.MF文件,点击MANIFEST.MF标签页,添加Eclipse-ExtensibleAPI: true(该配置能够保证会去加载fragment的代码,但能否加载到还得靠下面的配置)
3)打开Runtime标签页,点击Classpath—>New,添加library.jar和“.”(完全按照向导默认即可),同时将library.jar上移到“.”之前
4)切换到build标签页,删掉“library.jar.”,然后保存。
※3)和4)与Step1中的2)和3)对应,总的来说是保证host插件在包路径类名相同情况下,优先加载library的代码逻辑,其次加载host本身代码逻辑,而library.jar则指向了fragment的源码,这样就保证了fragment的代码逻辑优先生效。
至此fragment的开发配置即完成。需要注意的是,打包形成最终成果物时,host插件是被更改过的,需要重新导出为插件(相比较其他方式,该方式对host改动最小),而不是原版第三方插件。
而如果你是个熟手的话,你会发现所有的操作,最终影响的只是MANIFEST.MF文件的配置,熟悉了这点你可以直接更改host插件的.MF 文件,而不必重新对host打包
备忘:同名通路径非代码文件比如除plugin.xml之外的其他文件是否按此方式也能生效,有待检验(可能需要在加载的代码逻辑处进行分支处理,类似NLS的操作)