mvn构建后动态类转换抛出ClassCastException(Eclipse运行正常)
问题根因
该异常是MDHT(Medical Document Human Language Technology)框架基于EMF(Eclipse Modeling Framework)实现的模型注册机制差异导致的:
- Eclipse运行时会自动加载所有引入的MDHT插件的元模型配置,CONSOL(Consolidated CDA)模型的
ContinuityOfCareDocument实现类会提前注册到全局解析工厂中,解析XML时会自动匹配返回对应的子类实例 - Maven构建后的运行环境中,默认不会主动触发CONSOL模型的注册逻辑,且打包过程中容易丢失EMF扩展点配置,导致XML解析仅返回基础的
ClinicalDocumentImpl实例,无法强转为子类
解决方案
1. 显式触发CONSOL模型初始化
在加载CDA XML的代码执行前,先添加一行代码强制注册CONSOL元模型:
// 强制触发Consol包元模型注册到全局上下文 org.openhealthtools.mdht.uml.cda.consol.ConsolPackage.eINSTANCE.eClass();
2. 使用CONSOL专用资源工厂解析XML
替换默认的CDA解析工厂为CONSOL专用实现,确保解析时可以识别CCD文档结构:
import org.openhealthtools.mdht.uml.cda.consol.util.ConsolResourceFactoryImpl; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.common.util.URI; // 注册解析工厂 Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xml", new ConsolResourceFactoryImpl()); // 加载XML文件 Resource resource = Resource.Factory.Registry.INSTANCE.getFactory(URI.createFileURI("你的CCD文件路径")).createResource(URI.createFileURI("你的CCD文件路径")); resource.load(null); ClinicalDocument cda = (ClinicalDocument) resource.getContents().get(0); // 此时可正常强转 ContinuityOfCareDocument ccd = (ContinuityOfCareDocument) cda;
3. 检查Maven依赖配置
确认pom.xml中已引入CONSOL依赖,且依赖范围不是provided,确保打包时会将其包含到最终产物中:
<dependency> <groupId>org.openhealthtools.mdht</groupId> <artifactId>org.openhealthtools.mdht.uml.cda.consol</artifactId> <version>你使用的版本号</version> </dependency>
4. 修复可执行Jar打包配置
如果使用maven-shade-plugin打可执行Jar包,需要添加配置合并EMF的服务扩展文件,避免多个EMF相关依赖的扩展配置被覆盖:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.4.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <!-- 合并META-INF/services下的服务注册文件 --> <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/> <!-- 合并EMF插件的扩展配置 --> <transformer implementation="org.apache.maven.plugins.shade.resource.PluginXmlResourceTransformer"/> </transformers> </configuration> </execution> </executions> </plugin>
可选:增加类型校验逻辑
转换前增加类型判断,避免非法转换异常:
if (cda instanceof ContinuityOfCareDocument) { ContinuityOfCareDocument ccd = (ContinuityOfCareDocument) cda; // 执行后续业务逻辑 } else { // 处理非CCD格式文档的异常场景 }
内容的提问来源于stack exchange,提问作者Alexpandiyan Chokkan
相关产品推荐
相关产品推荐

