【问题标题】:Supporting multiple versions of Eclipse支持多个版本的 Eclipse
【发布时间】:2011-10-28 20:43:34
【问题描述】:

我有一个 Eclipse 插件,我的目标是 3.1 或 3.2 作为支持的最低版本。问题是我的一些代码仅适用于 3.5 及更高版本(请参阅我的另一个问题:Is there an alternative to CaretListener in Eclipse?)。

既然我有在旧版本中工作的代码和在新版本中工作的不同代码,有没有一种方法可以让我只有在我的插件在 3.5 或更高版本中运行然后恢复为如果运行旧代码,旧代码?

作为测试,我创建了两个具有相同类的插件(只是做的事情略有不同)。我已将 org.eclipse.ui 依赖项在一个插件中标记为至少 3.5,在另一个插件中标记为至少 3.1,但我无法在旧版本中忽略依赖 3.5 的那个版本...

谁能帮忙?

谢谢, 艾伦

【问题讨论】:

  • Eclipse 3.1/3.2?我认为您应该首先问自己是否真的需要支持旧的 Eclipse 版本。 3.1 于 2005 年问世。如果某些客户/客户使用的是那么旧的 Eclipse 版本,我会说您应该首先专注于鼓励他们升级。
  • 感谢 Fredrik,我同意您的观点,但 3.4 版仅在 2008 年发布 - 至少支持它会很好。所以,我仍然有兴趣了解它是否可能,因为它只是一个依赖项是一个问题。

标签: eclipse eclipse-plugin dependencies version multiple-versions


【解决方案1】:

您可以使用org.eclipse.core.runtime.Platform 获取org.eclipse.ui Bundle 并检查版本。

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

如果 >=3.5 则注册 MyListener,否则注册 OldMyListener

编辑:

是的,以上内容仅适用于捕获运行时行为的差异。

Eclipse 支持一些只加载某些类的技巧。

从开发的角度来看,最简单的是@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);

另一个使用更多 Eclipse 框架的选项是定义您自己的扩展点,以便其他包的贡献可以决定使用哪个版本。基本上它与上面的模式相同,除了版本检查是由插件上的依赖范围完成的,它贡献了Executable 来运行。旧方式依赖 org.eclipse.ui [0.0.0,3.5.0) ,而当前方式只需指定 org.eclipse.ui 3.5.0 (这是 3.5.0 上的开放范围)。然后你可以阅读你的扩展并实例化提供的类。

如果您为此创建额外的插件(这两个差异有点重),您可以在您的主插件中定义一个命令,并让额外的插件提供等效的处理程序。插件仍然必须具有依赖范围,以便在 =3.5 的情况下只加载一个。然后使用命令 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);

然后您的处理程序实现将使用HandlerUtil.getVariable(event, "toAddListener") 从 ExecutionEvent 中提取您需要的对象。

【讨论】:

  • 如果我对发帖人的理解正确,他说的是 API 差异,所以他需要针对两个(互斥)接口进行编译。
  • 是的,我在谈论 API 差异,并且在运行时检查版本不是一种选择。目前,我已同意至少支持 3.5,但仍会感谢任何其他建议。
【解决方案2】:

在我看来,您应该提供两个插件,一个支持 3.1 版到“略低于”3.5,另一个支持 3.5 版以上。所以你不必真正选择,它基本上是 Eclipse 插件层根据你的版本范围选择正确的。

或者如果你只提供编译后的类文件,那么当然你可以根据测试运行的 Eclipse 的版本动态加载所需的类。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-11
    • 2015-01-22
    • 2021-08-22
    • 2019-08-12
    • 2018-01-15
    • 1970-01-01
    • 2012-09-24
    • 1970-01-01
    相关资源
    最近更新 更多