为什么SBT没有将插件生成的资源文件复制到classes文件夹?
问题原因与修复方案
核心错误1:projectSettings 配置位置错误
你把override val projectSettings放在了autoImport对象内部,不符合sbt AutoPlugin的规范。sbt只会识别插件对象直接定义的projectSettings属性,嵌套在autoImport里的配置不会被自动加载到项目中。如果你的项目没有在build.sbt手动调用configProcessor(Compile),所有配置默认都不会生效。
核心错误2:资源生成器绑定不严谨
在inConfig(cfg)块中注册资源生成器时,未明确指定配置范围,不同sbt版本可能出现范围绑定偏差,导致生成的文件不被识别为托管资源。
核心错误3:生成文件返回值校验缺失
resourceGenerators绑定的任务返回的Seq[File]必须包含所有生成SQL文件的完整绝对路径,sbt只会将这个序列里的文件自动复制到classes目录。如果SqlProcessor.process返回空序列或者路径错误,就会出现文件生成到resource_managed但不复制到classes的问题。
修复后完整代码
object SqlProcessorPlugin extends AutoPlugin { import autoImport._ override def requires = plugins.JvmPlugin override def trigger = noTrigger object autoImport { lazy val processorSettings = taskKey[File]("Settings for sql processing") lazy val processSqlTask = taskKey[Seq[File]]("Process Sql") def configProcessor(cfg: Configuration) = { inConfig(cfg) { Seq( processorSettings / target := resourceManaged.value / "sql", processorSettings / sourceDirectory := sourceDirectory.value / "sql", processSqlTask / fileInputs += (processorSettings / sourceDirectory).value.toGlob / ** / "*.sql", processSqlTask := { val generatedFiles = SqlProcessor.process( processSqlTask.inputFileChanges, (processorSettings / target).value ) // 可打开日志验证返回的文件路径是否正确 // streams.value.log.info(s"Generated sql files: ${generatedFiles.mkString(", ")}") generatedFiles }, // 明确绑定当前配置范围的资源生成器 cfg / resourceGenerators += processSqlTask.taskValue ) } } } // 将projectSettings移到插件对象顶层,sbt可自动加载 override val projectSettings = configProcessor(Compile) }
可选适配与验证
- 如果需要Test阶段也能读取生成的SQL文件,在项目build.sbt中添加配置即可:
configProcessor(Test) - 执行命令
sbt show Compile / managedResources,如果输出列表包含你生成的SQL文件,说明配置已经生效,执行sbt copyResources后会自动同步到target/classes目录。
内容的提问来源于stack exchange,提问作者evanbergstrom
相关产品推荐
相关产品推荐

