简体   繁体   English

支持多个版本的Eclipse

[英]Supporting multiple versions of Eclipse

I have an Eclipse plugin and I am aiming for 3.1 or 3.2 as a minimum version to support. 我有一个Eclipse插件,我的目标是3.1或3.2作为支持的最低版本。 The problem is that some of my code only works in version 3.5 and above (see my other question: Is there an alternative to CaretListener in Eclipse? ). 问题是我的一些代码仅适用于3.5及更高版本(请参阅我的另一个问题: Eclipse中是否有替代CaretListener的方法? )。

Now that I have code that works in the older versions and different code that works in the newer versions, is there a way that I can call the newer code only if my plugin is running in version 3.5 or above and then revert to the old code if running anything older? 既然我有旧版本的代码和不同版本的代码,那么只有当我的插件在3.5或更高版本中运行然后恢复到旧代码时才能调用更新的代码。如果运行任何旧的?

As a test, I've created two plugins that have the same class within it (just doing slightly different things). 作为测试,我创建了两个在其中具有相同类的插件(只是略微不同的东西)。 I have marked the org.eclipse.ui dependency as a minimum of 3.5 in one plugin and 3.1 as a minimum in the other but I can't get the one that relies on 3.5 to be ignored in older versions... 我已经将org.eclipse.ui依赖项标记为一个插件中的最小值为3.5,而另一个插件中的最小值为3.1,但是我无法在旧版本中忽略依赖于3.5的那个...

Can anyone help? 有人可以帮忙吗?

Thanks, Alan 谢谢,艾伦

You could use org.eclipse.core.runtime.Platform to get the org.eclipse.ui Bundle and check the version. 您可以使用org.eclipse.core.runtime.Platform来获取org.eclipse.ui Bundle并检查版本。

Version ui = Platform.getBundle("org.eclipse.ui").getVersion();
// then do something with that

Register MyListener if >=3.5, and OldMyListener otherwise. 注册MyListener ,如果> = 3.5, OldMyListener否则。

EDIT: 编辑:

Right, the above is only good for capturing differences in runtime behaviour. 是的,上述内容仅适用于捕获运行时行为的差异。

Eclipse supports a couple of tricks for only loading some classes. Eclipse支持一些只加载某些类的技巧。

The easiest from a development point of view is the trick that @ShiDoiSi mentioned. 从开发的角度来看,最简单的是@ShiDoiSi提到的技巧。

Bundle myBundle = org.osgi.framework.FrameworkUtil.getBundle(this.class);
Version ui = Platform.getBundle("org.eclipse.ui").getVersion();
Version cutOff = new Version(3,5,0);
final Executable processListener;
if (ui.compareTo(cutOff)<0) {
    Class pc = myBundle.loadClass("my.pkg.OldListenerProcess");
    processListener = (Executable) pc.newInstance();
} else {
    Class pc = myBundle.loadClass("my.pkg.ListenerProcess");
    processListener = (Executable) pc.newInstance();
}
processListener.execute(targetObject);

Another option that uses more of the eclipse framework would be defining your own extension point so that contributions from other bundles can decide which version to use. 使用更多eclipse框架的另一个选项是定义自己的扩展点,以便其他bundle的贡献可以决定使用哪个版本。 Basically it's the same pattern as above, except the version checking is done by the dependency ranges on the plugin the contributes the Executable to run. 基本上它与上面的模式相同,除了版本检查由插件上的依赖项范围完成,这些依赖范围有助于运行Executable Depend on org.eclipse.ui [0.0.0,3.5.0) for the old way, and simply specifying org.eclipse.ui 3.5.0 (that's an open ended range on 3.5.0) for the current way. 对于旧方法依赖于org.eclipse.ui [0.0.0,3.5.0],并简单地为当前方式指定org.eclipse.ui 3.5.0(这是3.5.0上的开放范围)。 Then you can read your extension and instantiate the class provided. 然后,您可以阅读您的扩展并实例化提供的类。

If you were creating extra plugins for this (a little heavy weight for the 2 differences) you could define a command in your main plugin, and have the extra plugins provide the equivalent handler. 如果你正在为此创建额外的插件(对于2个差异稍微有点重),你可以在主插件中定义一个命令,并让额外的插件提供等效的处理程序。 The plugins would still have to have dependency ranges so that only one would load for the <3.5 or >=3.5 case. 插件仍然必须具有依赖性范围,因此只有一个将加载<3.5或> = 3.5的情况。 Then using the command API you could execute the command (and the correct handler would run). 然后使用命令API,您可以执行命令(并运行正确的处理程序)。

ICommandService cmdS 
  = (ICommandService) workbenchWindow.getService(ICommandService.class);
Command process = cmdS.getCommand("my.pkg.ListenerProcess");
ParameterizedCommand cmd = new ParameterizedCommand(process, null);
IHandlerService handlerS 
  = (IHandlerService) workbenchWindow.getService(IHandlerService.class);
IEvaluationContext ctx = handlerS.createContextSnapshot(false);
ctx.addVariable("toAddListener", targetObject);
handlerS.executeCommandInContext(cmd, null, ctx);

Then your implementation of handler would use HandlerUtil.getVariable(event, "toAddListener") to extract the object you need from the ExecutionEvent. 然后你的处理程序实现将使用HandlerUtil.getVariable(event, "toAddListener")从ExecutionEvent中提取你需要的对象。

It sounds to me that you should be supplying two plugins, one supporting version 3.1 to "just below" 3.5, and the other one from 3.5 upwards. 听起来你应该提供两个插件,一个支持版本3.1到“正下方”3.5,另一个支持从3.5向上。 So you don't really get to choose, it's basically the Eclipse plugin layer choosing the right one based on your version ranges. 所以你真的没有选择,它基本上是Eclipse插件层,根据你的版本范围选择正确的插件层。

Or if you provide just the compiled class files, then of course you could load the required class dynamically based on testing the version of the running Eclipse. 或者,如果您只提供已编译的类文件,那么您当然可以基于测试正在运行的Eclipse的版本动态加载所需的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM