Groovy编译报错:无法加载CTAnchor类,缺失CTPosH依赖求助
我正在使用IntelliJ IDEA进行开发,build.gradle的依赖配置如下:
dependencies { compile project(":signer-core") compile 'org.codehaus.groovy:groovy-all:2.4.8' def poi_version = "3.17" compile "org.apache.poi:poi:${poi_version}" compile "org.apache.poi:poi-ooxml:${poi_version}" compile "org.apache.poi:poi-ooxml-schemas:${poi_version}" compile "org.apache.santuario:xmlsec:2.1.0" testCompile "junit:junit:4.12" }
当我在Groovy文件中编写以下代码时:
private CTAnchor getAnchorWithGraphic(CTDrawing drawing /*inline drawing*/, String drawingDescr, boolean behind) throws Exception { CTGraphicalObject graphicalobject = drawing.getInlineArray(0).graphic long width = drawing.getInlineArray(0).getExtent().getCx() long height = drawing.getInlineArray(0).getExtent().getCy() String anchorXML = "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" " + "simplePos=\"0\" relativeHeight=\"0\" behindDoc=\""+((behind)?1:0)+"\" locked=\"0\" layoutInCell=\"1\"" + "allowOverlap=\"1\">" + "<wp:simplePos x=\"0\" y=\"0\"/>" + "<wp:positionH relativeFrom=\"column\"><wp:posOffset>0</wp:posOffset></wp:positionH>" + "<wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>0</wp:posOffset></wp:positionV>" + "<wp:extent cx=\""+width+"\" cy=\""+height+"\"/>" + "<wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/><wp:wrapNone/>" + "<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\""+drawingDescr+"\"/><wp:cNvGraphicFramePr/>" + "</wp:anchor>" drawing = CTDrawing.Factory.parse(anchorXML) CTAnchor anchor = drawing.getAnchorArray(0) anchor.setGraphic(graphicalobject) return anchor }
出现编译错误:
Error:Groovyc: While compiling signer-office_main: java.lang.RuntimeException: java.lang.NoClassDefFoundError: Unable to load class org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor due to missing dependency org/openxmlformats/schemas/drawingml/x2006/wordprocessingDrawing/CTPosH
但相同代码在Java文件中可以正常运行。我查看CTAnchor.class时,确实无法找到CTPosH的声明,且使用的是最新版本的Apache POI。
这个问题的核心在于Groovy编译器与Java编译器对POI的OOXML Schema类的处理逻辑差异,以下是具体的解决思路和步骤:
理解依赖差异
你当前使用的poi-ooxml-schemas是Apache POI提供的精简版Schema依赖,只打包了最常用的OOXML类;而CTPosH这类相对小众的类不在这个精简包中。Java能正常运行是因为它在运行时可以通过XMLBeans的动态类加载机制按需生成缺失类,但Groovy编译器在编译阶段会严格检查所有依赖类的存在性,无法容忍这种缺失。替换为完整Schema依赖
修改build.gradle,移除精简版的poi-ooxml-schemas,替换为包含所有OOXML类的完整包:def poi_version = "3.17" // 移除精简版依赖 // compile "org.apache.poi:poi-ooxml-schemas:${poi_version}" // 添加完整Schema依赖 compile "org.apache.poi:ooxml-schemas:${poi_version}"调整Groovy编译配置(可选)
如果替换依赖后仍有问题,可以让Groovy和Java共享编译逻辑:
打开IDEA的File > Settings > Build, Execution, Deployment > Compiler > Groovy Compiler,关闭Compile groovy files independently选项,让Groovy复用Java的类加载路径和编译规则。体积优化(可选)
完整Schema包体积较大,后续打包时可以用ProGuard或Shadow插件剔除未使用的类,平衡开发便利性和最终包体积。
内容的提问来源于stack exchange,提问作者JDChi

