2017-01-18 29 views
0

我有一個sbt autoplugin,當用戶運行一個任務時,我想用一個-javaagent分叉一個新的JVM。該任務應使用jamm來測量內存。sbt autoplugin:爲任務添加javaagent

object SbtMemory extends AutoPlugin { 
    object autoImport { 
     val agentTest = inputKey[Unit]("Run task with javaagent") 
    } 
    def makeAgentOptions(classpath: Classpath) : String = { 
      val jammJar = classpath.map(_.data).filter(_.toString.contains("jamm")).head 
      s"-javaagent:$jammJar" 
     } 
    override lazy val projectSettings = 
      Seq(
       agentTest := agentTask.value, 
       fork in agentTest := true, 
       javaOptions in agentTest += (dependencyClasspath in Test).map(makeAgentOptions).value 
      ) 

    lazy val agentTask = Def.task { 
     val o = new Array[Byte](1024*1024) 
     val mm = new MemoryMeter() 
     println("Size of new Array[Byte](1024*1024): " + mm.measureDeep(o)) 
    } 
} 

當我在命令行中運行sbt perf,我得到以下異常:

java.lang.IllegalStateException: Instrumentation is not set; Jamm must be set as -javaagent 

我也嘗試打印javaOptions和-javaagent選項沒有設置。

如何在插件中添加-javaagent javaOption以使用jamm運行任務?

謝謝!

回答

0

顯然,fork僅適用於runtest任務。我添加了自己的分叉代碼並將度量代碼移至單獨的類MemoryMeasure

val mainClass: String = "MemoryMeasure" 
val forkOptions = ForkOptions(
    bootJars = (fullClasspath in Test).value.files, 
    runJVMOptions = Seq(
     (dependencyClasspath in Test).map(makeAgentOptions).value 
    ) 
) 
val process = Fork.java.fork(forkOptions, mainClass +: arguments) 
def cancel() = { 
    process.destroy() 
    1 
} 
val exitCode = try process.exitValue() catch { case e: InterruptedException => cancel() }