From 8516613ad2ffd5b29f2e611a0a9e9006c5613ea4 Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 22 Jun 2016 15:32:23 -0300 Subject: + kamon-autoweave: add support Attach on IBM J9 and closes #354 --- .../scala/kamon/autoweave/loader/AgentLoader.scala | 5 ++- .../autoweave/loader/AttachmentProviders.scala | 41 ++++++++++++++++------ kamon-core/src/main/scala/kamon/Kamon.scala | 1 + 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala b/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala index 2f26a39d..5f865cb3 100644 --- a/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala +++ b/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AgentLoader.scala @@ -99,10 +99,9 @@ object AgentLoader { AttachmentProviders.resolve() match { case Some(virtualMachine) ⇒ val virtualMachineInstance = virtualMachine.getDeclaredMethod("attach", classOf[String]).invoke(null, getPidFromRuntimeMBean) - virtualMachine.getDeclaredMethod("loadAgent", classOf[String], classOf[String]) - .invoke(virtualMachineInstance, generateAgentJar(agent, resources).getAbsolutePath, "") + virtualMachine.getDeclaredMethod("loadAgent", classOf[String], classOf[String]).invoke(virtualMachineInstance, generateAgentJar(agent, resources).getAbsolutePath, "") virtualMachine.getDeclaredMethod("detach").invoke(virtualMachineInstance) - case None ⇒ throw new RuntimeException(s"Error trying to use Attach API") with NoStackTrace + case None ⇒ throw new IllegalStateException("Cannot read the virtual machine type...") with NoStackTrace } } diff --git a/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AttachmentProviders.scala b/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AttachmentProviders.scala index ebb112e4..fff23735 100644 --- a/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AttachmentProviders.scala +++ b/kamon-autoweave/src/main/scala/kamon/autoweave/loader/AttachmentProviders.scala @@ -17,13 +17,20 @@ package kamon.autoweave.loader import java.io.File import java.net.{ URL, URLClassLoader } -import java.security.{ PrivilegedAction, AccessController } +import java.security.{ AccessController, PrivilegedAction } -object AttachmentProviders extends { +import scala.util.control.NonFatal +import scala.util.{ Failure, Success, Try } - val VirtualMachineTyeName = "com.sun.tools.attach.VirtualMachine" +object AttachmentProviders { sealed trait AttachmentProvider { + def resolve(): Option[Class[_]] + } + + trait DefaultAttachmentProvider extends AttachmentProvider { + val VirtualMachineTyeName = "com.sun.tools.attach.VirtualMachine" + def toolsJarPath: String /** @@ -34,17 +41,31 @@ object AttachmentProviders extends { */ def resolve(): Option[Class[_]] = { val toolsJar = new File(System.getProperty("java.home").replace('\\', '/') + "/../" + toolsJarPath) - if (toolsJar.isFile && toolsJar.canRead) - Some(AccessController.doPrivileged(new ClassLoaderCreationAction(toolsJar)).loadClass(VirtualMachineTyeName)) - else None + if (toolsJar.isFile && toolsJar.canRead) { + Try(AccessController.doPrivileged(new ClassLoaderCreationAction(toolsJar)).loadClass(VirtualMachineTyeName)) match { + case Success(vm) ⇒ Some(vm) + case Failure(NonFatal(_)) ⇒ None + } + } else None } } - case object JVM extends AttachmentProvider { val toolsJarPath = "../lib/tools.jar" } - case object JDK extends AttachmentProvider { val toolsJarPath = "lib/tools.jar" } - case object MAC extends AttachmentProvider { val toolsJarPath = "../Classes/classes.jar" } + case object JVM extends DefaultAttachmentProvider { val toolsJarPath = "../lib/tools.jar" } + case object JDK extends DefaultAttachmentProvider { val toolsJarPath = "lib/tools.jar" } + case object MAC extends DefaultAttachmentProvider { val toolsJarPath = "../Classes/classes.jar" } + case object IBM extends AttachmentProvider { + + val IBMVirtualMachineTyeName = "com.ibm.tools.attach.VirtualMachine" + + override def resolve(): Option[Class[_]] = { + Try(ClassLoader.getSystemClassLoader.loadClass(IBMVirtualMachineTyeName)) match { + case Success(vm) ⇒ Some(vm) + case Failure(NonFatal(_)) ⇒ None + } + } + } - private val providers = Seq(JVM, JDK, MAC) + private val providers = Seq(JVM, JDK, MAC, IBM) private final class ClassLoaderCreationAction(toolsJar: File) extends PrivilegedAction[ClassLoader] { override def run(): ClassLoader = new URLClassLoader(Array[URL](toolsJar.toURI.toURL), null) diff --git a/kamon-core/src/main/scala/kamon/Kamon.scala b/kamon-core/src/main/scala/kamon/Kamon.scala index 3f49845f..03b0de03 100644 --- a/kamon-core/src/main/scala/kamon/Kamon.scala +++ b/kamon-core/src/main/scala/kamon/Kamon.scala @@ -70,6 +70,7 @@ object Kamon { val color = (msg: String) ⇒ s"""\u001B[32m${msg}\u001B[0m""" log.info(color("Kamon-autoweave has been successfully loaded.")) log.info(color("The AspectJ loadtime weaving agent is now attached to the JVM (you don't need to use -javaagent).")) + log.info(color("This offers extra flexibility but obviously any classes loaded before attachment will not be woven.")) case Failure(NonFatal(reason)) ⇒ log.debug(s"Kamon-autoweave failed to load. Reason: ${reason.getMessage}.") } } -- cgit v1.2.3