Groovy代码编译为.class文件本地存储时遇MissingPropertyException求助
问题描述
我最近在研究如何将Groovy代码编译为.class文件并保存到本地,但遇到了MissingPropertyException异常。
相关代码
import gewu.blue.model.DynamicActionContextFactory def stringResult = "//\n" + "// Source code recreated from a .class file by IntelliJ IDEA\n" + "// (powered by FernFlower decompiler)\n" + "//\n" + "\n" + "package gewu.blue.action.system;\n" + "\n" + "import gewu.blue.exception.DataPermissionException;\n" + "import gewu.blue.kaovy.ActionContext;\n" + "import gewu.blue.model.ErrorInfo;\n" + "import gewu.blue.record.PermissionUtil;\n" + "import gewu.util.SpringUtil;\n" + "import groovy.lang.MetaClass;\n" + "import groovy.transform.Generated;\n" + "import java.util.List;\n" + "import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;\n" + "import org.codehaus.groovy.runtime.callsite.CallSite;\n" + "import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;\n" + "\n" + "public class ActionSaveData extends ActionContext {\n" + " private PermissionUtil permissionUtil;\n" + "\n" + " @Generated\n" + " public ActionSaveData() {\n" + " CallSite[] var1 = $getCallSiteArray();\n" + " super();\n" + " PermissionUtil var2 = (PermissionUtil)ScriptBytecodeAdapter.castToType(var1[0].call(SpringUtil.class, \"permissionUtil\"), PermissionUtil.class);\n" + " this.permissionUtil = var2;\n" + " MetaClass var3 = this.$getStaticMetaClass();\n" + " this.metaClass = var3;\n" + " }\n" + "\n" + " public Object run(List args) {\n" + " CallSite[] var2 = $getCallSiteArray();\n" + " Object record = var2[1].call(args, 0);\n" + " Object fields = var2[2].call(args, 1);\n" + " Object hasPermissionBeforeSave = var2[3].call(this.permissionUtil, record);\n" + " if (!DefaultTypeTransformation.booleanUnbox(hasPermissionBeforeSave)) {\n" + " throw (Throwable)var2[4].callConstructor(DataPermissionException.class, var2[5].callGetProperty(ErrorInfo.class));\n" + " } else {\n" + " var2[6].call(record);\n" + " var2[7].callStatic(ActionSaveData.class, ScriptBytecodeAdapter.createList(new Object[]{record}), ScriptBytecodeAdapter.createList(new Object[]{fields}));\n" + " return record;\n" + " }\n" + " }\n" + "}\n" def baseDir = "/Users/wangkaipeng/Desktop/groovy编译" new File(baseDir,"demo2"+".class").withWriter('utf-8') { writer -> writer.writeLine(stringResult) }
异常详情
异常信息:groovy.lang.MissingPropertyException: No such property: $getCallSiteArray for class: gewu.blue.action.system.ActionSaveData
问题分析与解决方案
你当前的做法完全错误——把反编译出来的Java代码(包含Groovy编译器生成的特殊符号$getCallSiteArray)直接写入.class文件,这不是编译,只是把文本当成字节码文件保存,必然报错。
正确的做法是编译Groovy源码,而非操作反编译后的Java代码:
- 编写真正的Groovy源码(示例
ActionSaveData.groovy):
package gewu.blue.action.system import gewu.blue.exception.DataPermissionException import gewu.blue.kaovy.ActionContext import gewu.blue.model.ErrorInfo import gewu.blue.record.PermissionUtil import gewu.util.SpringUtil class ActionSaveData extends ActionContext { private PermissionUtil permissionUtil = SpringUtil.getBean("permissionUtil") as PermissionUtil Object run(List args) { def record = args[0] def fields = args[1] if (!permissionUtil.hasPermissionBeforeSave(record)) { throw new DataPermissionException(ErrorInfo.INSTANCE) } record.save() ActionSaveData.staticMethod([record], [fields]) return record } }
- 使用Groovy编译器编译源码
- 方式一:通过Groovy CLI命令编译
groovyc -d /Users/wangkaipeng/Desktop/groovy编译 ActionSaveData.groovy- 方式二:在Groovy代码中调用编译器API
import org.codehaus.groovy.control.CompilerConfiguration import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer import groovy.transform.Generated def baseDir = new File("/Users/wangkaipeng/Desktop/groovy编译") def sourceFile = new File(baseDir, "ActionSaveData.groovy") def compilerConfig = new CompilerConfiguration() compilerConfig.setTargetDirectory(baseDir) // 如需添加生成注解等自定义配置,可添加自定义器 compilerConfig.addCompilationCustomizers(new ASTTransformationCustomizer(Generated)) // 编译源码 new GroovyClassLoader().compile(sourceFile, compilerConfig)
关键说明
$getCallSiteArray是Groovy编译器生成的内部方法,不会出现在手写的Groovy源码中,仅反编译class文件时可见。- 直接写入文本到
.class文件无法生成有效的字节码,必须通过Groovy编译器处理源码生成正确的class文件。
内容的提问来源于stack exchange,提问作者CarpeWang
相关产品推荐
相关产品推荐

