我有一个SBT插件,在这个插件中我想实例化作为编译步骤的一部分编译的类。
基本上,想想我的插件是这样做的:
classOf[com.skamuel.Dummy].newInstance
其中Dummy是由构建编译的类。
但是当我尝试这个时,我得到的课程没有找到异常。我可以在执行编译任务后在控制台中执行上面的代码,而不是作为插件的一部分。
那么,为了让上述功能发挥作用,我需要做什么类路径魔术?
答案 0 :(得分:2)
您的插件可以使用已添加它的已编译项目的运行时类路径,但它不能在编译时使用它。这是合乎逻辑的我猜,你的插件在不知道你的项目的情况下存在。
鉴于你可以像这样使用上面提到的类:
import sbt._
import Keys._
import classpath._
object MyPlugin extends Plugin {
val createClass = taskKey[Unit]("Creates new instance of a class")
lazy val myPluginSettings = inConfig(Compile)(Seq(
createClass := {
// we need to make sure the class we want to use is compiled
val analysis = (compile in Compile).value
// create custom class loader from the output of compile plus other deps
val classpath = (fullClasspath in Compile).value.map(_.data)
val loader = ClasspathUtilities.makeLoader(classpath, scalaInstance.value)
val myClass = Class.forName("com.stackoverflow.lpiepiora.MyClass", true, loader).newInstance
println(myClass.asInstanceOf[{def helloWorld(): String}].helloWorld())
}
))
}
问题是你不能对这个类做很多事情,因为插件不能直接将它强制转换为类型 - 它不知道它。
我正在使用结构类型作为示例,因为我将我的类定义为
package com.stackoverflow.lpiepiora
class MyClass {
def helloWorld(): String = "Hello World"
}
您还可以查看my GitHub repository
中完整,有效的示例