"object is not a member of package" when importing dependency built from another project via slick codegen

3.9k views Asked by At

I have a multi project setup like this:

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
  )

The main class of kalosgen generates a model via slick-codegen and places is it in:

kalosgen/target/scala-2.13/src_managed/main 

in the package com.kalos.gen. It also compiles protobufs into scala classes at compile time but that package is in the classpath as expected.

I can then import those files from kalosgen into kalosrpc, intelliJ does not complain and has full access to the type information defined in those files. So I run kalosgen/compile and the packages are generated as I expect however when I follow that up with kalosrpc/compile I get:

object gen is not a member of package com.kalos

I've tried changing the name of the packages but it doesn't fix anything. Based on the information presented here my project configuration seems correct.

2

There are 2 answers

0
Robbie Milejczak On BEST ANSWER

The problem here was that I was generating the sources in scala code via the slick-codegen utility:

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
    )
  )
}

My guess is that you have to generate sources via SBT tasks to have them recognized by SBT as being valid sources (at least for the purposes of inter project dependencies), so I was able to translate the above code to a task that runs at compile time in 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
  )

Now the generated Tables.scala appears as expected in the class path and my project compiles. If someone with more knowledge of sbt could provide a more comprehensive explanation of why this happened I will gladly accept it as the proper answer.

1
Mario Galic On

Try executing show sourceManaged from sbt which should output the location of where generated files should end up, for example in my project it is at

.../myproject/target/scala-2.13/src_managed

It likely should be

kalosgen/target/scala-2.13/src_managed/main/com/kalos/gen

instead of

kalosgen/target/scala-2.13/main/com/kalos/gen

Also double check generated files have package statements at the top.