我正在使用Groovy ConfigSlurper从Groovy脚本加载一个大型groovy文件(741KB),并在尝试进行编译时始终收到RuntimeException.
Groovy 2.1.1,Java 1.6(Apple / MacOSX)
我称之为:
conf = new ConfigSlurper().parse(new File('conf.groovy').toURL())
并始终获得以下例外. ConfigSlurper可以编译的文件大小是否存在已知限制?
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
General error during class generation: Class file too large!
java.lang.RuntimeException: Class file too large!
at org.objectweb.asm.ClassWriter.toByteArray(Unknown Source)
at org.codehaus.groovy.control.CompilationUnit$15.call(CompilationUnit.java:797)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1036)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:573)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:551)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:528)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:279)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:258)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:244)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:202)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:212)
at groovy.lang.GroovyClassLoader$parseClass.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at groovy.util.ConfigSlurper.parse(ConfigSlurper.groovy:146)
at groovy.util.ConfigSlurper$parse.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at write_users.run(write_users.groovy:19)
at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:257)
at groovy.lang.GroovyShell.run(GroovyShell.java:220)
at groovy.lang.GroovyShell.run(GroovyShell.java:150)
at groovy.ui.GroovyMain.processOnce(GroovyMain.java:588)
at groovy.ui.GroovyMain.run(GroovyMain.java:375)
at groovy.ui.GroovyMain.process(GroovyMain.java:361)
at groovy.ui.GroovyMain.processArgs(GroovyMain.java:120)
at groovy.ui.GroovyMain.main(GroovyMain.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.groovy.tools.GroovyStarter.rootLoader(GroovyStarter.java:106)
at org.codehaus.groovy.tools.GroovyStarter.main(GroovyStarter.java:128)
1 error
解决方法:
有一个已知的限制,但可以说它不是Groovy;它是ASM library,最终是Java.
正如Stuart Halloway在谈话中提到的那样,知道在抽象层次之下的一层发生了什么通常很有见地.
例如,this link显示此代码:
public byte[] toByteArray() {
if (index > Short.MAX_VALUE) {
throw new RuntimeException("Class file too large!");
}
……可能是此处显示的例外情况:
java.lang.RuntimeException: Class file too large!
at org.objectweb.asm.ClassWriter.toByteArray(Unknown Source)
为什么ASM方法会抛出此异常? This post州:
It turns out that the magic number for the “code too large” error is
65535 bytes (compiled byte code, not source code).
对于Groovy的内部实现,该文件可能太大,这会导致合成方法对于JVM来说太大.