Make auto instrumentation works when Module definition existing (#3199)
* Refactor open edge.
* Make refactor works.
* Revert log back.
* Remove unnecessary codes.
* Open edge for all internal binding interceptors.
* Add document about JDK 9+ module.
* Change bytebuddy to 1.10.1(unreleased)
* Change document
* 1. Adopt the latest bytebudy changes(snapshot only), commit b609711564.
2. Remove disruptor by ArrayBlockingQueue, because Disruptor can't work in both JDK 8(1) and 9-12, if we don't add `--add-modules jdk.unsupported`
3. Doc update.
* Update README.md
This commit is contained in:
parent
19b37cab6f
commit
0ae2228a86
|
|
@ -36,15 +36,11 @@
|
|||
<jetty.version>9.4.2.v20170220</jetty.version>
|
||||
<grpc.version>1.14.0</grpc.version>
|
||||
<guava.version>20.0</guava.version>
|
||||
<bytebuddy.version>1.9.16</bytebuddy.version>
|
||||
<disruptor.version>3.3.6</disruptor.version>
|
||||
<bytebuddy.version>1.10.1</bytebuddy.version>
|
||||
<wiremock.version>2.6.0</wiremock.version>
|
||||
<netty-tcnative-boringssl-static.version>2.0.7.Final</netty-tcnative-boringssl-static.version>
|
||||
<os-maven-plugin.version>1.4.1.Final</os-maven-plugin.version>
|
||||
<shade.package>org.apache.skywalking.apm.dependencies</shade.package>
|
||||
<shade.com.lmax.disruptor.source>com.lmax.disruptor</shade.com.lmax.disruptor.source>
|
||||
<shade.com.lmax.disruptor.target>${shade.package}.${shade.com.lmax.disruptor.source}
|
||||
</shade.com.lmax.disruptor.target>
|
||||
<shade.com.google.source>com.google</shade.com.google.source>
|
||||
<shade.com.google.target>${shade.package}.${shade.com.google.source}</shade.com.google.target>
|
||||
<shade.io.grpc.source>io.grpc</shade.io.grpc.source>
|
||||
|
|
@ -72,11 +68,6 @@
|
|||
<artifactId>byte-buddy</artifactId>
|
||||
<version>${bytebuddy.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lmax</groupId>
|
||||
<artifactId>disruptor</artifactId>
|
||||
<version>${disruptor.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-netty</artifactId>
|
||||
|
|
@ -180,10 +171,6 @@
|
|||
</excludes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>${shade.com.lmax.disruptor.source}</pattern>
|
||||
<shadedPattern>${shade.com.lmax.disruptor.target}</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>${shade.com.google.source}</pattern>
|
||||
<shadedPattern>${shade.com.google.target}</shadedPattern>
|
||||
|
|
|
|||
|
|
@ -19,35 +19,33 @@
|
|||
|
||||
package org.apache.skywalking.apm.agent.core.logging.core;
|
||||
|
||||
import com.lmax.disruptor.EventFactory;
|
||||
import com.lmax.disruptor.EventHandler;
|
||||
import com.lmax.disruptor.RingBuffer;
|
||||
import com.lmax.disruptor.dsl.Disruptor;
|
||||
import com.lmax.disruptor.util.DaemonThreadFactory;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.apache.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Constants;
|
||||
import org.apache.skywalking.apm.util.RunnableWithExceptionProtection;
|
||||
|
||||
/**
|
||||
* The <code>FileWriter</code> support async file output, by using a queue as buffer.
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class FileWriter implements IWriter, EventHandler<LogMessageHolder> {
|
||||
public class FileWriter implements IWriter {
|
||||
private static FileWriter INSTANCE;
|
||||
private static final Object CREATE_LOCK = new Object();
|
||||
private Disruptor<LogMessageHolder> disruptor;
|
||||
private RingBuffer<LogMessageHolder> buffer;
|
||||
private FileOutputStream fileOutputStream;
|
||||
private volatile boolean started = false;
|
||||
private ArrayBlockingQueue logBuffer;
|
||||
private volatile int fileSize;
|
||||
private volatile int lineNum;
|
||||
|
||||
public static FileWriter get() {
|
||||
if (INSTANCE == null) {
|
||||
|
|
@ -61,44 +59,45 @@ public class FileWriter implements IWriter, EventHandler<LogMessageHolder> {
|
|||
}
|
||||
|
||||
private FileWriter() {
|
||||
disruptor = new Disruptor<LogMessageHolder>(new EventFactory<LogMessageHolder>() {
|
||||
@Override
|
||||
public LogMessageHolder newInstance() {
|
||||
return new LogMessageHolder();
|
||||
logBuffer = new ArrayBlockingQueue(1024);
|
||||
final ArrayList<String> outputLogs = new ArrayList<String>(200);
|
||||
Executors
|
||||
.newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("LogFileWriter"))
|
||||
.scheduleAtFixedRate(new RunnableWithExceptionProtection(new Runnable() {
|
||||
@Override public void run() {
|
||||
logBuffer.drainTo(outputLogs);
|
||||
for (String log : outputLogs) {
|
||||
writeToFile(log + Constants.LINE_SEPARATOR);
|
||||
}
|
||||
try {
|
||||
fileOutputStream.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}, new RunnableWithExceptionProtection.CallbackWhenException() {
|
||||
@Override public void handle(Throwable t) {
|
||||
}
|
||||
}
|
||||
}, 1024, DaemonThreadFactory.INSTANCE);
|
||||
disruptor.handleEventsWith(this);
|
||||
buffer = disruptor.getRingBuffer();
|
||||
lineNum = 0;
|
||||
disruptor.start();
|
||||
), 0, 1, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(LogMessageHolder event, long sequence, boolean endOfBatch) throws Exception {
|
||||
if (hasWriteStream()) {
|
||||
/**
|
||||
* @param message to be written into the file.
|
||||
*/
|
||||
private void writeToFile(String message) {
|
||||
if (prepareWriteStream()) {
|
||||
try {
|
||||
lineNum++;
|
||||
write(event.getMessage() + Constants.LINE_SEPARATOR, endOfBatch);
|
||||
fileOutputStream.write(message.getBytes());
|
||||
fileSize += message.length();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
event.setMessage(null);
|
||||
switchFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void write(String message, boolean forceFlush) {
|
||||
try {
|
||||
fileOutputStream.write(message.getBytes());
|
||||
fileSize += message.length();
|
||||
if (forceFlush || lineNum % 20 == 0) {
|
||||
fileOutputStream.flush();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
switchFile();
|
||||
}
|
||||
}
|
||||
|
||||
private void switchFile() {
|
||||
if (fileSize > Config.Logging.MAX_FILE_SIZE) {
|
||||
forceExecute(new Callable() {
|
||||
|
|
@ -128,7 +127,6 @@ public class FileWriter implements IWriter, EventHandler<LogMessageHolder> {
|
|||
@Override
|
||||
public Object call() throws Exception {
|
||||
fileOutputStream = null;
|
||||
started = false;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
|
@ -143,37 +141,40 @@ public class FileWriter implements IWriter, EventHandler<LogMessageHolder> {
|
|||
}
|
||||
}
|
||||
|
||||
private boolean hasWriteStream() {
|
||||
/**
|
||||
* @return true if stream is prepared ready.
|
||||
*/
|
||||
private boolean prepareWriteStream() {
|
||||
if (fileOutputStream != null) {
|
||||
return true;
|
||||
}
|
||||
if (!started) {
|
||||
File logFilePath = new File(Config.Logging.DIR);
|
||||
if (!logFilePath.exists()) {
|
||||
logFilePath.mkdirs();
|
||||
} else if (!logFilePath.isDirectory()) {
|
||||
System.err.println("Log dir(" + Config.Logging.DIR + ") is not a directory.");
|
||||
}
|
||||
try {
|
||||
fileOutputStream = new FileOutputStream(new File(logFilePath, Config.Logging.FILE_NAME), true);
|
||||
fileSize = Long.valueOf(new File(logFilePath, Config.Logging.FILE_NAME).length()).intValue();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
started = true;
|
||||
File logFilePath = new File(Config.Logging.DIR);
|
||||
if (!logFilePath.exists()) {
|
||||
logFilePath.mkdirs();
|
||||
} else if (!logFilePath.isDirectory()) {
|
||||
System.err.println("Log dir(" + Config.Logging.DIR + ") is not a directory.");
|
||||
}
|
||||
try {
|
||||
fileOutputStream = new FileOutputStream(new File(logFilePath, Config.Logging.FILE_NAME), true);
|
||||
fileSize = Long.valueOf(new File(logFilePath, Config.Logging.FILE_NAME).length()).intValue();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return fileOutputStream != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(String message) {
|
||||
long next = buffer.next();
|
||||
/**
|
||||
* Write log to the queue.
|
||||
* W/ performance trade off, set 2ms timeout for the log OP.
|
||||
*
|
||||
* @param message to log
|
||||
*/
|
||||
@Override public void write(String message) {
|
||||
try {
|
||||
LogMessageHolder messageHolder = buffer.get(next);
|
||||
messageHolder.setMessage(message);
|
||||
} finally {
|
||||
buffer.publish(next);
|
||||
logBuffer.offer(message, 2, TimeUnit.MILLISECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.agent.core.plugin;
|
||||
|
||||
/**
|
||||
* All ByteBuddy core classes required to expose, including open edge for JDK 9+ module, or Bootstrap instrumentation.
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class ByteBuddyCoreClasses {
|
||||
private static final String SHADE_PACKAGE = "org.apache.skywalking.apm.dependencies.";
|
||||
|
||||
public static final String[] CLASSES = {
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.RuntimeType",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.This",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.AllArguments",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.AllArguments$Assignment",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.SuperCall",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.Origin",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.Morph",
|
||||
};
|
||||
}
|
||||
|
|
@ -35,12 +35,14 @@ import net.bytebuddy.pool.TypePool;
|
|||
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;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.ByteBuddyCoreClasses;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.InstrumentDebuggingClass;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.PluginException;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.PluginFinder;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.jdk9module.JDK9ModuleExporter;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.loader.AgentClassLoader;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
|
|
@ -53,32 +55,26 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
|||
*/
|
||||
public class BootstrapInstrumentBoost {
|
||||
private static final ILog logger = LogManager.getLogger(BootstrapInstrumentBoost.class);
|
||||
private static final String SHADE_PACKAGE = "org.apache.skywalking.apm.dependencies.";
|
||||
|
||||
private static final String[] HIGH_PRIORITY_CLASSES = {
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.BootstrapInterRuntimeAssist",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.bootstrap.IBootstrapLog",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.RuntimeType",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.This",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.AllArguments",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.AllArguments$Assignment",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.SuperCall",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.Origin",
|
||||
SHADE_PACKAGE + "net.bytebuddy.implementation.bind.annotation.Morph"
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult"
|
||||
};
|
||||
|
||||
private static String INSTANCE_METHOD_DELEGATE_TEMPLATE = "org.apache.skywalking.apm.agent.core.plugin.bootstrap.template.InstanceMethodInterTemplate";
|
||||
private static String INSTANCE_METHOD_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE = "org.apache.skywalking.apm.agent.core.plugin.bootstrap.template.InstanceMethodInterWithOverrideArgsTemplate";
|
||||
private static String CONSTRUCTOR_DELEGATE_TEMPLATE = "org.apache.skywalking.apm.agent.core.plugin.bootstrap.template.ConstructorInterTemplate";
|
||||
private static String STATIC_METHOD_DELEGATE_TEMPLATE = "org.apache.skywalking.apm.agent.core.plugin.bootstrap.template.StaticMethodInterTemplate";
|
||||
private static String STATIC_METHOD_WITH_OVERRIDE_ARGS_DELEGATE_TEMPLATE = "org.apache.skywalking.apm.agent.core.plugin.bootstrap.template.StaticMethodInterWithOverrideArgsTemplate";
|
||||
|
||||
public static AgentBuilder inject(PluginFinder pluginFinder, AgentBuilder agentBuilder,
|
||||
Instrumentation instrumentation) throws PluginException {
|
||||
public static AgentBuilder inject(PluginFinder pluginFinder, Instrumentation instrumentation, AgentBuilder agentBuilder,
|
||||
JDK9ModuleExporter.EdgeClasses edgeClasses) throws PluginException {
|
||||
Map<String, byte[]> classesTypeMap = new HashMap<String, byte[]>();
|
||||
|
||||
if (!prepareJREInstrumentation(pluginFinder, classesTypeMap)) {
|
||||
|
|
@ -88,36 +84,25 @@ public class BootstrapInstrumentBoost {
|
|||
for (String highPriorityClass : HIGH_PRIORITY_CLASSES) {
|
||||
loadHighPriorityClass(classesTypeMap, highPriorityClass);
|
||||
}
|
||||
for (String highPriorityClass : ByteBuddyCoreClasses.CLASSES) {
|
||||
loadHighPriorityClass(classesTypeMap, highPriorityClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare to open edge of necessary classes.
|
||||
*/
|
||||
for (String generatedClass : classesTypeMap.keySet()) {
|
||||
edgeClasses.add(generatedClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject the classes into bootstrap class loader by using Unsafe Strategy.
|
||||
* ByteBuddy adapts the sun.misc.Unsafe and jdk.internal.misc.Unsafe automatically.
|
||||
*/
|
||||
ClassInjector.UsingUnsafe.ofBootLoader().injectRaw(classesTypeMap);
|
||||
agentBuilder = agentBuilder.enableUnsafeBootstrapInjection();
|
||||
ClassInjector.UsingUnsafe.Factory factory = ClassInjector.UsingUnsafe.Factory.resolve(instrumentation);
|
||||
factory.make(null, null).injectRaw(classesTypeMap);
|
||||
agentBuilder = agentBuilder.with(new AgentBuilder.InjectionStrategy.UsingUnsafe.OfFactory(factory));
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
return agentBuilder;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.agent.core.plugin.jdk9module;
|
||||
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.bytebuddy.agent.builder.AgentBuilder;
|
||||
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.ByteBuddyCoreClasses;
|
||||
|
||||
/**
|
||||
* Since JDK 9, module concept has been introduced. By supporting that, agent core needs to open the
|
||||
*
|
||||
* @author wusheng
|
||||
*/
|
||||
public class JDK9ModuleExporter {
|
||||
private static final ILog logger = LogManager.getLogger(JDK9ModuleExporter.class);
|
||||
|
||||
private static final String[] HIGH_PRIORITY_CLASSES = {
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.OverrideCallable",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ConstructorInter",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInterWithOverrideArgs",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsInter",
|
||||
"org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsInterWithOverrideArgs",
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public static AgentBuilder openReadEdge(Instrumentation instrumentation, AgentBuilder agentBuilder,
|
||||
EdgeClasses classes) {
|
||||
for (String className : classes.classes) {
|
||||
try {
|
||||
agentBuilder = agentBuilder.assureReadEdgeFromAndTo(instrumentation, Class.forName(className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new UnsupportedOperationException("Fail to open read edge for class " + className + " to public access in JDK9+", e);
|
||||
}
|
||||
}
|
||||
for (String className : HIGH_PRIORITY_CLASSES) {
|
||||
try {
|
||||
agentBuilder = agentBuilder.assureReadEdgeFromAndTo(instrumentation, Class.forName(className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new UnsupportedOperationException("Fail to open read edge for class " + className + " to public access in JDK9+", e);
|
||||
}
|
||||
}
|
||||
|
||||
return agentBuilder;
|
||||
}
|
||||
|
||||
public static class EdgeClasses {
|
||||
private List<String> classes = new ArrayList<String>();
|
||||
|
||||
public EdgeClasses() {
|
||||
for (String className : ByteBuddyCoreClasses.CLASSES) {
|
||||
add(className);
|
||||
}
|
||||
}
|
||||
|
||||
public void add(String className) {
|
||||
if (!classes.contains(className)) {
|
||||
classes.add(className);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -76,7 +76,6 @@
|
|||
</transformers>
|
||||
<artifactSet>
|
||||
<excludes>
|
||||
<exclude>com.lmax:*</exclude>
|
||||
<exclude>*:gson</exclude>
|
||||
<exclude>io.grpc:*</exclude>
|
||||
<exclude>io.netty:*</exclude>
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import org.apache.skywalking.apm.agent.core.plugin.PluginBootstrap;
|
|||
import org.apache.skywalking.apm.agent.core.plugin.PluginException;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.PluginFinder;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.bootstrap.BootstrapInstrumentBoost;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.jdk9module.JDK9ModuleExporter;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameContains;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
|
|
@ -97,13 +98,21 @@ public class SkyWalkingAgent {
|
|||
.or(allSkyWalkingAgentExcludeToolkit())
|
||||
.or(ElementMatchers.<TypeDescription>isSynthetic()));
|
||||
|
||||
JDK9ModuleExporter.EdgeClasses edgeClasses = new JDK9ModuleExporter.EdgeClasses();
|
||||
try {
|
||||
agentBuilder = BootstrapInstrumentBoost.inject(pluginFinder, agentBuilder, instrumentation);
|
||||
agentBuilder = BootstrapInstrumentBoost.inject(pluginFinder, instrumentation, agentBuilder, edgeClasses);
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "SkyWalking agent inject bootstrap instrumentation failure. Shutting down.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
agentBuilder = JDK9ModuleExporter.openReadEdge(instrumentation, agentBuilder, edgeClasses);
|
||||
} catch (Exception e) {
|
||||
logger.error(e, "SkyWalking agent open read edge in JDK 9+ failure. Shutting down.");
|
||||
return;
|
||||
}
|
||||
|
||||
agentBuilder
|
||||
.type(pluginFinder.buildMatch())
|
||||
.transform(new Transformer(pluginFinder))
|
||||
|
|
|
|||
Loading…
Reference in New Issue