2017-01-18 30 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() }