EMF自定义后缀模型实例加载报错:MyExtFactoryImpl无法转换为Resource$Factory问题咨询
How to Fix "Cannot Cast MyExtFactoryImpl to Resource$Factory" Error When Loading Custom EMF Model Instances
你猜得完全没错——问题的核心就是那行错误的工厂注册代码。咱们先把事儿掰扯清楚:
MyExtFactoryImpl是EFactory的实现类,它的职责是创建你自定义元模型对应的实例对象;而resourceFactoryRegistry里需要的是Resource.Factory类型的实现类,负责解析和加载你的.myext格式的资源文件(本质上还是EMF默认的XMI结构,只是后缀被你自定义了)。这俩完全不是一个类型,直接放进去肯定会抛出类型转换异常。
解决方案步骤
替换错误的Resource Factory注册:
把原来的new MyExtFactoryImpl()换成XMIResourceFactoryImpl(EMF自带的XMI资源解析工厂),因为你的.myext文件本质还是XMI格式,这个工厂完全能处理。如果你的元模型生成代码时EMF自动生成了专属的ResourceFactory(比如MyExtResourceFactoryImpl),用那个也可以,效果一致。确保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




