You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

EMF自定义后缀模型实例加载报错:MyExtFactoryImpl无法转换为Resource$Factory问题咨询

How to Fix "Cannot Cast MyExtFactoryImpl to Resource$Factory" Error When Loading Custom EMF Model Instances

你猜得完全没错——问题的核心就是那行错误的工厂注册代码。咱们先把事儿掰扯清楚:

MyExtFactoryImplEFactory的实现类,它的职责是创建你自定义元模型对应的实例对象;而resourceFactoryRegistry里需要的是Resource.Factory类型的实现类,负责解析和加载你的.myext格式的资源文件(本质上还是EMF默认的XMI结构,只是后缀被你自定义了)。这俩完全不是一个类型,直接放进去肯定会抛出类型转换异常。

解决方案步骤

  1. 替换错误的Resource Factory注册
    把原来的new MyExtFactoryImpl()换成XMIResourceFactoryImpl(EMF自带的XMI资源解析工厂),因为你的.myext文件本质还是XMI格式,这个工厂完全能处理。如果你的元模型生成代码时EMF自动生成了专属的ResourceFactory(比如MyExtResourceFactoryImpl),用那个也可以,效果一致。

  2. 确保EPackage注册正确
    你已经在代码里把EPackage注册到了packageRegistry,但要注意用mp.getNsURI()来获取元模型的命名空间URI,避免硬编码出错——毕竟这个URI是EMF关联模型和元模型的关键标识。

修正后的完整代码

class GetModelObjects { 
    ResourceSet resourceSet = new ResourceSetImpl() 
    Resource metamodel 
    EPackage mp 
    Resource model 
    EFactory mappinginstance 

    def doTransform() { 
        // 注册Ecore元模型的资源工厂
        resourceSet.resourceFactoryRegistry.extensionToFactoryMap.put("ecore", new EcoreResourceFactoryImpl()) 
        // 注册自定义后缀的XMI资源工厂(关键修正)
        resourceSet.resourceFactoryRegistry.extensionToFactoryMap.put("myext", new XMIResourceFactoryImpl()) 
        
        // 加载自定义元模型
        metamodel = resourceSet.getResource(URI.createFileURI("myext.ecore"), true) 
        mp = metamodel.contents.get(0) as EPackage 
        
        // 将元模型注册到packageRegistry,让EMF能找到对应的工厂
        resourceSet.packageRegistry.put(mp.getNsURI(), mp) 
        
        // 加载自定义后缀的模型实例
        model = resourceSet.getResource(URI.createURI("model.myext"), true) 
        
        // 获取EFactory实例(如果需要创建新的模型对象时会用到)
        mappinginstance = mp.getEFactoryInstance() 
        
        System.out.println("Model contents:" + model.contents) 
    } 

    def static void main(String[] args) { 
        new GetModelObjects().doTransform() 
    } 
}

额外说明

  • 如果你不确定自己的.myext文件是不是XMI格式,可以用文本编辑器打开看看——开头应该是类似<myext:RootElement xmlns:myext="http://www.example.org/myExt">这样的XML结构,这就说明是XMI序列化的,用XMIResourceFactoryImpl完全没问题。
  • 要是后续你需要自定义模型的序列化格式(比如JSON或者自己的二进制格式),那时候才需要实现自己的Resource.Factory,但目前你的场景用默认的XMI工厂就足够了。

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

火山引擎 最新活动