Eclipse插件开发:外部JAR中类文件右键菜单不显示问题排查
原因分析
这个问题我之前开发Eclipse插件时也踩过坑,核心原因是外部JAR中的class文件和项目内的class文件对应Eclipse的模型对象完全不同:
- 项目内的class文件属于Eclipse Workspace的本地资源,对应的模型对象是
org.eclipse.core.resources.IFile,所以你原来的<adapt type="org.eclipse.core.resources.IFile">条件能成功匹配,菜单正常显示。 - 但外部JAR中的class文件属于归档资源,它并不属于Workspace内的IFile,而是对应
org.eclipse.jdt.core.IClassFile(当JDT解析该JAR时)或者更底层的org.eclipse.core.resources.IStorage接口实现类。因为你的可见性条件只匹配IFile类型,所以这些外部class文件触发右键时,菜单会被过滤掉。
解决方案
你需要修改<visibleWhen>的条件,让它同时覆盖项目内IFile和外部JAR中IClassFile(或通用IStorage)的场景,下面提供两种可行方案:
方案一:同时匹配IFile和IClassFile
这种方案明确区分两种资源类型,适合需要针对不同类型做特殊处理的场景:
<menuContribution allPopups="false" locationURI="popup:org.eclipse.ui.popup.any"> <command commandId="my_command" label="Test" style="push"> <visibleWhen> <iterate ifEmpty="false"> <or> <!-- 匹配项目内的class文件 --> <adapt type="org.eclipse.core.resources.IFile"> <test property="org.eclipse.core.resources.name" value="*.class" /> </adapt> <!-- 匹配外部JAR中的class文件 --> <adapt type="org.eclipse.jdt.core.IClassFile"> <test property="org.eclipse.jdt.core.classFile.name" value="*.class" /> </adapt> </or> </iterate> </visibleWhen> </command> </menuContribution>
注意事项
如果使用这个方案,需要在你的插件plugin.xml的<requires>节点中添加对JDT核心插件的依赖,否则IClassFile的适配会失效:
<requires> <import plugin="org.eclipse.ui"/> <import plugin="org.eclipse.core.resources"/> <import plugin="org.eclipse.jdt.core"/> </requires>
方案二:使用通用IStorage接口匹配
org.eclipse.core.resources.IStorage是Eclipse中所有可存储资源的通用接口,IFile和IClassFile都可以适配到这个接口,用它可以统一处理两种场景:
<menuContribution allPopups="false" locationURI="popup:org.eclipse.ui.popup.any"> <command commandId="my_command" label="Test" style="push"> <visibleWhen> <iterate ifEmpty="false"> <adapt type="org.eclipse.core.resources.IStorage"> <test property="org.eclipse.core.resources.name" value="*.class" /> </adapt> </iterate> </visibleWhen> </command> </menuContribution>
这种方案更简洁,不需要额外依赖JDT插件(除非你的命令逻辑本身用到JDT),适合大多数通用场景。
测试验证
修改配置后,重新部署你的插件,然后:
- 右键点击项目内的class文件,确认菜单正常显示;
- 展开项目依赖的外部JAR,右键点击其中的class文件,菜单应该也能正常显示了。
内容的提问来源于stack exchange,提问作者FP93
相关产品推荐
相关产品推荐

