This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new 0ae2228  Make auto instrumentation works when Module definition 
existing (#3199)
0ae2228 is described below

commit 0ae2228a86713d89ce9f6bf849fb9a96303d0cfa
Author: 吴晟 Wu Sheng <[email protected]>
AuthorDate: Thu Aug 15 07:46:28 2019 +0800

    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 
https://github.com/raphw/byte-buddy/commit/b60971156403ed8fba6124b8e424f0749917594a.
    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
---
 apm-sniffer/apm-agent-core/pom.xml                 |  15 +--
 .../apm/agent/core/logging/core/FileWriter.java    | 125 +++++++++++----------
 .../agent/core/plugin/ByteBuddyCoreClasses.java    |  38 +++++++
 .../plugin/bootstrap/BootstrapInstrumentBoost.java |  59 ++++------
 .../core/plugin/jdk9module/JDK9ModuleExporter.java |  89 +++++++++++++++
 apm-sniffer/apm-agent/pom.xml                      |   1 -
 .../skywalking/apm/agent/SkyWalkingAgent.java      |  11 +-
 7 files changed, 223 insertions(+), 115 deletions(-)

diff --git a/apm-sniffer/apm-agent-core/pom.xml 
b/apm-sniffer/apm-agent-core/pom.xml
index 566500e..d57fdde 100644
--- a/apm-sniffer/apm-agent-core/pom.xml
+++ b/apm-sniffer/apm-agent-core/pom.xml
@@ -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>
@@ -73,11 +69,6 @@
             <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>
             <version>${grpc.version}</version>
@@ -181,10 +172,6 @@
                             </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>
                                 </relocation>
diff --git 
a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/logging/core/FileWriter.java
 
b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/logging/core/FileWriter.java
index a885b0d..1b0c6ef 100644
--- 
a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/logging/core/FileWriter.java
+++ 
b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/logging/core/FileWriter.java
@@ -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();
         }
     }
 }
diff --git 
a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/ByteBuddyCoreClasses.java
 
b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/ByteBuddyCoreClasses.java
new file mode 100644
index 0000000..ee73248
--- /dev/null
+++ 
b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/ByteBuddyCoreClasses.java
@@ -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",
+    };
+}
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 00aa7f6..ebb4035 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
@@ -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);
+        }
 
         /**
-         * Inject the classes into bootstrap class loader by using Unsafe 
Strategy.
-         * ByteBuddy adapts the sun.misc.Unsafe and jdk.internal.misc.Unsafe 
automatically.
+         * Prepare to open edge of necessary classes.
          */
-        ClassInjector.UsingUnsafe.ofBootLoader().injectRaw(classesTypeMap);
-        agentBuilder = agentBuilder.enableUnsafeBootstrapInjection();
+        for (String generatedClass : classesTypeMap.keySet()) {
+            edgeClasses.add(generatedClass);
+        }
 
         /**
-         * 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.
+         * Inject the classes into bootstrap class loader by using Unsafe 
Strategy.
+         * ByteBuddy adapts the sun.misc.Unsafe and jdk.internal.misc.Unsafe 
automatically.
          */
-        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.UsingUnsafe.Factory factory = 
ClassInjector.UsingUnsafe.Factory.resolve(instrumentation);
+        factory.make(null, null).injectRaw(classesTypeMap);
+        agentBuilder = agentBuilder.with(new 
AgentBuilder.InjectionStrategy.UsingUnsafe.OfFactory(factory));
+
 
         return agentBuilder;
     }
diff --git 
a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/jdk9module/JDK9ModuleExporter.java
 
b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/jdk9module/JDK9ModuleExporter.java
new file mode 100644
index 0000000..92943af
--- /dev/null
+++ 
b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/jdk9module/JDK9ModuleExporter.java
@@ -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);
+            }
+        }
+    }
+}
diff --git a/apm-sniffer/apm-agent/pom.xml b/apm-sniffer/apm-agent/pom.xml
index 8b1ca51..3ee9334 100644
--- a/apm-sniffer/apm-agent/pom.xml
+++ b/apm-sniffer/apm-agent/pom.xml
@@ -76,7 +76,6 @@
                             </transformers>
                             <artifactSet>
                                 <excludes>
-                                    <exclude>com.lmax:*</exclude>
                                     <exclude>*:gson</exclude>
                                     <exclude>io.grpc:*</exclude>
                                     <exclude>io.netty:*</exclude>
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 b880d2b..b86ba54 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
@@ -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))

Reply via email to