From b091c0ae48ae49f4784b3c176b95da9673dbbba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=99=9F=20Wu=20Sheng?= Date: Wed, 31 Jul 2019 15:30:11 +0800 Subject: [PATCH] Make bootstrap instrumentation available in JDK9 - 11 (#3194) * Make JDK9-11 available for bootstrap instrumentation * Remove temp folder of old bootstrap instrumentation requirement. --- .../bootstrap/BootstrapInstrumentBoost.java | 48 +++++++++++++------ apm-sniffer/apm-agent/pom.xml | 1 - .../skywalking/apm/agent/SkyWalkingAgent.java | 2 +- .../setup/service-agent/java-agent/README.md | 4 +- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/BootstrapInstrumentBoost.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/BootstrapInstrumentBoost.java index 6e12d9d96..90753a5e1 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/BootstrapInstrumentBoost.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/bootstrap/BootstrapInstrumentBoost.java @@ -19,7 +19,6 @@ package org.apache.skywalking.apm.agent.core.plugin.bootstrap; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.lang.instrument.Instrumentation; @@ -33,8 +32,6 @@ import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.dynamic.DynamicType; import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.pool.TypePool; -import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException; -import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath; import org.apache.skywalking.apm.agent.core.logging.api.ILog; import org.apache.skywalking.apm.agent.core.logging.api.LogManager; import org.apache.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; @@ -82,7 +79,6 @@ public class BootstrapInstrumentBoost { public static AgentBuilder inject(PluginFinder pluginFinder, AgentBuilder agentBuilder, Instrumentation instrumentation) throws PluginException { - Map classesTypeMap = new HashMap(); if (!prepareJREInstrumentation(pluginFinder, classesTypeMap)) { @@ -93,17 +89,36 @@ public class BootstrapInstrumentBoost { loadHighPriorityClass(classesTypeMap, highPriorityClass); } - File temp = null; - try { - temp = new File(AgentPackagePath.getPath(), "bootstrapJarTmp"); - } catch (AgentPackageNotFoundException e) { - logger.error(e, "Bootstrap plugin exist, but SkyWalking agent can't create bootstrapJarTmp folder. Shutting down."); - throw new UnsupportedOperationException("Bootstrap plugin exist, but SkyWalking agent can't create bootstrapJarTmp folder. Shutting down.", e); + /** + * This strategy is no longer available after Java 11. + * Inject the classes into bootstrap class loader. + */ + ClassInjector.UsingUnsafe.ofBootLoader().injectRaw(classesTypeMap); + agentBuilder = agentBuilder.enableUnsafeBootstrapInjection(); + + /** + * Assures that all modules of the supplied types are read by the module of any instrumented type. + * JDK Module system was introduced since JDK9. + * + * The following codes work only JDK Module system exist. + */ + for (String highPriorityClass : HIGH_PRIORITY_CLASSES) { + try { + agentBuilder = agentBuilder.assureReadEdgeTo(instrumentation, Class.forName(highPriorityClass)); + } catch (ClassNotFoundException e) { + logger.error(e, "Fail to open the high priority class " + highPriorityClass + " to public access in JDK9+"); + throw new UnsupportedOperationException("Fail to open the high priority class " + highPriorityClass + " to public access in JDK9+", e); + } + } + for (String generatedClass : classesTypeMap.keySet()) { + try { + agentBuilder = agentBuilder.assureReadEdgeTo(instrumentation, Class.forName(generatedClass)); + } catch (ClassNotFoundException e) { + logger.error(e, "Fail to open the high generated class " + generatedClass + " to public access in JDK9+"); + throw new UnsupportedOperationException("Fail to open the high generated class " + generatedClass + " to public access in JDK9+", e); + } } - ClassInjector.UsingInstrumentation.of(temp, ClassInjector.UsingInstrumentation.Target.BOOTSTRAP, instrumentation).injectRaw(classesTypeMap); - - agentBuilder = agentBuilder.enableBootstrapInjection(instrumentation, temp); return agentBuilder; } @@ -206,12 +221,17 @@ public class BootstrapInstrumentBoost { * @param loadedTypeMap hosts all injected class * @param className to load */ - private static void loadHighPriorityClass(Map loadedTypeMap, String className) { + private static void loadHighPriorityClass(Map loadedTypeMap, + String className) throws PluginException { byte[] enhancedInstanceClassFile; try { String classResourceName = className.replaceAll("\\.", "/") + ".class"; InputStream resourceAsStream = AgentClassLoader.getDefault().getResourceAsStream(classResourceName); + if (resourceAsStream == null) { + throw new PluginException("High priority class " + className + " not found."); + } + ByteArrayOutputStream os = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; diff --git a/apm-sniffer/apm-agent/pom.xml b/apm-sniffer/apm-agent/pom.xml index 897ea6d26..da9db7f10 100644 --- a/apm-sniffer/apm-agent/pom.xml +++ b/apm-sniffer/apm-agent/pom.xml @@ -136,7 +136,6 @@ - diff --git a/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java b/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java index 8f5b439dd..b880d2bbe 100644 --- a/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java +++ b/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java @@ -100,7 +100,7 @@ public class SkyWalkingAgent { try { agentBuilder = BootstrapInstrumentBoost.inject(pluginFinder, agentBuilder, instrumentation); } catch (Exception e) { - logger.error(e, "SkyWalking agent inject boostrap instrumentation failure. Shutting down."); + logger.error(e, "SkyWalking agent inject bootstrap instrumentation failure. Shutting down."); return; } diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index e283708f1..3b5838b34 100644 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -1,4 +1,5 @@ # Setup java agent +1. Agent is available for JDK 1.6 - 11. 1. Find `agent` folder in SkyWalking release package 1. Set `agent.service_name` in `config/agent.config`. Could be any String in English. 1. Set `collector.backend_service` in `config/agent.config`. Default point to `127.0.0.1:11800`, only works for local backend. @@ -19,7 +20,6 @@ The agent release dist is included in Apache [official release](http://skywalkin apm-feign-default-http-9.x.jar apm-httpClient-4.x-plugin.jar ..... - +--- bootstrapJarTmp +--- logs skywalking-agent.jar ``` @@ -108,8 +108,6 @@ Now, we have the following known optional plugins. ## Bootstrap class plugins All bootstrap plugins are optional, due to unexpected risk. Bootstrap plugins are provided in `bootstrap-plugins` folder. -**Make sure `bootstrapJarTmp` writable by agent, which is required by bootstrap instrumentation. New temp jar files will be generated there.**. - ## Advanced Features * Set the settings through system properties for config file override. Read [setting override](Setting-override.md). * Use gRPC TLS to link backend. See [open TLS](TLS.md)