使用ShadowJar压缩Micronaut AWS Lambda包后遇ExceptionInInitializerError
解决ShadowJar压缩Micronaut Lambda包后运行报错问题
问题描述
原本90MB的Micronaut Lambda Jar包,通过Gradle ShadowJar任务启用minimize()后压缩至24MB,但部署到AWS Lambda后抛出java.lang.ExceptionInInitializerError异常,根源是io.micronaut.core.convert.DefaultConversionService初始化时出现空指针。
当前ShadowJar配置:
tasks.withType(ShadowJar) { mergeServiceFiles() minimize() setZip64(true) manifest { attributes 'Main-Class': 'mx.business.services.Application' } }
构建命令:./gradlew clean build 或 ./gradlew shadowJar
问题原因
ShadowJar的minimize()默认通过静态代码分析移除未被直接引用的类,但Micronaut框架大量依赖反射、注解处理器生成的类以及SPI服务加载机制,这些类无法被静态分析识别,导致核心初始化类(如ConversionService依赖的转换器)被误删,最终触发初始化异常。
解决方案
修改ShadowJar配置,添加minimize的保留规则,强制保留Micronaut核心依赖、自定义业务包及SPI配置文件:
tasks.withType(ShadowJar) { mergeServiceFiles() minimize { // 保留Micronaut核心依赖的所有类 include(dependency("io.micronaut:micronaut-core")) include(dependency("io.micronaut:micronaut-context")) include(dependency("io.micronaut:micronaut-function-aws")) // 保留自定义Lambda处理器及业务代码所在包 include("mx/business/services/**") // 保留SPI服务加载配置文件 include("META-INF/services/**") } setZip64(true) manifest { attributes 'Main-Class': 'mx.business.services.Application' } }
关键说明
- Micronaut核心依赖:必须保留
micronaut-core、micronaut-context等核心包,避免转换服务、上下文初始化所需的类被误删; - 自定义业务包:确保Lambda处理器类及业务逻辑代码不被移除;
- SPI配置文件:
META-INF/services目录下的文件是Micronaut组件SPI加载的关键,必须保留以保证框架组件正常初始化。
额外验证步骤
- 先构建未启用
minimize()的ShadowJar包,部署到Lambda确认能正常运行,排除其他配置问题; - 若仍有异常,可通过
./gradlew dependencyInsight --dependency io.micronaut:micronaut-runtime检查是否遗漏核心依赖,添加到include(dependency(...))规则中。
内容的提问来源于stack exchange,提问作者Jesús Toscano
相关产品推荐
相关产品推荐

