scala - Sbt:从根项目调用子项目的源代码
问题描述
所以我的项目结构如下所示:我的根项目包含设置、任务和配置。此外还有一个包含所有子项目的子项目文件夹。我在根项目上创建了一个任务,该任务依赖于子项目 X 中的一些代码。是否可以在该任务定义内从子项目 x 调用方法?
我的代码如下所示:
lazy val rootSettings: Seq[Setting[_]] = Seq (someRootTask := { //I need to call an object from a subproject here..})
我尝试使用反射 api 没有成功:
import scala.reflect.runtime.{universe => u }
lazy val docSettings: Seq[Setting[_]] = Seq(
rootTask := {
val subproject = baseDirectory.in(playApp).value.getAbsolutePath
val mirror = u.runtimeMirror(getClass.getClassLoader)
val clazz = mirror.staticModule(subproject+"/" +"controllers.pckg.obj" )
val cm = mirror.reflectModule(clazz)
val instanceMirror = mirror.reflect(cm.instance)
val methodName ="sayHi"
val methodSymbol = u.typeOf[instanceMirror.type].declaration(u.newTermName(methodName)).asMethod
val method = instanceMirror.reflectMethod(methodSymbol)
method.apply()
}
)
// still can't point to the object i want to call.
上面的代码会引发错误。它找不到对象,我知道它的路径,但我不能从根项目中将它作为 package.class 引用。
解决方案
如果我理解正确你的项目看起来像
root
project
build.properties
build.sbt
subproject1
src
main
scala
com.example.package1
App.scala
subproject2
src
main
scala
com.example.package2
build.sbt
在project/build.sbt
我可以写
Compile / unmanagedSourceDirectories += baseDirectory.value / ".." / "subproject1" / "src" / "main" / "scala"
假设subproject1/src/main/scala/com/example/package1/App.scala
是
package com.example.package1
object App {
def foo(): Unit = println("foo")
}
然后在根build.sbt
我可以打电话foo
name := "sbtdemo"
version := "0.1"
ThisBuild / scalaVersion := "2.13.4"
lazy val sampleUnitTask = taskKey[Unit]("A sample unit task.")
lazy val rootSettings: Seq[Setting[_]] = Seq(
sampleUnitTask := {
com.example.package1.App.foo()
}
)
lazy val root = project
.in(file("."))
.dependsOn(subproject1, subproject2)
.settings(rootSettings)
lazy val subproject1 = project
.in(file("subproject1"))
lazy val subproject2 = project
.in(file("subproject2"))
如果在 sbt shell 中运行root/sampleUnitTask
它会打印foo
.
我用sbt new playframework/play-scala-seed.g8
. 一切似乎都奏效了。我添加了project/build.sbt
和subproject1/src/main/scala/com/example/package1/App.scala
如上。然后使用以下根build.sbt
name := """playframeworkdemo"""
organization := "com.example"
version := "1.0-SNAPSHOT"
lazy val sampleUnitTask = taskKey[Unit]("A sample unit task.")
lazy val rootSettings: Seq[Setting[_]] = Seq(
sampleUnitTask := {
com.example.package1.App.foo()
}
)
lazy val root = (project in file(".")).enablePlugins(PlayScala)
.dependsOn(subproject1, subproject2)
.settings(rootSettings)
ThisBuild / scalaVersion := "2.13.3"
libraryDependencies += guice
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0" % Test
// Adds additional packages into Twirl
//TwirlKeys.templateImports += "com.example.controllers._"
// Adds additional packages into conf/routes
// play.sbt.routes.RoutesKeys.routesImport += "com.example.binders._"
lazy val subproject1 = project
.in(file("subproject1"))
lazy val subproject2 = project
.in(file("subproject2"))
root/sampleUnitTask
在 sbt shell prints 中执行foo
。
推荐阅读
- java - 在 Java android 的上下文菜单中实现类似的功能
- symfony - 为所有表单添加属性
- tensorflow.js - 创建带有时间戳数组的张量时,数字不正确
- javascript - 在 chrome 版本 85+ 中检测自定义协议处理程序
- discord.py - 使用不和谐机器人发送高优先级和低优先级消息
- c# - 在 Selenium 中附加到现有的 Chrome 页面
- reactjs - 将打字稿哈希图标题作为键和值反应在里面
- javascript - 如何防止垂直滚动条被推到宽内容的视野之外
- excel - 我无法通过从 Excel 中的单元格调用 vba 函数来获得正确的范围(使用 currentRegion)
- python - 如何使 Content-Encoding: deflate 可读?