You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Eclipse插件项目中程序化应用Papyrus Designer构造型?

问题分析与解决

问题背景

开发了一个基于Eclipse UML2的Java程序,负责加载.uml文件并执行模型转换,核心逻辑是应用Papyrus Designer的Codegen和C_Cpp Profile构造型,生成的模型可被Papyrus Designer识别并生成C++代码。该程序在标准Java项目中依赖插件JAR运行正常,但转为Eclipse插件项目后出现异常。

核心代码片段

Profile codegenProfile = loadProfile(codegenProfileUri); // 从插件JAR加载Profile资源并返回org.eclipse.uml2.uml.Profile
codegenProfile.define();
...
model.applyProfile(codegenProfile);
...
final Stereotype listHint = codegenProfile.getOwnedStereotype("ListHint");
model.applyStereotype(listHint);
// 其他构造型应用逻辑

遇到的异常

  1. 普通Java项目中必须调用define(),否则会抛出:
java.lang.IllegalArgumentException: profile "C_Cpp" has no Ecore definition
  1. 转为插件项目后,Profile能正常加载,但应用构造型时抛出:
java.lang.IllegalArgumentException: org.eclipse.uml2.uml.internal.impl.StereotypeImpl@540dcfba (name: ListHint, visibility: <unset>) (isLeaf: false, isAbstract: false, isFinalSpecialization: false) (isActive: false)
    at org.eclipse.uml2.uml.internal.operations.ElementOperations.setValue(ElementOperations.java:667)
    at org.eclipse.uml2.uml.internal.impl.ElementImpl.setValue(ElementImpl.java:307)

查看ElementOperations源码,问题根源在于:

EObject eObject = element.getStereotypeApplication(stereotype);

if (eObject == null) {
   throw new IllegalArgumentException(String.valueOf(stereotype));
}

说明Profile未被正确初始化,导致构造型应用后无法找到对应的实例。


解决方案

1. 完善插件项目的依赖声明

在插件的MANIFEST.MF中,显式添加以下依赖:

  • org.eclipse.uml2.uml
  • Papyrus Designer的Profile相关插件(如org.eclipse.papyrus.designer.languages.cpp.profile、org.eclipse.papyrus.designer.codegen.profile)
  • 确保依赖插件的版本与加载的Profile版本完全匹配,避免版本冲突。

2. 使用UML2标准机制加载Profile

插件环境下不要用自定义loadProfile方法读取JAR资源,改用UML2提供的注册式加载:

// 通过Profile的URI加载,插件环境会自动处理资源上下文
URI profileUri = URI.createURI("http://www.eclipse.org/papyrus/designer/codegen/Codegen");
Profile codegenProfile = UMLUtil.getProfile(profileUri, model);
model.applyProfile(codegenProfile);

或直接通过Qualified Name加载:

Profile codegenProfile = UMLUtil.getProfile("http://www.eclipse.org/papyrus/designer/codegen/Codegen", model);
model.applyProfile(codegenProfile);

此方式无需手动调用define(),UML2会自动完成Profile的定义与初始化。

3. 确保Profile资源与EMF注册表配置正确

  • 在plugin.xml中注册UML资源工厂:
<extension point="org.eclipse.emf.ecore.extension_parser">
    <parser type="uml" class="org.eclipse.uml2.uml.resource.UMLResourceFactoryImpl"/>
</extension>
  • 在build.properties的bin.includes中添加Profile的.uml文件路径,确保打包时资源被正确包含。

4. 配置正确的ResourceSet上下文

插件环境中加载模型时,需为ResourceSet配置对应的资源工厂与包注册表:

ResourceSet resourceSet = new ResourceSetImpl();
// 注册UML资源工厂
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap()
    .put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
// 注册UML包到EMF注册表
resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI, UMLPackage.eINSTANCE);
// 加载模型资源
Resource modelResource = resourceSet.getResource(modelUri, true);
Model model = (Model) modelResource.getContents().get(0);

5. 移除手动define()调用

插件环境下UML2会自动处理Profile的Ecore定义生成,手动调用define()可能导致上下文冲突,建议移除该调用。

内容的提问来源于stack exchange,提问作者Graham L

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:36:16