SBT Assembly多主类配置问题:AWS Lambda任务Jar包按需构建
解决AWS Lambda作业Jar包的sbt配置问题
针对你的需求——仅按需构建job模块、为每个作业主类生成独立Jar包,以下是具体的配置方案:
1. 为每个作业主类创建专属Assembly任务
由于job模块包含多个主类,我们需要抛弃默认的assembly任务,为每个作业单独定义打包任务,这样既能指定主类,也能自定义Jar文件名。
单个作业的配置示例
假设你的job模块有两个作业:io.example.job.DataSyncJob和io.example.job.ReportGenerateJob,可以这样配置job模块:
lazy val job = project .settings(commonSettings: _*) .settings( // 禁用默认assembly任务,避免多主类报错 assembly := throw new IllegalArgumentException("请使用作业专属的assembly任务,如assemblyDataSyncJob"), // 配置DataSync作业的打包任务 assemblyDataSyncJob := assembly.value, mainClass in assemblyDataSyncJob := Some("io.example.job.DataSyncJob"), assemblyJarName in assemblyDataSyncJob := "job-data-sync.jar", // 配置ReportGenerate作业的打包任务 assemblyReportGenerateJob := assembly.value, mainClass in assemblyReportGenerateJob := Some("io.example.job.ReportGenerateJob"), assemblyJarName in assemblyReportGenerateJob := "job-report-generate.jar" ) .dependsOn(core)
批量生成任务(适合多作业场景)
如果作业数量较多,用循环批量生成任务更高效:
// 定义所有作业的名称和对应主类路径 val jobList = Seq( "DataSync" -> "io.example.job.DataSyncJob", "ReportGenerate" -> "io.example.job.ReportGenerateJob", "Cleanup" -> "io.example.job.CleanupJob" ) lazy val job = project .settings(commonSettings: _*) .settings( assembly := throw new IllegalArgumentException("请使用作业专属的assembly任务,如assemblyDataSync"), // 遍历作业列表,自动生成打包任务 jobList.foreach { case (jobName, mainClassPath) => val taskKey = TaskKey[File](s"assembly$jobName") taskKey := assembly.value mainClass in taskKey := Some(mainClassPath) assemblyJarName in taskKey := s"job-$jobName.jar" } ) .dependsOn(core)
2. 确保仅构建job模块及其依赖
执行作业专属的打包任务时,sbt只会构建job模块和它的依赖(core),不会触发service模块的构建——因为job和service是平级模块,互相没有依赖关系。
比如,构建DataSync作业的Jar只需执行:
sbt job/assemblyDataSyncJob
如果之前执行sbt job/assembly会触发service模块构建,大概率是因为root项目聚合了所有模块,且你误执行了root的全局assembly任务。使用上述模块专属任务就能彻底避免这个问题。
额外优化提示
- 可以自定义Jar的输出目录:
assemblyOutputPath in assemblyDataSyncJob := file("target/aws-jobs/job-data-sync.jar") - 确保sbt-assembly插件版本在0.15.0以上,避免兼容性问题。
内容的提问来源于stack exchange,提问作者Andreas Jarbol
相关产品推荐
相关产品推荐

