"object is not a member of package" 当通过 slick codegen 导入从另一个项目构建的依赖项时
"object is not a member of package" when importing dependency built from another project via slick codegen
我有一个这样的多项目设置:
lazy val kalosrpc = project
.settings(
libraryDependencies ++= Seq(
"io.grpc" % "grpc-netty" % scalapb.compiler.Version.grpcJavaVersion
)
).dependsOn(kalosgen)
lazy val kalosgen = project
.settings(
// settings not important
)
kalosgen
的主要 class 通过 slick-codegen
生成模型并将其放置在:
kalosgen/target/scala-2.13/src_managed/main
在包中 com.kalos.gen
。它还在编译时将 protobufs 编译成 scala classes,但该包按预期位于 class 路径中。
然后我可以将这些文件从 kalosgen
导入到 kalosrpc
,intelliJ 不会抱怨并且可以完全访问这些文件中定义的类型信息。所以我 运行 kalosgen/compile
并且包是按照我的预期生成的,但是当我用 kalosrpc/compile
跟进时,我得到:
object gen is not a member of package com.kalos
我试过更改包的名称,但没有解决任何问题。根据信息 presented here 我的项目配置似乎是正确的。
尝试从 sbt 执行 show sourceManaged
,它应该输出 generated files 应该结束的位置,例如在我的项目中它是
.../myproject/target/scala-2.13/src_managed
应该是
kalosgen/target/scala-2.13/src_managed/main/com/kalos/gen
而不是
kalosgen/target/scala-2.13/main/com/kalos/gen
还要仔细检查生成的文件是否在顶部包含包 。
这里的问题是我通过 slick-codegen
实用程序在 scala 代码中生成源代码:
import slick.codegen.SourceCodeGenerator
object Main extends App {
val url = "hidden"
val user = "hidden"
val password = "hidden"
val dbDriver = "com.mysql.jdbc.Driver"
val profile = "slick.jdbc.MySQLProfile"
SourceCodeGenerator.main(
Array(
profile,
dbDriver,
url,
"./kalosgen/target/scala-2.13/src_managed/main",
"com.kalos.gen",
user,
password
)
)
}
我的猜测是,您必须通过 SBT 任务生成源代码才能让 SBT 将它们识别为有效源代码(至少对于项目间依赖性而言),因此我能够将上述代码翻译成在 build.sbt
:
编译时运行的任务
lazy val gen = project
.settings(
libraryDependencies ++= Seq(
"dependencies"
),
sourceGenerators in Compile += Def.task {
val outDir = (sourceManaged in Compile).value.getPath
(runner in Compile).value.run(
"slick.codegen.SourceCodeGenerator",
(dependencyClasspath in Compile).value.files,
Array(
"slick.jdbc.MySQLProfile",
"com.mysql.jdbc.Driver",
"url",
outDir,
"com.kalos.gen",
"username",
"password"
),
streams.value.log
)
Seq(file(outDir + "/com/kalos/gen/Tables.scala"))
}.taskValue
)
现在生成的 Tables.scala
出现在 class 路径中,我的项目编译成功。如果对 sbt 有更多了解的人可以更全面地解释为什么会发生这种情况,我会很乐意接受它作为正确答案。
我有一个这样的多项目设置:
lazy val kalosrpc = project
.settings(
libraryDependencies ++= Seq(
"io.grpc" % "grpc-netty" % scalapb.compiler.Version.grpcJavaVersion
)
).dependsOn(kalosgen)
lazy val kalosgen = project
.settings(
// settings not important
)
kalosgen
的主要 class 通过 slick-codegen
生成模型并将其放置在:
kalosgen/target/scala-2.13/src_managed/main
在包中 com.kalos.gen
。它还在编译时将 protobufs 编译成 scala classes,但该包按预期位于 class 路径中。
然后我可以将这些文件从 kalosgen
导入到 kalosrpc
,intelliJ 不会抱怨并且可以完全访问这些文件中定义的类型信息。所以我 运行 kalosgen/compile
并且包是按照我的预期生成的,但是当我用 kalosrpc/compile
跟进时,我得到:
object gen is not a member of package com.kalos
我试过更改包的名称,但没有解决任何问题。根据信息 presented here 我的项目配置似乎是正确的。
尝试从 sbt 执行 show sourceManaged
,它应该输出 generated files 应该结束的位置,例如在我的项目中它是
.../myproject/target/scala-2.13/src_managed
应该是
kalosgen/target/scala-2.13/src_managed/main/com/kalos/gen
而不是
kalosgen/target/scala-2.13/main/com/kalos/gen
还要仔细检查生成的文件是否在顶部包含包
这里的问题是我通过 slick-codegen
实用程序在 scala 代码中生成源代码:
import slick.codegen.SourceCodeGenerator
object Main extends App {
val url = "hidden"
val user = "hidden"
val password = "hidden"
val dbDriver = "com.mysql.jdbc.Driver"
val profile = "slick.jdbc.MySQLProfile"
SourceCodeGenerator.main(
Array(
profile,
dbDriver,
url,
"./kalosgen/target/scala-2.13/src_managed/main",
"com.kalos.gen",
user,
password
)
)
}
我的猜测是,您必须通过 SBT 任务生成源代码才能让 SBT 将它们识别为有效源代码(至少对于项目间依赖性而言),因此我能够将上述代码翻译成在 build.sbt
:
lazy val gen = project
.settings(
libraryDependencies ++= Seq(
"dependencies"
),
sourceGenerators in Compile += Def.task {
val outDir = (sourceManaged in Compile).value.getPath
(runner in Compile).value.run(
"slick.codegen.SourceCodeGenerator",
(dependencyClasspath in Compile).value.files,
Array(
"slick.jdbc.MySQLProfile",
"com.mysql.jdbc.Driver",
"url",
outDir,
"com.kalos.gen",
"username",
"password"
),
streams.value.log
)
Seq(file(outDir + "/com/kalos/gen/Tables.scala"))
}.taskValue
)
现在生成的 Tables.scala
出现在 class 路径中,我的项目编译成功。如果对 sbt 有更多了解的人可以更全面地解释为什么会发生这种情况,我会很乐意接受它作为正确答案。