Repository: pinpoint-apm/pinpoint
Issue: com.navercorp.pinpoint.bootstrap.instrument.InstrumentException: Failed to add getter: com.navercorp.pinpoint.plugin.okhttp.v2.ConnectionGetter

**What version of pinpoint are you using?**
v1.7.3

**Describe your problem**
I have one java application which can not post interaction data from pp agent to pp collector.
I can see the agent was registered successfully in the application list from pp web, but there is no any line which connects to other apps.
From the log, i can see the following.

I just mask some of the package name, sorry.
BTW: I tried to disable okhttp from pinpoint.config, "profiler.okhttp.enable=false", there is no exception but still no change to this application in the pp web.
all the others java app work very well, only except this java app, I assume this is something different in this special app which causes this issue, but need your help for thoubleshooting.
thanks a lot.

-------------------
2018-09-30 17:14:41 [ERROR](c.n.p.p.BaseClassFileTransformer   ) Transformer:com.navercorp.pinpoint.profiler.plugin.MatchableClassFileTransformerGuardDelegate threw an exception. cl:org.springframework.boot.loader.LaunchedURLClassLoader@6d366c9b ctxCl:org.springframework.boot.loader.LaunchedURLClassLoader@6d366c9b agentCl:com.navercorp.pinpoint.bootstrap.classloader.ParallelCapablePinpointURLClassLoader@2c8d66b2 Cause:com.navercorp.pinpoint.bootstrap.instrument.InstrumentException: Failed to add getter: com.navercorp.pinpoint.plugin.okhttp.v2.ConnectionGetter
com.navercorp.pinpoint.exception.PinpointException: com.navercorp.pinpoint.bootstrap.instrument.InstrumentException: Failed to add getter: com.navercorp.pinpoint.plugin.okhttp.v2.ConnectionGetter
        at com.navercorp.pinpoint.profiler.plugin.MatchableClassFileTransformerGuardDelegate.transform(MatchableClassFileTransformerGuardDelegate.java:77)
        at com.navercorp.pinpoint.profiler.BaseClassFileTransformer.transform(BaseClassFileTransformer.java:56)
        at com.navercorp.pinpoint.profiler.MatchableClassFileTransformerDispatcher.transform(MatchableClassFileTransformerDispatcher.java:131)
        at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
        at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:93)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at com.squareup.okhttp.Call.getResponse(Call.java:275)
        at com.squareup.okhttp.Call$ApplicationInterceptorChain.proceed(Call.java:243)
        at com.squareup.okhttp.Call.getResponseWithInterceptorChain(Call.java:205)
        at com.squareup.okhttp.Call.execute(Call.java:80)
        at com.qcloud.image.http.DefaultImageHttpClient.sendPostRequest(DefaultImageHttpClient.java:153)
        at com.qcloud.image.http.AbstractImageHttpClient.sendHttpRequest(AbstractImageHttpClient.java:45)
        at com.qcloud.image.op.DetectionOp.idcardDetect(DetectionOp.java:192)
        at com.qcloud.image.ImageClient.idcardDetect(ImageClient.java:128)
        at com.XXXX.ocr.OcrServiceQcloudImpl.idCardOcrPath(OcrServiceQcloudImpl.java:57)
        at com.XXXX.ocr.OcrController.idCardOcr(OcrController.java:90)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:877)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:783)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
        at com.codahale.metrics.servlet.AbstractInstrumentedFilter.doFilter(AbstractInstrumentedFilter.java:111)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:101)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:158)
        at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.filterAndRecordMetrics(WebMvcMetricsFilter.java:126)
        at org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter.doFilterInternal(WebMvcMetricsFilter.java:111)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.springframework.boot.actuate.web.trace.servlet.HttpTraceFilter.doFilterInternal(HttpTraceFilter.java:90)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
        at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at com.XXXX.security.jwt.JWTFilter.doFilter(JWTFilter.java:36)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:96)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
        at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
        at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
        at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
        at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
        at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
        at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
        at io.undertow.server.Connectors.executeRootHandler(Connectors.java:336)
        at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)





Caused by: com.navercorp.pinpoint.bootstrap.instrument.InstrumentException: Failed to add getter: com.navercorp.pinpoint.plugin.okhttp.v2.ConnectionGetter
        at com.navercorp.pinpoint.profiler.instrument.ASMClass.addGetter(ASMClass.java:275)
        at com.navercorp.pinpoint.plugin.okhttp.v2.OkHttpPlugin$4.doInTransform(OkHttpPlugin.java:127)
        at com.navercorp.pinpoint.profiler.plugin.MatchableClassFileTransformerGuardDelegate.transform(MatchableClassFileTransformerGuardDelegate.java:75)
        ... 140 more
Caused by: java.lang.IllegalArgumentException: Not found field. name=connection
        at com.navercorp.pinpoint.profiler.instrument.ASMClass.addGetter(ASMClass.java:263)
        ... 142 more

-------------------



Issue comments:
Hi @pikuzi 
Are you using okhttp version 2.7.x?
We add a getter for `private Connection connection` field in **HttpEngine** to use it in our interceptor but okhttp 2.7.0+ does not have this field. This would have led to your issue.
We'll try to fix this for 1.8.1 (or you could cook up a fix and throw us a PR which would be superb).

In the mean time, the exception shouldn't cause any issue except for okhttp client calls not being traced.
@pikuzi 
Fixed merged to master branch (1.8.1-SNAPSHOT) if you're still around :)

Pull request review comments:

Patch that resolved the issue:
diff --git a/agent-it/pom.xml b/agent-it/pom.xml
index bfd4e9756941..a96b3cb54eae 100644
--- a/agent-it/pom.xml
+++ b/agent-it/pom.xml
@@ -188,11 +188,15 @@
             <scope>test</scope>
         </dependency>
 
-
         <dependency>
             <groupId>com.squareup.okhttp</groupId>
             <artifactId>okhttp</artifactId>
-            <scope>provided</scope>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <scope>test</scope>
         </dependency>
 
         <dependency>
diff --git a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/OkHttpPlugin.java b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/OkHttpPlugin.java
index 9a57efa4be2f..57acd9f01c9a 100644
--- a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/OkHttpPlugin.java
+++ b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/OkHttpPlugin.java
@@ -124,18 +124,34 @@ public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, Strin
                 final InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer);
                 target.addGetter(OkHttpConstants.USER_REQUEST_GETTER_V2, OkHttpConstants.FIELD_USER_REQUEST);
                 target.addGetter(OkHttpConstants.USER_RESPONSE_GETTER_V2, OkHttpConstants.FIELD_USER_RESPONSE);
-                target.addGetter(OkHttpConstants.CONNECTION_GETTER_V2, OkHttpConstants.FIELD_CONNECTION);
 
                 final InstrumentMethod sendRequestMethod = target.getDeclaredMethod("sendRequest");
                 if (sendRequestMethod != null) {
                     sendRequestMethod.addScopedInterceptor("com.navercorp.pinpoint.plugin.okhttp.v2.interceptor.HttpEngineSendRequestMethodInterceptor", OkHttpConstants.SEND_REQUEST_SCOPE);
                 }
 
-                final InstrumentMethod connectMethod = target.getDeclaredMethod("connect");
-                if (connectMethod != null) {
-                    connectMethod.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v2.interceptor.HttpEngineConnectMethodInterceptor");
+                // pre-2.7.0
+                if (target.hasField("connection", "com.squareup.okhttp.Connection")) {
+                    target.addGetter(OkHttpConstants.CONNECTION_GETTER_V2, OkHttpConstants.FIELD_CONNECTION);
+                    // 2.3.0+
+                    final InstrumentMethod connectMethod = target.getDeclaredMethod("connect");
+                    if (connectMethod != null) {
+                        connectMethod.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v2.interceptor.HttpEngineConnectMethodInterceptor");
+                    }
+                    // pre-2.3.0
+                    final InstrumentMethod connectMethodWithParam = target.getDeclaredMethod("connect", "com.squareup.okhttp.Request");
+                    if (connectMethodWithParam != null) {
+                        connectMethodWithParam.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v2.interceptor.HttpEngineConnectMethodInterceptor");
+                    }
+                } else {
+                    // 2.7.0+
+                    final InstrumentMethod connectMethod = target.getDeclaredMethod("connect");
+                    if (connectMethod != null) {
+                        connectMethod.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v2.interceptor.HttpEngineConnectMethodFromUserRequestInterceptor");
+                    }
                 }
 
+
                 final InstrumentMethod readResponseMethod = target.getDeclaredMethod("readResponse");
                 if (readResponseMethod != null) {
                     readResponseMethod.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v2.interceptor.HttpEngineReadResponseMethodInterceptor", va(config.isStatusCode()));
diff --git a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineConnectMethodFromUserRequestInterceptor.java b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineConnectMethodFromUserRequestInterceptor.java
new file mode 100644
index 000000000000..eb103a1fa83d
--- /dev/null
+++ b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineConnectMethodFromUserRequestInterceptor.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 NAVER Corp.
+ *
+ * Licensed 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 com.navercorp.pinpoint.plugin.okhttp.v2.interceptor;
+
+import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor;
+import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder;
+import com.navercorp.pinpoint.bootstrap.context.TraceContext;
+import com.navercorp.pinpoint.bootstrap.interceptor.SpanEventSimpleAroundInterceptorForPlugin;
+import com.navercorp.pinpoint.common.plugin.util.HostAndPort;
+import com.navercorp.pinpoint.common.trace.AnnotationKey;
+import com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants;
+import com.navercorp.pinpoint.plugin.okhttp.v2.UserRequestGetter;
+import com.squareup.okhttp.HttpUrl;
+import com.squareup.okhttp.Request;
+
+/**
+ * @author HyunGil Jeong
+ */
+public class HttpEngineConnectMethodFromUserRequestInterceptor extends SpanEventSimpleAroundInterceptorForPlugin {
+
+    public HttpEngineConnectMethodFromUserRequestInterceptor(TraceContext traceContext, MethodDescriptor descriptor) {
+        super(traceContext, descriptor);
+    }
+
+    @Override
+    protected void doInBeforeTrace(SpanEventRecorder recorder, Object target, Object[] args) {
+    }
+
+    @Override
+    protected void doInAfterTrace(SpanEventRecorder recorder, Object target, Object[] args, Object result, Throwable throwable) {
+        recorder.recordApi(methodDescriptor);
+        recorder.recordServiceType(OkHttpConstants.OK_HTTP_CLIENT_INTERNAL);
+        recorder.recordException(throwable);
+
+        if (target instanceof UserRequestGetter) {
+            final Request request = ((UserRequestGetter)target)._$PINPOINT$_getUserRequest();
+            if (request != null && request.httpUrl() != null) {
+                final HttpUrl httpUrl = request.httpUrl();
+                final String hostAndPort = HostAndPort.toHostAndPortString(httpUrl.host(), httpUrl.port());
+                recorder.recordAttribute(AnnotationKey.HTTP_INTERNAL_DISPLAY, hostAndPort);
+            }
+        }
+    }
+}
diff --git a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineReadResponseMethodInterceptor.java b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineReadResponseMethodInterceptor.java
index 5608e4aff40a..3ed4f3e17da0 100644
--- a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineReadResponseMethodInterceptor.java
+++ b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineReadResponseMethodInterceptor.java
@@ -21,7 +21,6 @@
 import com.navercorp.pinpoint.bootstrap.logging.PLogger;
 import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory;
 import com.navercorp.pinpoint.common.trace.AnnotationKey;
-import com.navercorp.pinpoint.plugin.okhttp.v2.ConnectionGetter;
 import com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants;
 import com.navercorp.pinpoint.plugin.okhttp.v2.UserRequestGetter;
 import com.navercorp.pinpoint.plugin.okhttp.v2.UserResponseGetter;
@@ -78,13 +77,6 @@ private boolean validate(Object target) {
             return false;
         }
 
-        if (!(target instanceof ConnectionGetter)) {
-            if (isDebug) {
-                logger.debug("Invalid target object. Need field accessor({}).", OkHttpConstants.FIELD_CONNECTION);
-            }
-            return false;
-        }
-
         return true;
     }
 
diff --git a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineSendRequestMethodInterceptor.java b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineSendRequestMethodInterceptor.java
index 318c218a85d1..cf64892c702e 100644
--- a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineSendRequestMethodInterceptor.java
+++ b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v2/interceptor/HttpEngineSendRequestMethodInterceptor.java
@@ -32,7 +32,6 @@
 import com.navercorp.pinpoint.bootstrap.plugin.request.util.CookieExtractor;
 import com.navercorp.pinpoint.bootstrap.plugin.request.util.CookieRecorder;
 import com.navercorp.pinpoint.bootstrap.plugin.request.util.CookieRecorderFactory;
-import com.navercorp.pinpoint.plugin.okhttp.v2.ConnectionGetter;
 import com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants;
 import com.navercorp.pinpoint.plugin.okhttp.OkHttpPluginConfig;
 import com.navercorp.pinpoint.plugin.okhttp.v2.OkHttpClientRequestAdaptor;
@@ -119,13 +118,6 @@ private boolean validate(Object target) {
             return false;
         }
 
-        if (!(target instanceof ConnectionGetter)) {
-            if (isDebug) {
-                logger.debug("Invalid target object. Need field accessor({}).", OkHttpConstants.FIELD_CONNECTION);
-            }
-            return false;
-        }
-
         return true;
     }
 
diff --git a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v3/OkHttpPlugin.java b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v3/OkHttpPlugin.java
index b314486d679d..22b77a5d1e96 100644
--- a/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v3/OkHttpPlugin.java
+++ b/plugins/okhttp/src/main/java/com/navercorp/pinpoint/plugin/okhttp/v3/OkHttpPlugin.java
@@ -197,10 +197,34 @@ private void addRealConnection() {
             public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException {
                 final InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer);
 
-                final InstrumentMethod connectMethod = target.getDeclaredMethod("connect", "int", "int", "int", "boolean");
-                if (connectMethod != null) {
+                boolean addRouteGetter = false;
+                // 3.4.x, 3.5.x
+                final InstrumentMethod connectMethod1 = target.getDeclaredMethod("connect", "int", "int", "int", "java.util.List", "boolean");
+                if (connectMethod1 != null) {
+                    connectMethod1.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v3.interceptor.RealConnectionConnectMethodInterceptor");
+                    addRouteGetter = true;
+                }
+                // 3.6.x - 3.8.x
+                final InstrumentMethod connectMethod2 = target.getDeclaredMethod("connect", "int", "int", "int", "boolean");
+                if (connectMethod2 != null) {
+                    connectMethod2.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v3.interceptor.RealConnectionConnectMethodInterceptor");
+                    addRouteGetter = true;
+                }
+                // 3.9.0
+                final InstrumentMethod connectMethod3 = target.getDeclaredMethod("connect", "int", "int", "int", "boolean", "okhttp3.Call", "okhttp3.EventListener");
+                if (connectMethod3 != null) {
+                    connectMethod3.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v3.interceptor.RealConnectionConnectMethodInterceptor");
+                    addRouteGetter = true;
+                }
+                // 3.10.0+
+                final InstrumentMethod connectMethod4 = target.getDeclaredMethod("connect", "int", "int", "int", "int", "boolean", "okhttp3.Call", "okhttp3.EventListener");
+                if (connectMethod4 != null) {
+                    connectMethod4.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v3.interceptor.RealConnectionConnectMethodInterceptor");
+                    addRouteGetter = true;
+                }
+
+                if (addRouteGetter) {
                     target.addGetter("com.navercorp.pinpoint.plugin.okhttp.v3.RouteGetter", "route");
-                    connectMethod.addInterceptor("com.navercorp.pinpoint.plugin.okhttp.v3.interceptor.RealConnectionConnectMethodInterceptor");
                 }
 
                 return target.toBytecode();


Test patch:
diff --git a/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClientBackwardCompatibilityIT.java b/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClientBackwardCompatibilityIT.java
deleted file mode 100644
index bd0298537a4e..000000000000
--- a/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClientBackwardCompatibilityIT.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2018 NAVER Corp.
- *
- * Licensed 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 com.navercorp.pinpoint.plugin.jdk7.okhttp;
-
-import com.navercorp.pinpoint.bootstrap.plugin.test.Expectations;
-import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifier;
-import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifierHolder;
-import com.navercorp.pinpoint.plugin.AgentPath;
-import com.navercorp.pinpoint.plugin.WebServer;
-import com.navercorp.pinpoint.test.plugin.Dependency;
-import com.navercorp.pinpoint.test.plugin.PinpointAgent;
-import com.navercorp.pinpoint.test.plugin.PinpointPluginTestSuite;
-import com.squareup.okhttp.*;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.lang.reflect.Method;
-
-/**
- * @author jaehong.kim
- */
-@RunWith(PinpointPluginTestSuite.class)
-@PinpointAgent(AgentPath.PATH)
-@Dependency({"com.squareup.okhttp:okhttp:[2.0.0],[2.1.0],[2.2.0],[2.3.0]", "org.nanohttpd:nanohttpd:2.3.1"})
-public class OkHttpClientBackwardCompatibilityIT {
-
-    private static WebServer webServer;
-
-
-    @BeforeClass
-    public static void BeforeClass() throws Exception {
-        webServer = WebServer.newTestWebServer();
-    }
-
-
-    @AfterClass
-    public static void AfterClass() throws Exception {
-        final WebServer copy = webServer;
-        if (copy != null) {
-            copy.stop();
-            webServer = null;
-        }
-    }
-
-    @Test
-    public void execute() throws Exception {
-        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
-        OkHttpClient client = new OkHttpClient();
-        Response response = client.newCall(request).execute();
-
-        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
-        verifier.printCache();
-
-        Method callMethod = Call.class.getDeclaredMethod("execute");
-        verifier.verifyTrace(Expectations.event("OK_HTTP_CLIENT_INTERNAL", callMethod));
-    }
-}
diff --git a/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClientIT.java b/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClientIT.java
deleted file mode 100644
index 807d0db4fe8d..000000000000
--- a/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClientIT.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2018 NAVER Corp.
- *
- * Licensed 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 com.navercorp.pinpoint.plugin.jdk7.okhttp;
-
-import com.navercorp.pinpoint.bootstrap.plugin.test.Expectations;
-import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifier;
-import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifierHolder;
-import com.navercorp.pinpoint.plugin.AgentPath;
-import com.navercorp.pinpoint.plugin.WebServer;
-import com.navercorp.pinpoint.test.plugin.Dependency;
-import com.navercorp.pinpoint.test.plugin.PinpointAgent;
-import com.navercorp.pinpoint.test.plugin.PinpointPluginTestSuite;
-import com.squareup.okhttp.*;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author jaehong.kim
- */
-@RunWith(PinpointPluginTestSuite.class)
-@PinpointAgent(AgentPath.PATH)
-@Dependency({"com.squareup.okhttp:okhttp:[2.4.0],[2.5.0]", "org.nanohttpd:nanohttpd:2.3.1"})
-public class OkHttpClientIT {
-
-    private static WebServer webServer;
-
-
-    @BeforeClass
-    public static void BeforeClass() throws Exception {
-        webServer = WebServer.newTestWebServer();
-    }
-
-
-    @AfterClass
-    public static void AfterClass() throws Exception {
-        final WebServer copy = webServer;
-        if (copy != null) {
-            copy.stop();
-            webServer = null;
-        }
-    }
-
-    @Test
-    public void execute() throws Exception {
-        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
-        OkHttpClient client = new OkHttpClient();
-        Response response = client.newCall(request).execute();
-
-        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
-        verifier.printCache();
-
-        Method callMethod = Call.class.getDeclaredMethod("execute");
-        verifier.verifyTrace(Expectations.event("OK_HTTP_CLIENT_INTERNAL", callMethod));
-    }
-
-    @Test
-    public void enqueue() throws Exception {
-        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
-        OkHttpClient client = new OkHttpClient();
-        final CountDownLatch latch = new CountDownLatch(1);
-        client.newCall(request).enqueue(new Callback() {
-            @Override
-            public void onFailure(Request request, IOException e) {
-                latch.countDown();
-            }
-
-            @Override
-            public void onResponse(Response response) throws IOException {
-                latch.countDown();
-            }
-        });
-        latch.await(3, TimeUnit.SECONDS);
-
-        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
-        verifier.printCache();
-
-
-        Method enqueueMethod = Call.class.getDeclaredMethod("enqueue", com.squareup.okhttp.Callback.class);
-        verifier.verifyTrace(Expectations.event("OK_HTTP_CLIENT_INTERNAL", enqueueMethod));
-    }
-
-}
diff --git a/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_2_x_IT.java b/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_2_x_IT.java
new file mode 100644
index 000000000000..e5067b8702c9
--- /dev/null
+++ b/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_2_x_IT.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2018 NAVER Corp.
+ *
+ * Licensed 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 com.navercorp.pinpoint.plugin.jdk7.okhttp;
+
+import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifier;
+import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifierHolder;
+import com.navercorp.pinpoint.common.plugin.util.HostAndPort;
+import com.navercorp.pinpoint.plugin.AgentPath;
+import com.navercorp.pinpoint.plugin.WebServer;
+import com.navercorp.pinpoint.plugin.okhttp.EndPointUtils;
+import com.navercorp.pinpoint.test.plugin.Dependency;
+import com.navercorp.pinpoint.test.plugin.PinpointAgent;
+import com.navercorp.pinpoint.test.plugin.PinpointPluginTestSuite;
+import com.squareup.okhttp.*;
+import com.squareup.okhttp.internal.http.HttpEngine;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.annotation;
+import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.event;
+import static com.navercorp.pinpoint.common.trace.ServiceType.ASYNC;
+import static com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants.OK_HTTP_CLIENT;
+import static com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants.OK_HTTP_CLIENT_INTERNAL;
+
+/**
+ * @author jaehong.kim
+ */
+@RunWith(PinpointPluginTestSuite.class)
+@PinpointAgent(AgentPath.PATH)
+@Dependency({"com.squareup.okhttp:okhttp:[2.0.0,3.0.0)", "org.nanohttpd:nanohttpd:2.3.1"})
+public class OkHttpClient_2_x_IT {
+
+    private static WebServer webServer;
+
+
+    @BeforeClass
+    public static void BeforeClass() throws Exception {
+        webServer = WebServer.newTestWebServer();
+    }
+
+
+    @AfterClass
+    public static void AfterClass() throws Exception {
+        final WebServer copy = webServer;
+        if (copy != null) {
+            copy.stop();
+            webServer = null;
+        }
+    }
+
+    @Test
+    public void execute() throws Exception {
+        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
+        OkHttpClient client = new OkHttpClient();
+        Response response = client.newCall(request).execute();
+
+        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
+        verifier.printCache();
+
+        Method executeMethod = Call.class.getDeclaredMethod("execute");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), executeMethod));
+
+        Method sendRequestMethod = HttpEngine.class.getDeclaredMethod("sendRequest");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT.getName(), sendRequestMethod,
+                null, null, webServer.getHostAndPort(),
+                annotation("http.url", request.urlString())));
+
+        URL url = request.url();
+        int port = EndPointUtils.getPort(url.getPort(), url.getDefaultPort());
+        String hostAndPort = HostAndPort.toHostAndPortString(url.getHost(), port);
+        Method connectMethod = getConnectMethod();
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), connectMethod,
+                annotation("http.internal.display", hostAndPort)));
+
+        Method readResponseMethod = HttpEngine.class.getDeclaredMethod("readResponse");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), readResponseMethod,
+                annotation("http.status.code", response.code())));
+
+        verifier.verifyTraceCount(0);
+    }
+
+    @Test
+    public void enqueue() throws Exception {
+        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
+        OkHttpClient client = new OkHttpClient();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final AtomicReference<Response> responseRef = new AtomicReference<Response>(null);
+        client.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Request request, IOException e) {
+                latch.countDown();
+            }
+
+            @Override
+            public void onResponse(Response response) throws IOException {
+                responseRef.set(response);
+                latch.countDown();
+            }
+        });
+        latch.await(3, TimeUnit.SECONDS);
+
+        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
+        verifier.printCache();
+
+
+        Method callEnqueueMethod = Call.class.getDeclaredMethod("enqueue", com.squareup.okhttp.Callback.class);
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), callEnqueueMethod));
+
+        Method dispatcherEnqueueMethod = Dispatcher.class.getDeclaredMethod("enqueue", Class.forName("com.squareup.okhttp.Call$AsyncCall"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), dispatcherEnqueueMethod));
+
+        verifier.verifyTrace(event(ASYNC.getName(), "Asynchronous Invocation"));
+
+        Method executeMethod = Class.forName("com.squareup.okhttp.Call$AsyncCall").getDeclaredMethod("execute");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), executeMethod));
+
+        Method sendRequestMethod = HttpEngine.class.getDeclaredMethod("sendRequest");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT.getName(), sendRequestMethod,
+                null, null, webServer.getHostAndPort(),
+                annotation("http.url", request.urlString())));
+
+        URL url = request.url();
+        int port = EndPointUtils.getPort(url.getPort(), url.getDefaultPort());
+        String hostAndPort = HostAndPort.toHostAndPortString(url.getHost(), port);
+        Method connectMethod = getConnectMethod();
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), connectMethod,
+                annotation("http.internal.display", hostAndPort)));
+
+        Response response = responseRef.get();
+        Assert.assertNotNull("response is null", response);
+        Method readResponseMethod = HttpEngine.class.getDeclaredMethod("readResponse");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), readResponseMethod,
+                annotation("http.status.code", response.code())));
+
+        verifier.verifyTraceCount(0);
+    }
+
+    private Method getConnectMethod() {
+        try {
+            // [2.3.0,)
+            return HttpEngine.class.getDeclaredMethod("connect");
+        } catch (NoSuchMethodException e) {
+            try {
+                // [2.0.0,2.2.max]
+                return HttpEngine.class.getDeclaredMethod("connect", Request.class);
+            } catch (NoSuchMethodException e1) {
+                throw new AssertionError("Expected methods connect() / connect(com.squareup.okhttp.Request) not found in HttpEngine class");
+            }
+        }
+    }
+
+}
diff --git a/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_3_0_0_to_3_3_x_IT.java b/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_3_0_0_to_3_3_x_IT.java
new file mode 100644
index 000000000000..6b410faac961
--- /dev/null
+++ b/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_3_0_0_to_3_3_x_IT.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2018 NAVER Corp.
+ *
+ * Licensed 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 com.navercorp.pinpoint.plugin.jdk7.okhttp;
+
+import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifier;
+import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifierHolder;
+import com.navercorp.pinpoint.common.plugin.util.HostAndPort;
+import com.navercorp.pinpoint.plugin.AgentPath;
+import com.navercorp.pinpoint.plugin.WebServer;
+import com.navercorp.pinpoint.test.plugin.Dependency;
+import com.navercorp.pinpoint.test.plugin.PinpointAgent;
+import com.navercorp.pinpoint.test.plugin.PinpointPluginTestSuite;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.annotation;
+import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.event;
+import static com.navercorp.pinpoint.common.trace.ServiceType.ASYNC;
+import static com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants.OK_HTTP_CLIENT;
+import static com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants.OK_HTTP_CLIENT_INTERNAL;
+
+/**
+ * @author HyunGil Jeong
+ */
+@RunWith(PinpointPluginTestSuite.class)
+@PinpointAgent(AgentPath.PATH)
+@Dependency({"com.squareup.okhttp3:okhttp:[3.0.0,3.3.max]", "org.nanohttpd:nanohttpd:2.3.1"})
+public class OkHttpClient_3_0_0_to_3_3_x_IT {
+
+    private static WebServer webServer;
+
+
+    @BeforeClass
+    public static void BeforeClass() throws Exception {
+        webServer = WebServer.newTestWebServer();
+    }
+
+
+    @AfterClass
+    public static void AfterClass() throws Exception {
+        final WebServer copy = webServer;
+        if (copy != null) {
+            copy.stop();
+            webServer = null;
+        }
+    }
+
+    @Test
+    public void execute() throws Exception {
+        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
+        OkHttpClient client = new OkHttpClient();
+        Response response = client.newCall(request).execute();
+
+        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
+        verifier.printCache();
+
+        Method executeMethod = Class.forName("okhttp3.RealCall").getDeclaredMethod("execute");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), executeMethod));
+
+        Method sendRequestMethod = Class.forName("okhttp3.internal.http.HttpEngine").getDeclaredMethod("sendRequest");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT.getName(), sendRequestMethod,
+                null, null, webServer.getHostAndPort(),
+                annotation("http.url", request.url().toString())));
+
+        String hostAndPort = HostAndPort.toHostAndPortString(request.url().host(), request.url().port());
+        Method connectMethod = Class.forName("okhttp3.internal.http.HttpEngine").getDeclaredMethod("connect");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), connectMethod,
+                annotation("http.internal.display", hostAndPort)));
+
+        Method readResponseMethod = Class.forName("okhttp3.internal.http.HttpEngine").getDeclaredMethod("readResponse");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), readResponseMethod,
+                annotation("http.status.code", response.code())));
+
+        verifier.verifyTraceCount(0);
+    }
+
+    @Test
+    public void enqueue() throws Exception {
+        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
+        OkHttpClient client = new OkHttpClient();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final AtomicReference<Response> responseRef = new AtomicReference<Response>(null);
+        client.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+                latch.countDown();
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                responseRef.set(response);
+                latch.countDown();
+            }
+        });
+        latch.await(3, TimeUnit.SECONDS);
+
+        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
+        verifier.printCache();
+
+        Method realCallEnqueueMethod = Class.forName("okhttp3.RealCall").getDeclaredMethod("enqueue", Class.forName("okhttp3.Callback"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), realCallEnqueueMethod));
+
+        Method dispatcherEnqueueMethod = Class.forName("okhttp3.Dispatcher").getDeclaredMethod("enqueue", Class.forName("okhttp3.RealCall$AsyncCall"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), dispatcherEnqueueMethod));
+
+        verifier.verifyTrace(event(ASYNC.getName(), "Asynchronous Invocation"));
+
+        Method executeMethod = Class.forName("okhttp3.RealCall$AsyncCall").getDeclaredMethod("execute");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), executeMethod));
+
+        Method sendRequestMethod = Class.forName("okhttp3.internal.http.HttpEngine").getDeclaredMethod("sendRequest");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT.getName(), sendRequestMethod,
+                null, null, webServer.getHostAndPort(),
+                annotation("http.url", request.url().toString())));
+
+        String hostAndPort = HostAndPort.toHostAndPortString(request.url().host(), request.url().port());
+        Method connectMethod = Class.forName("okhttp3.internal.http.HttpEngine").getDeclaredMethod("connect");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), connectMethod,
+                annotation("http.internal.display", hostAndPort)));
+
+        Response response = responseRef.get();
+        Method readResponseMethod = Class.forName("okhttp3.internal.http.HttpEngine").getDeclaredMethod("readResponse");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), readResponseMethod,
+                annotation("http.status.code", response.code())));
+
+        verifier.verifyTraceCount(0);
+    }
+
+}
diff --git a/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_3_4_0_to_3_x_IT.java b/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_3_4_0_to_3_x_IT.java
new file mode 100644
index 000000000000..cf6fe90c35b2
--- /dev/null
+++ b/agent-it/src/test/java/com/navercorp/pinpoint/plugin/jdk7/okhttp/OkHttpClient_3_4_0_to_3_x_IT.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2018 NAVER Corp.
+ *
+ * Licensed 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 com.navercorp.pinpoint.plugin.jdk7.okhttp;
+
+import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifier;
+import com.navercorp.pinpoint.bootstrap.plugin.test.PluginTestVerifierHolder;
+import com.navercorp.pinpoint.common.plugin.util.HostAndPort;
+import com.navercorp.pinpoint.plugin.AgentPath;
+import com.navercorp.pinpoint.plugin.WebServer;
+import com.navercorp.pinpoint.test.plugin.Dependency;
+import com.navercorp.pinpoint.test.plugin.PinpointAgent;
+import com.navercorp.pinpoint.test.plugin.PinpointPluginTestSuite;
+import okhttp3.Call;
+import okhttp3.Callback;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.annotation;
+import static com.navercorp.pinpoint.bootstrap.plugin.test.Expectations.event;
+import static com.navercorp.pinpoint.common.trace.ServiceType.ASYNC;
+import static com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants.OK_HTTP_CLIENT;
+import static com.navercorp.pinpoint.plugin.okhttp.OkHttpConstants.OK_HTTP_CLIENT_INTERNAL;
+
+/**
+ * @author HyunGil Jeong
+ */
+@RunWith(PinpointPluginTestSuite.class)
+@PinpointAgent(AgentPath.PATH)
+@Dependency({"com.squareup.okhttp3:okhttp:[3.4.0,)", "org.nanohttpd:nanohttpd:2.3.1"})
+public class OkHttpClient_3_4_0_to_3_x_IT {
+
+    private static WebServer webServer;
+
+
+    @BeforeClass
+    public static void BeforeClass() throws Exception {
+        webServer = WebServer.newTestWebServer();
+    }
+
+
+    @AfterClass
+    public static void AfterClass() throws Exception {
+        final WebServer copy = webServer;
+        if (copy != null) {
+            copy.stop();
+            webServer = null;
+        }
+    }
+
+    @Test
+    public void execute() throws Exception {
+        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
+        OkHttpClient client = new OkHttpClient();
+        Response response = client.newCall(request).execute();
+
+        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
+        verifier.printCache();
+
+        Method executeMethod = Class.forName("okhttp3.RealCall").getDeclaredMethod("execute");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), executeMethod));
+
+        Method interceptMethod = Class.forName("okhttp3.internal.http.BridgeInterceptor").getDeclaredMethod("intercept", Class.forName("okhttp3.Interceptor$Chain"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT.getName(), interceptMethod,
+                null, null, webServer.getHostAndPort(),
+                annotation("http.url", request.url().toString()),
+                annotation("http.status.code", response.code())));
+
+        String hostAndPort = HostAndPort.toHostAndPortString(request.url().host(), request.url().port());
+        Method connectMethod = getConnectMethod(Class.forName("okhttp3.internal.connection.RealConnection"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), connectMethod,
+                annotation("http.internal.display", hostAndPort)));
+
+        verifier.verifyTraceCount(0);
+    }
+
+    @Test
+    public void enqueue() throws Exception {
+        Request request = new Request.Builder().url(webServer.getCallHttpUrl()).build();
+        OkHttpClient client = new OkHttpClient();
+        final CountDownLatch latch = new CountDownLatch(1);
+        final AtomicReference<Response> responseRef = new AtomicReference<Response>(null);
+        client.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+                latch.countDown();
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                responseRef.set(response);
+                latch.countDown();
+            }
+        });
+        latch.await(3, TimeUnit.SECONDS);
+
+        PluginTestVerifier verifier = PluginTestVerifierHolder.getInstance();
+        verifier.printCache();
+
+        Method realCallEnqueueMethod = Class.forName("okhttp3.RealCall").getDeclaredMethod("enqueue", Class.forName("okhttp3.Callback"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), realCallEnqueueMethod));
+
+        Method dispatcherEnqueueMethod = Class.forName("okhttp3.Dispatcher").getDeclaredMethod("enqueue", Class.forName("okhttp3.RealCall$AsyncCall"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), dispatcherEnqueueMethod));
+
+        verifier.verifyTrace(event(ASYNC.getName(), "Asynchronous Invocation"));
+
+        Method executeMethod = Class.forName("okhttp3.RealCall$AsyncCall").getDeclaredMethod("execute");
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), executeMethod));
+
+        Response response = responseRef.get();
+        Method interceptMethod = Class.forName("okhttp3.internal.http.BridgeInterceptor").getDeclaredMethod("intercept", Class.forName("okhttp3.Interceptor$Chain"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT.getName(), interceptMethod,
+                null, null, webServer.getHostAndPort(),
+                annotation("http.url", request.url().toString()),
+                annotation("http.status.code", response.code())));
+
+        String hostAndPort = HostAndPort.toHostAndPortString(request.url().host(), request.url().port());
+        Method connectMethod = getConnectMethod(Class.forName("okhttp3.internal.connection.RealConnection"));
+        verifier.verifyTrace(event(OK_HTTP_CLIENT_INTERNAL.getName(), connectMethod,
+                annotation("http.internal.display", hostAndPort)));
+
+        verifier.verifyTraceCount(0);
+    }
+
+    private Method getConnectMethod(Class<?> realConnectionClass) throws ClassNotFoundException {
+        // [3.4.0,3.5.max]
+        try {
+            return realConnectionClass.getDeclaredMethod("connect", int.class, int.class, int.class, List.class, boolean.class);
+        } catch (NoSuchMethodException e) {
+            try {
+                // [3.6.0,3.8.max]
+                return realConnectionClass.getDeclaredMethod("connect", int.class, int.class, int.class, boolean.class);
+            } catch (NoSuchMethodException e1) {
+                try {
+                    // [3.9.0,3.9.max]
+                    return realConnectionClass.getDeclaredMethod("connect", int.class, int.class, int.class, boolean.class,
+                            Class.forName("okhttp3.Call"), Class.forName("okhttp3.EventListener"));
+                } catch (NoSuchMethodException e2) {
+                    try {
+                        // [3.10.0,)
+                        return realConnectionClass.getDeclaredMethod("connect", int.class, int.class, int.class, int.class, boolean.class,
+                                Class.forName("okhttp3.Call"), Class.forName("okhttp3.EventListener"));
+                    } catch (NoSuchMethodException e3) {
+                        throw new AssertionError("Expected methods connect(...) not found in RealConnection class");
+                    }
+                }
+            }
+        }
+    }
+
+}