在sbt中引用src文件:自定义Slick代码生成器遇类找不到异常
我之前也踩过这个坑,这个错误本质是sbt的类加载机制导致的——你放在app/utils下的自定义生成器类属于应用代码,需要先编译才能被sbt任务加载,但默认情况下你的自定义sbt任务并没有先触发编译步骤,或者没有正确引用编译后的类路径。下面是几个靠谱的解决办法:
先确保应用代码已编译,再运行生成任务
最简单的临时办法是先手动执行sbt compile,确保你的utils.MySourceCodeGenerator没有编译错误,已经生成到target/scala-<version>/classes目录里,再运行你的自定义生成任务。但这个方法每次改完生成器都要手动编译,有点麻烦。修改sbt任务,让它自动依赖编译并使用正确类路径
更好的方式是调整你的任务定义,让它依赖于Compile阶段,并且获取包含编译后类的完整类路径。比如把build.sbt里的任务改成这样:lazy val generateSlickCode = taskKey[Unit]("Generates Slick code with custom generator") generateSlickCode := { // 获取编译后的完整类路径 val classpath = (Compile / fullClasspath).value // 自定义生成器的全限定类名 val generatorClass = "utils.MySourceCodeGenerator" // 获取sbt的runner来执行类 val runner = (Compile / runner).value // 运行生成器,传递空参数列表 runner.run(generatorClass, classpath.files, Nil, streams.value.log) }这样每次运行
generateSlickCode时,sbt会先自动执行Compile任务,确保你的生成器类已经编译完成,再用正确的类路径去加载它。把生成器移到project目录下
如果你的自定义生成器不需要依赖应用里的其他代码,可以把它放到sbt的构建源码目录project下,比如project/utils/MySourceCodeGenerator.scala。project目录下的代码会在sbt加载构建定义时就被编译,属于sbt自身的类路径,直接在build.sbt里引用utils.MySourceCodeGenerator就不会出现找不到类的问题了。检查类名和包名的拼写
最后别忘了确认一下:你的类确实在utils包下,类名是MySourceCodeGenerator,没有大小写错误或者拼写失误——Java的类加载器是严格区分大小写的,哪怕一个字母错了都会导致找不到类。
内容的提问来源于stack exchange,提问作者Julian Wilson

