运行一个子项目主要class

Running a sub-project main class

我有一个 built.sbt 引用子项目的主要 class 作为它自己的主要 class:

lazy val akka = (project in file("."))
  .aggregate(api)
  .dependsOn(api)
  .enablePlugins(JavaAppPackaging)

lazy val api = project in file("api")

scalaVersion := "2.11.6"

// This is referencing API code 
mainClass in (Compile, run) := Some("maslow.akka.cluster.node.ClusterNode")

artifactName := { (sv: ScalaVersion, module: ModuleID, artifact: Artifact) =>
  s"""${artifact.name}.${artifact.extension}"""
}

name in Universal := name.value

packageName in Universal := name.value

但是,每次我 运行 sbt run 我都会收到以下错误:

> run
[info] Updating {file:/Users/mark/dev/Maslow-Akka/}api...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Updating {file:/Users/mark/dev/Maslow-Akka/}akka...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Running maslow.akka.cluster.node.ClusterNode
[error] (run-main-0) java.lang.ClassNotFoundException: maslow.akka.cluster.node.ClusterNode
java.lang.ClassNotFoundException: maslow.akka.cluster.node.ClusterNode
    at java.lang.ClassLoader.findClass(ClassLoader.java:530)

由于我一直在研究这个问题,所以我首先将项目从 akka 切换到 api,然后打开控制台。从那里,它找不到 maslow 包,即使它肯定存在。在那之后,我进入了 api 文件夹和 运行 sbt console 并且它访问了上述包就好了。在我这样做之后,akka 项目中的 sbt run 就可以工作了。为什么?

文件夹 api 通过 git read-tree 拉入。它应该没有什么特别之处。我正在使用 sbt 0.13.5

我认为在一个多项目中构建一条全局线,例如

mainClass in (Compile, run) := ...

将被吞下而不会产生任何后果,因为它不涉及任何项目。

大概是以下作品:

mainClass in (Compile, run) in ThisBuild := ...

或者您将其添加到根项目的设置中:

lazy val akka = (project in file("."))
  .aggregate(api)
  .dependsOn(api)
  .enablePlugins(JavaAppPackaging)
  .settings(
    mainClass in (Compile, run) := ...
  )

问题出在这一行:lazy val api = project in file("api")

来自docs

When defining a dependency on another project, you provide a ProjectReference. In the simplest case, this is a Project object. (Technically, there is an implicit conversion Project => ProjectReference) This indicates a dependency on a project within the same build.

这表示在同一构建 中存在依赖关系。相反,我需要的是使用 RootProject 因为 api 是外部构建:

It is possible to declare a dependency on a project in a directory separate from the current build, in a git repository, or in a project packaged into a jar and accessible via http/https. These are referred to as external builds and projects. You can reference the root project in an external build with RootProject:

为了解决这个问题,我将 build.sbt 中的项目声明删除到 project/Build.scala:

import sbt._

object MyBuild extends Build {
  lazy val akka = Project("akka", file(".")).aggregate(api).dependsOn(api)
  lazy val api = RootProject(file("api"))
}

明确地说,问题是我的 api 子项目是 ProjectRef 而不是 RootProject