大型Ballerina项目执行bal build时触发Class too large异常求助
问题分析与解决:Ballerina构建时
ClassTooLargeException异常 成因分析
- Ballerina的JVM后端编译逻辑中,会将整个模块内的所有字符串常量集中生成到一个名为
$_string_constants的自动生成类中,通过一个初始化方法加载所有常量。 - JVM规范限制单个方法的字节码长度不能超过65535字节(64KB),当项目包含大量字符串常量(250+文件×至少2个const=500+常量)时,初始化这些常量的方法字节码长度超出限制,触发
org.objectweb.asm.ClassTooLargeException异常。 - 减少文件数量后,常量总数下降,方法字节码长度回到限制范围内,因此构建成功。
解决办法
- 拆分模块:将原单模块项目拆分为多个子模块,每个子模块只包含一部分常量文件。每个模块会独立生成自己的常量类,单个类的初始化方法长度就不会超标。
- 升级Ballerina版本:官方后续版本可能优化了常量生成逻辑(比如自动拆分常量类、优化初始化方法实现),修复了该问题,建议尝试升级到最新稳定版。
- 合并常量文件:将分散在多个文件中的相关常量合并到少量文件中,虽然常量总数不变,但可减少编译器处理的文件数量,部分场景下能缓解方法长度问题(更推荐拆分模块方案)。
- 优化常量定义:对于可通过逻辑生成的字符串,避免硬编码为
const,改用函数返回值的方式动态生成,减少硬编码常量的总数。
异常堆栈信息
[2022-11-23 15:37:08,733] SEVERE {b7a.log.crash} - Class too large: wso2healthcare/healthcare$0046fhir$0046r4/0/constants/$_string_constants org.objectweb.asm.ClassTooLargeException: Class too large: wso2healthcare/healthcare$0046fhir$0046r4/0/constants/$_string_constants at org.objectweb.asm.ClassWriter.toByteArray(ClassWriter.java:538) at org.wso2.ballerinalang.compiler.bir.codegen.split.constants.JvmBStringConstantsGen.generateConstantInit(JvmBStringConstantsGen.java:130) at org.wso2.ballerinalang.compiler.bir.codegen.split.JvmConstantsGen.generateConstants(JvmConstantsGen.java:91) at org.wso2.ballerinalang.compiler.bir.codegen.JvmPackageGen.generate(JvmPackageGen.java:809) at org.wso2.ballerinalang.compiler.bir.codegen.CodeGenerator.generate(CodeGenerator.java:96) at org.wso2.ballerinalang.compiler.bir.codegen.CodeGenerator.generate(CodeGenerator.java:71) at io.ballerina.projects.JBallerinaBackend.performCodeGen(JBallerinaBackend.java:309) at io.ballerina.projects.ModuleContext.generateCodeInternal(ModuleContext.java:473) at io.ballerina.projects.ModuleCompilationState$4.generatePlatformSpecificCode(ModuleCompilationState.java:132) at io.ballerina.projects.ModuleContext.generatePlatformSpecificCode(ModuleContext.java:381) at io.ballerina.projects.JBallerinaBackend.performCodeGen(JBallerinaBackend.java:165) at io.ballerina.projects.JBallerinaBackend.<init>(JBallerinaBackend.java:134) at io.ballerina.projects.JBallerinaBackend.lambda$from$0(JBallerinaBackend.java:112) at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1133) at io.ballerina.projects.PackageCompilation.getCompilerBackend(PackageCompilation.java:169) at io.ballerina.projects.JBallerinaBackend.from(JBallerinaBackend.java:111) at io.ballerina.cli.task.CompileTask.execute(CompileTask.java:130) at io.ballerina.cli.TaskExecutor.executeTasks(TaskExecutor.java:40) at io.ballerina.cli.cmd.BuildCommand.execute(BuildCommand.java:252) at java.base/java.util.Optional.ifPresent(Optional.java:183) at io.ballerina.cli.launcher.Main.main(Main.java:51)
内容的提问来源于stack exchange,提问作者Anjana
相关产品推荐
相关产品推荐

