diff --git a/.gitignore b/.gitignore
index aa77d55f3..ee734eb46 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@
/*.iml
/deploy
/target
+/build/
diff --git a/arcus/pom.xml b/arcus/pom.xml
index 3c2cda10b..b3fb1946f 100644
--- a/arcus/pom.xml
+++ b/arcus/pom.xml
@@ -3,11 +3,11 @@
4.0.0
com.nhn.pinpoint
- pinpoint-plugins
+ pom
1.0.4-SNAPSHOT
- pinpoint-arcus-plugin
+ pinpoint-arcus
pinpoint arcus plugin
jar
@@ -92,8 +92,9 @@
org.apache.maven.plugins
maven-jar-plugin
+
- ${pinpiont-plugin-dir}
+ ../${pinpoint.agent.plugin.directory}
diff --git a/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/ArcusPlugin.java b/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/ArcusPlugin.java
index daf8e8a97..8f43d9c0b 100644
--- a/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/ArcusPlugin.java
+++ b/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/ArcusPlugin.java
@@ -4,43 +4,199 @@ import java.util.ArrayList;
import java.util.List;
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
-import com.nhn.pinpoint.bootstrap.instrument.MethodInfo;
-import com.nhn.pinpoint.bootstrap.interceptor.ParameterExtractor;
import com.nhn.pinpoint.bootstrap.plugin.ClassEditor;
import com.nhn.pinpoint.bootstrap.plugin.ClassEditorBuilder;
-import com.nhn.pinpoint.bootstrap.plugin.ClassEditorFactoryMapping;
import com.nhn.pinpoint.bootstrap.plugin.Condition;
-import com.nhn.pinpoint.bootstrap.plugin.ParameterExtractorFactory;
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPlugin;
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPluginContext;
+import com.nhn.pinpoint.plugin.arcus.filter.ArcusMethodFilter;
+import com.nhn.pinpoint.plugin.arcus.filter.FrontCacheMemcachedMethodFilter;
+import com.nhn.pinpoint.plugin.arcus.filter.MemcachedMethodFilter;
// TODO split arcus plugin and memcached plugin
public class ArcusPlugin implements ProfilerPlugin {
@Override
- public List getClassEditorMappings(ProfilerPluginContext context) {
+ public List getClassEditors(ProfilerPluginContext context) {
boolean arcus = context.getConfig().isArucs();
boolean memcached = context.getConfig().isMemcached();
- List editors = new ArrayList();
+ List editors = new ArrayList();
- if (arcus) {
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.ArcusClient", "com.nhn.pinpoint.plugin.arcus.ArcusClientEditorFactory"));
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.internal.CollectionFuture", "com.nhn.pinpoint.plugin.arcus.FutureEditorFactory"));
+ if (arcus) {
+ editors.add(getArcusClientEditor(context));
+ editors.add(getCollectionFutureEditor(context));
}
if (arcus || memcached) {
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.protocol.BaseOperationImpl", "com.nhn.pinpoint.plugin.arcus.BaseOperationImplEditorFactory"));
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.CacheManager", "com.nhn.pinpoint.plugin.arcus.BaseCacheManagerEditorFactory"));
+ editors.add(getBaseOperationImplEditor(context));
+ editors.add(getCacheManagerEditor(context));
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.internal.GetFuture", "com.nhn.pinpoint.plugin.arcus.FutureEditorFactory"));
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.internal.ImmediateFuture", "com.nhn.pinpoint.plugin.arcus.FutureEditorFactory"));
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.internal.OperationFuture", "com.nhn.pinpoint.plugin.arcus.FutureEditorFactory"));
+ editors.add(getGetFutureEditor(context));
+ // TODO ImmedateFuture doesn't have setOperation(Operation) method.
+// editors.add(getImmediateFutureEditor(context));
+ editors.add(getOperationFutureEditor(context));
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.plugin.FrontCacheGetFuture", "com.nhn.pinpoint.plugin.arcus.FrontCacheGetFutureEditorFactory"));
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.plugin.FrontCacheMemcachedClient", "com.nhn.pinpoint.plugin.arcus.FrontCacheMemcachedClientEditorFactory"));
- editors.add(new ClassEditorFactoryMapping("net.spy.memcached.MemcachedClient", "com.nhn.pinpoint.plugin.arcus.MemcachedClientEditorFactory"));
+ editors.add(getFrontCacheGetFutureEditor(context));
+ editors.add(getFrontCacheMemcachedClientEditor(context));
+ editors.add(getMemcachedClientEditor(context));
}
return editors;
}
-}
+
+ private ClassEditor getArcusClientEditor(ProfilerPluginContext context) {
+ boolean traceArcusKey = context.getConfig().isArucsKeyTrace();
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+
+ builder.edit("net.spy.memcached.ArcusClient");
+ builder.when(new Condition() {
+ @Override
+ public boolean check(InstrumentClass target) {
+ return target.hasMethod("addOp", new String[] {"java.lang.String", "net.spy.memcached.ops.Operation"}, "net.spy.memcached.ops.Operation");
+ }
+ });
+
+ builder.intercept("setCacheManager", "net.spy.memcached.CacheManager")
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.SetCacheManagerInterceptor");
+
+ builder.interceptMethodsFilteredBy(new ArcusMethodFilter())
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.ApiInterceptor")
+ .in(Commons.ARCUS_SCOPE)
+ .using(traceArcusKey ? Commons.ARCUS_KEY_EXTRACTOR_FACTORY : null);
+
+ return builder.build();
+ }
+
+ private ClassEditor getCacheManagerEditor(ProfilerPluginContext context) {
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+
+ builder.edit("net.spy.memcached.CacheManager");
+
+ builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor");
+
+ builder.interceptConstructor("java.lang.String", "java.lang.String", "net.spy.memcached.ConnectionFactoryBuilder", "java.util.concurrent.CountDownLatch", "int", "int")
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.CacheManagerConstructInterceptor");
+
+ return builder.build();
+ }
+
+
+ private ClassEditor getBaseOperationImplEditor(ProfilerPluginContext context) {
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+
+ builder.edit("net.spy.memcached.protocol.BaseOperationImpl");
+
+ builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor");
+
+ return builder.build();
+ }
+
+ private ClassEditor getFrontCacheGetFutureEditor(ProfilerPluginContext context) {
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+
+ builder.edit("net.spy.memcached.plugin.FrontCacheGetFuture");
+
+ builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.CacheNameAccessor");
+ builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.CacheKeyAccessor");
+
+ builder.interceptConstructor("net.sf.ehcache.Element")
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.FrontCacheGetFutureConstructInterceptor");
+ builder.intercept("get", "long", "java.util.concurrent.TimeUnit")
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.FrontCacheGetFutureGetInterceptor")
+ .in(Commons.ARCUS_SCOPE);
+ builder.intercept("get")
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.FrontCacheGetFutureGetInterceptor")
+ .in(Commons.ARCUS_SCOPE);
+
+ return builder.build();
+ }
+
+ private ClassEditor getFrontCacheMemcachedClientEditor(ProfilerPluginContext context) {
+ boolean traceArcusKey = context.getConfig().isArucsKeyTrace();
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+
+ builder.edit("net.spy.memcached.plugin.FrontCacheMemcachedClient");
+ builder.when(new Condition() {
+
+ @Override
+ public boolean check(InstrumentClass target) {
+ return target.hasDeclaredMethod("putFrontCache", new String[] { "java.lang.String", "java.util.concurrent.Future", "long" });
+ }
+
+ });
+
+ builder.interceptMethodsFilteredBy(new FrontCacheMemcachedMethodFilter())
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.ApiInterceptor")
+ .in(Commons.ARCUS_SCOPE)
+ .using(traceArcusKey ? Commons.ARCUS_KEY_EXTRACTOR_FACTORY : null);
+
+ return builder.build();
+ }
+
+
+ private ClassEditor getMemcachedClientEditor(ProfilerPluginContext context) {
+ boolean traceArcusKey = context.getConfig().isArucsKeyTrace();
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+
+ builder.edit("net.spy.memcached.MemcachedClient");
+ builder.when(new Condition() {
+
+ @Override
+ public boolean check(InstrumentClass target) {
+ return target.hasDeclaredMethod("addOp", new String[] { "java.lang.String", "net.spy.memcached.ops.Operation" });
+ }
+
+ });
+
+
+ builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor");
+
+ builder.intercept("addOp", "java.lang.String", "net.spy.memcached.ops.Operation")
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.AddOpInterceptor");
+
+ builder.interceptMethodsFilteredBy(new MemcachedMethodFilter())
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.ApiInterceptor")
+ .in(Commons.ARCUS_SCOPE)
+ .using(traceArcusKey ? Commons.ARCUS_KEY_EXTRACTOR_FACTORY : null);
+
+ return builder.build();
+ }
+
+ private ClassEditor getFutureEditor(ClassEditorBuilder builder) {
+ builder.inject("com.nhn.pinpoint.plugin.arcus.accessor.OperationAccessor");
+
+ builder.intercept("setOperation", "net.spy.memcached.ops.Operation")
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.FutureSetOperationInterceptor");
+
+ builder.intercept("get", "long", "java.util.concurrent.TimeUnit")
+ .with("com.nhn.pinpoint.plugin.arcus.interceptor.FutureGetInterceptor")
+ .in(Commons.ARCUS_SCOPE);
+
+ return builder.build();
+ }
+
+ private ClassEditor getCollectionFutureEditor(ProfilerPluginContext context) {
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+ builder.edit("net.spy.memcached.internal.CollectionFuture");
+ return getFutureEditor(builder);
+ }
+
+ private ClassEditor getGetFutureEditor(ProfilerPluginContext context) {
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+ builder.edit("net.spy.memcached.internal.GetFuture");
+ return getFutureEditor(builder);
+ }
+
+ private ClassEditor getOperationFutureEditor(ProfilerPluginContext context) {
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+ builder.edit("net.spy.memcached.internal.OperationFuture");
+ return getFutureEditor(builder);
+ }
+
+ private ClassEditor getImmediateFutureEditor(ProfilerPluginContext context) {
+ ClassEditorBuilder builder = context.newClassEditorBuilder();
+ builder.edit("net.spy.memcached.internal.ImmediateFuture");
+ return getFutureEditor(builder);
+ }
+
+}
\ No newline at end of file
diff --git a/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/interceptor/ApiInterceptor.java b/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/interceptor/ApiInterceptor.java
index da9be4fc8..ae70e19c2 100644
--- a/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/interceptor/ApiInterceptor.java
+++ b/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/interceptor/ApiInterceptor.java
@@ -19,7 +19,11 @@ import com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor;
*/
public class ApiInterceptor extends SpanEventSimpleAroundInterceptor {
private final ParameterExtractor parameterExtractor;
-
+
+ public ApiInterceptor() {
+ this(null);
+ }
+
public ApiInterceptor(ParameterExtractor parameterExtractor) {
super(ApiInterceptor.class);
this.parameterExtractor = parameterExtractor;
diff --git a/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/interceptor/FutureGetInterceptor.java b/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/interceptor/FutureGetInterceptor.java
index a6fad3a93..54da20a9e 100644
--- a/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/interceptor/FutureGetInterceptor.java
+++ b/arcus/src/main/java/com/nhn/pinpoint/plugin/arcus/interceptor/FutureGetInterceptor.java
@@ -8,14 +8,10 @@ import net.spy.memcached.ops.Operation;
import com.nhn.pinpoint.bootstrap.context.Trace;
import com.nhn.pinpoint.bootstrap.context.TraceContext;
-import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport;
import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor;
import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor;
-import com.nhn.pinpoint.bootstrap.interceptor.TargetClassLoader;
-import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport;
import com.nhn.pinpoint.bootstrap.logging.PLogger;
import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory;
-import com.nhn.pinpoint.bootstrap.util.MetaObject;
import com.nhn.pinpoint.common.ServiceType;
import com.nhn.pinpoint.plugin.arcus.accessor.OperationAccessor;
import com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor;
diff --git a/arcus/src/main/resources/META-INF/services/com.nhn.pinpoint.bootstrap.plugin.ProfilerPlugin b/arcus/src/main/resources/META-INF/services/com.nhn.pinpoint.bootstrap.plugin.ProfilerPlugin
new file mode 100644
index 000000000..7720c40c9
--- /dev/null
+++ b/arcus/src/main/resources/META-INF/services/com.nhn.pinpoint.bootstrap.plugin.ProfilerPlugin
@@ -0,0 +1 @@
+com.nhn.pinpoint.plugin.arcus.ArcusPlugin
\ No newline at end of file
diff --git a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/ArcusPluginIT.java b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/ArcusPluginIT.java
new file mode 100644
index 000000000..1d6f78a41
--- /dev/null
+++ b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/ArcusPluginIT.java
@@ -0,0 +1,58 @@
+package com.nhn.pinpoint.plugin.arcus;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.nhn.pinpoint.plugin.arcus.accessor.CacheKeyAccessor;
+import com.nhn.pinpoint.plugin.arcus.accessor.CacheNameAccessor;
+import com.nhn.pinpoint.plugin.arcus.accessor.OperationAccessor;
+import com.nhn.pinpoint.plugin.arcus.accessor.ServiceCodeAccessor;
+import com.nhn.pinpoint.test.fork.ForkRunner;
+import com.nhn.pinpoint.test.fork.OnChildClassLoader;
+import com.nhn.pinpoint.test.fork.PinpointAgentPath;
+import com.nhn.pinpoint.test.fork.PinpointConfig;
+
+@RunWith(ForkRunner.class)
+@PinpointConfig("target/test-classes/pinpoint-test.config")
+@PinpointAgentPath("../build/pinpoint-agent")
+@OnChildClassLoader
+public class ArcusPluginIT {
+
+ // TODO how to test intercpetor?
+
+ @Test
+ public void test() throws Exception {
+
+ Class> arcusClient = Class.forName("net.spy.memcached.ArcusClient");
+
+ Class> cacheManager = Class.forName("net.spy.memcached.CacheManager");
+ assertTrue(ServiceCodeAccessor.class.isAssignableFrom(cacheManager));
+
+ Class> collectionFuture = Class.forName("net.spy.memcached.internal.CollectionFuture");
+ assertTrue(OperationAccessor.class.isAssignableFrom(collectionFuture));
+
+ Class> baseOperationImpl = Class.forName("net.spy.memcached.protocol.BaseOperationImpl");
+ assertTrue(ServiceCodeAccessor.class.isAssignableFrom(baseOperationImpl));
+
+
+ Class> getFuture = Class.forName("net.spy.memcached.internal.GetFuture");
+ assertTrue(OperationAccessor.class.isAssignableFrom(getFuture));
+
+ Class> immediateFuture = Class.forName("net.spy.memcached.internal.ImmediateFuture");
+// assertTrue(OperationAccessor.class.isAssignableFrom(immediateFuture));
+
+ Class> operationFuture = Class.forName("net.spy.memcached.internal.OperationFuture");
+ assertTrue(OperationAccessor.class.isAssignableFrom(operationFuture));
+
+ Class> frontCacheGetFuture = Class.forName("net.spy.memcached.plugin.FrontCacheGetFuture");
+ assertTrue(CacheNameAccessor.class.isAssignableFrom(frontCacheGetFuture));
+ assertTrue(CacheKeyAccessor.class.isAssignableFrom(frontCacheGetFuture));
+
+ Class> frontCacheMemcachedClient = Class.forName("net.spy.memcached.plugin.FrontCacheMemcachedClient");
+
+ Class> memcachedClient = Class.forName("net.spy.memcached.MemcachedClient");
+ assertTrue(ServiceCodeAccessor.class.isAssignableFrom(memcachedClient));
+ }
+}
\ No newline at end of file
diff --git a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/FrontCacheGetFutureModifierIntegrationTest.java b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/FrontCacheGetFutureModifierIntegrationTest.java
index 30ccc3cd0..5f76c77cc 100644
--- a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/FrontCacheGetFutureModifierIntegrationTest.java
+++ b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/FrontCacheGetFutureModifierIntegrationTest.java
@@ -1,4 +1,4 @@
-package com.nhn.pinpoint.profiler.modifier.arcus;
+package com.nhn.pinpoint.plugin.arcus;
import com.nhn.pinpoint.common.bo.SpanEventBo;
import com.nhn.pinpoint.profiler.junit4.BasePinpointTest;
diff --git a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/ApiInterceptorTest.java b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/ApiInterceptorTest.java
index eb02d627c..bb761ca70 100644
--- a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/ApiInterceptorTest.java
+++ b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/ApiInterceptorTest.java
@@ -1,4 +1,4 @@
-package com.nhn.pinpoint.profiler.modifier.arcus.interceptor;
+package com.nhn.pinpoint.plugin.arcus.interceptor;
import static org.mockito.Mockito.*;
diff --git a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/BaseOperationTransitionStateInterceptorTest.java b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/BaseOperationTransitionStateInterceptorTest.java
index 5c42fc744..8d8ec3677 100644
--- a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/BaseOperationTransitionStateInterceptorTest.java
+++ b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/BaseOperationTransitionStateInterceptorTest.java
@@ -1,4 +1,4 @@
-package com.nhn.pinpoint.profiler.modifier.arcus.interceptor;
+package com.nhn.pinpoint.plugin.arcus.interceptor;
import junit.framework.Assert;
import net.spy.memcached.ops.OperationState;
diff --git a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/FutureGetInterceptorTest.java b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/FutureGetInterceptorTest.java
index 1cf2750d3..2979ad5f6 100644
--- a/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/FutureGetInterceptorTest.java
+++ b/arcus/src/test/java/com/nhn/pinpoint/plugin/arcus/interceptor/FutureGetInterceptorTest.java
@@ -1,4 +1,4 @@
-package com.nhn.pinpoint.profiler.modifier.arcus.interceptor;
+package com.nhn.pinpoint.plugin.arcus.interceptor;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
diff --git a/arcus/src/test/resources/pinpoint-test.config b/arcus/src/test/resources/pinpoint-test.config
new file mode 100644
index 000000000..b331ae8e0
--- /dev/null
+++ b/arcus/src/test/resources/pinpoint-test.config
@@ -0,0 +1,186 @@
+#
+# Pinpoint agent configuration
+# (Phase : local)
+#
+
+###########################################################
+# Collector server #
+###########################################################
+# 로컬
+profiler.collector.ip=127.0.0.1
+# 개발
+#profiler.collector.ip=10.64.84.188
+# 운영
+#profiler.collector.ip=10.25.149.249
+
+profiler.collector.udpspan.port=9996
+profiler.collector.udp.port=9995
+profiler.collector.tcp.port=9994
+
+
+###########################################################
+# Profiler Global Configuration #
+###########################################################
+profiler.enable=true
+
+profiler.jvm.collect.interval=1000
+
+profiler.sampling.enable=true
+
+# 아래 지정한 값중 한 개의 트랜잭션을 수집합니다. (예를들어 1로 지정하면 100%수집, 2로 지정하면 50%수집 셈)
+profiler.sampling.rate=1
+
+# span을 Io에 flush할 경우 buffering 여부
+profiler.io.buffering.enable=true
+
+# buffering 시 몇개 까지 저장할지 여부
+profiler.io.buffering.buffersize=20
+
+
+
+profiler.spandatasender.write.queue.size=5120
+#profiler.spandatasender.socket.sendbuffersize=1048576
+#profiler.spandatasender.socket.timeout=3000
+
+profiler.statdatasender.write.queue.size=5120
+#profiler.statdatasender.socket.sendbuffersize=1048576
+#profiler.statdatasender.socket.timeout=3000
+
+profiler.heartbeat.interval=300000
+
+# Tcp Data Command 허용 여부
+profiler.tcpdatasender.command.accept.enable=true
+
+###########################################################
+# application type #
+###########################################################
+#profiler.applicationservertype=TOMCAT
+#profiler.applicationservertype=BLOC
+
+
+###########################################################
+# user defined classes #
+###########################################################
+profiler.include=com.nhn.pinpoint.testweb.controller.*,com.nhn.pinpoint.testweb.MyClass
+
+
+###########################################################
+# JDBC #
+###########################################################
+profiler.jdbc=true
+profiler.jdbc.sqlcachesize=1024
+profiler.jdbc.maxsqlbindvaluesize=1024
+
+#
+# MYSQL
+#
+profiler.jdbc.mysql=true
+profiler.jdbc.mysql.setautocommit=true
+profiler.jdbc.mysql.commit=true
+profiler.jdbc.mysql.rollback=true
+
+#
+# MSSQL
+#
+profiler.jdbc.mssql=false
+
+#
+# Oracle
+#
+profiler.jdbc.oracle=true
+profiler.jdbc.oracle.setautocommit=true
+profiler.jdbc.oracle.commit=true
+profiler.jdbc.oracle.rollback=true
+
+#
+# CUBRID
+#
+profiler.jdbc.cubrid=true
+profiler.jdbc.cubrid.setautocommit=true
+profiler.jdbc.cubrid.commit=true
+profiler.jdbc.cubrid.rollback=true
+
+#
+# DBCP
+#
+profiler.jdbc.dbcp=true
+profiler.jdbc.dbcp.connectionclose=true
+
+
+###########################################################
+# Apache HTTP Client 4.x #
+###########################################################
+profiler.apache.httpclient4=true
+profiler.apache.httpclient4.cookie=true
+
+# cookie를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지
+profiler.apache.httpclient4.cookie.dumptype=ALWAYS
+profiler.apache.httpclient4.cookie.sampling.rate=1
+
+# post, put의 entity를 덤프한다. 단 HttpEtity.isRepeatable()=true 인 Entity에 한정된다.
+profiler.apache.httpclient4.entity=true
+
+# entity를 언제 덤프할지 결정. ALWAYS or EXCEPTION 2가지
+profiler.apache.httpclient4.entity.dumptype=ALWAYS
+profiler.apache.httpclient4.entity.sampling.rate=1
+
+profiler.apache.nio.httpclient4=true
+
+
+###########################################################
+# Ning Async HTTP Client #
+###########################################################
+profiler.ning.asynchttpclient=true
+profiler.ning.asynchttpclient.cookie=true
+profiler.ning.asynchttpclient.cookie.dumptype=ALWAYS
+profiler.ning.asynchttpclient.cookie.dumpsize=1024
+profiler.ning.asynchttpclient.cookie.sampling.rate=1
+profiler.ning.asynchttpclient.entity=true
+profiler.ning.asynchttpclient.entity.dumptype=ALWAYS
+profiler.ning.asynchttpclient.entity.dumpsize=1024
+profiler.ning.asynchttpclient.entity.sampling.rate=1
+profiler.ning.asynchttpclient.param=true
+profiler.ning.asynchttpclient.param.dumptype=ALWAYS
+profiler.ning.asynchttpclient.param.dumpsize=1024
+profiler.ning.asynchttpclient.param.sampling.rate=1
+
+
+###########################################################
+# LINE+ baseframework #
+###########################################################
+profiler.line.game.netty.param.dumpsize=512
+profiler.line.game.netty.entity.dumpsize=512
+
+
+###########################################################
+# Arcus #
+###########################################################
+profiler.arcus=true
+profiler.arcus.keytrace=true
+
+
+###########################################################
+# Memcached #
+###########################################################
+profiler.memcached=true
+profiler.memcached.keytrace=true
+
+
+###########################################################
+# ibatis #
+###########################################################
+profiler.orm.ibatis=true
+
+
+###########################################################
+# mybatis #
+###########################################################
+profiler.orm.mybatis=true
+
+###########################################################
+# spring-beans
+###########################################################
+profiler.spring.beans=true
+profiler.spring.beans.name.pattern=ma.*, outer
+profiler.spring.beans.class.pattern=.*Morae
+profiler.spring.beans.annotation=org.springframework.stereotype.Component
\ No newline at end of file
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorRegistry.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorRegistry.java
index d141c8075..c603479ca 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorRegistry.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/InterceptorRegistry.java
@@ -18,7 +18,7 @@ public class InterceptorRegistry {
private final AtomicInteger id = new AtomicInteger(0);
private final StaticAroundInterceptor[] index;
- private final SimpleAroundInterceptor[] simpleIndex;
+ private final SimpleInterceptor[] simpleIndex;
// private final ConcurrentMap nameIndex = new ConcurrentHashMap();
@@ -29,7 +29,7 @@ public class InterceptorRegistry {
InterceptorRegistry(int max) {
this.max = max;
this.index = new StaticAroundInterceptor[max];
- this.simpleIndex = new SimpleAroundInterceptor[max];
+ this.simpleIndex = new SimpleInterceptor[max];
}
@@ -51,7 +51,7 @@ public class InterceptorRegistry {
return id.getAndIncrement();
}
- int addSimpleInterceptor0(SimpleAroundInterceptor interceptor) {
+ int addSimpleInterceptor0(SimpleInterceptor interceptor) {
if (interceptor == null) {
return -1;
}
@@ -59,7 +59,7 @@ public class InterceptorRegistry {
if (newId >= max) {
throw new IndexOutOfBoundsException("size=" + index.length + " id=" + id);
}
-
+
this.simpleIndex[newId] = interceptor;
// this.nameIndex.put(interceptor.getClass().getName(), newId);
return newId;
@@ -74,8 +74,8 @@ public class InterceptorRegistry {
return interceptor;
}
- SimpleAroundInterceptor getSimpleInterceptor0(int key) {
- SimpleAroundInterceptor interceptor = simpleIndex[key];
+ SimpleInterceptor getSimpleInterceptor0(int key) {
+ SimpleInterceptor interceptor = simpleIndex[key];
if (interceptor == null) {
// 로직이 잘못되었을경우 에러가 발생하지 않도록 더미를 리턴.
return DUMMY;
@@ -109,7 +109,7 @@ public class InterceptorRegistry {
public static Interceptor findInterceptor(int key) {
- SimpleAroundInterceptor simpleInterceptor = REGISTRY.getSimpleInterceptor0(key);
+ SimpleInterceptor simpleInterceptor = REGISTRY.getSimpleInterceptor0(key);
if (simpleInterceptor != null) {
return simpleInterceptor;
}
@@ -124,12 +124,12 @@ public class InterceptorRegistry {
return DUMMY;
}
- public static int addSimpleInterceptor(SimpleAroundInterceptor interceptor) {
+ public static int addSimpleInterceptor(SimpleInterceptor interceptor) {
return REGISTRY.addSimpleInterceptor0(interceptor);
}
- public static SimpleAroundInterceptor getSimpleInterceptor(int key) {
+ public static SimpleInterceptor getSimpleInterceptor(int key) {
return REGISTRY.getSimpleInterceptor0(key);
}
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleAfterInterceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleAfterInterceptor.java
index f764192df..f95c04f79 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleAfterInterceptor.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleAfterInterceptor.java
@@ -3,6 +3,6 @@ package com.nhn.pinpoint.bootstrap.interceptor;
/**
* @author emeroad
*/
-public interface SimpleAfterInterceptor extends Interceptor {
+public interface SimpleAfterInterceptor extends SimpleInterceptor {
void after(Object target, Object[] args, Object result, Throwable throwable);
}
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleBeforeInterceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleBeforeInterceptor.java
index 534f40062..600ce1f88 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleBeforeInterceptor.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleBeforeInterceptor.java
@@ -1,5 +1,5 @@
package com.nhn.pinpoint.bootstrap.interceptor;
-public interface SimpleBeforeInterceptor extends Interceptor {
+public interface SimpleBeforeInterceptor extends SimpleInterceptor {
void before(Object target, Object[] args);
}
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleInterceptor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleInterceptor.java
new file mode 100644
index 000000000..cd69bc154
--- /dev/null
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/interceptor/SimpleInterceptor.java
@@ -0,0 +1,5 @@
+package com.nhn.pinpoint.bootstrap.interceptor;
+
+public interface SimpleInterceptor extends Interceptor {
+
+}
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/BasicClassEditor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/BasicClassEditor.java
index 9ad1953ae..02cb69748 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/BasicClassEditor.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/BasicClassEditor.java
@@ -5,12 +5,14 @@ import java.util.List;
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
import com.nhn.pinpoint.exception.PinpointException;
-public class BasicClassEditor implements ClassEditor {
+public class BasicClassEditor implements DedicatedClassEditor {
+ private final String targetClassName;
private final List metadataInjectors;
private final List interceptorInjectors;
- public BasicClassEditor(List metadataInjectors, List interceptorInjectors) {
+ public BasicClassEditor(String targetClassName, List metadataInjectors, List interceptorInjectors) {
+ this.targetClassName = targetClassName;
this.metadataInjectors = metadataInjectors;
this.interceptorInjectors = interceptorInjectors;
}
@@ -28,7 +30,14 @@ public class BasicClassEditor implements ClassEditor {
return target.toBytecode();
} catch (Throwable t) {
- throw new PinpointException("Fail to edit class", t);
+ throw new PinpointException("Fail to edit class: " + targetClassName, t);
}
}
+
+ @Override
+ public String getTargetClassName() {
+ return targetClassName;
+ }
+
+
}
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ClassEditorBuilder.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ClassEditorBuilder.java
index 92569e952..14bafbf33 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ClassEditorBuilder.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ClassEditorBuilder.java
@@ -6,8 +6,6 @@ import java.util.List;
import com.nhn.pinpoint.bootstrap.context.TraceContext;
import com.nhn.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
import com.nhn.pinpoint.bootstrap.instrument.MethodFilter;
-import com.nhn.pinpoint.bootstrap.interceptor.Interceptor;
-import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue;
import com.nhn.pinpoint.bootstrap.plugin.MetadataInitializationStrategy.ByConstructor;
public class ClassEditorBuilder {
@@ -17,6 +15,7 @@ public class ClassEditorBuilder {
private final List interceptorBuilders = new ArrayList();
private final List metadataBuilders = new ArrayList();
+ private String targetClassName;
private Condition condition;
public ClassEditorBuilder(ByteCodeInstrumentor instrumentor, TraceContext traceContext) {
@@ -24,13 +23,18 @@ public class ClassEditorBuilder {
this.traceContext = traceContext;
}
- public ClassEditorBuilder editWhen(Condition condition) {
+ public ClassEditorBuilder edit(String targetClassName) {
+ this.targetClassName = targetClassName;
+ return this;
+ }
+
+ public ClassEditorBuilder when(Condition condition) {
this.condition = condition;
return this;
}
- public InterceptorBuilder intercept(String methodName, Class>... parameterTypes) {
- InterceptorBuilder interceptorBuilder = new InterceptorBuilder(methodName, parameterTypes, null);
+ public InterceptorBuilder intercept(String methodName, String... parameterTypeNames) {
+ InterceptorBuilder interceptorBuilder = new InterceptorBuilder(methodName, parameterTypeNames, null);
interceptorBuilders.add(interceptorBuilder);
return interceptorBuilder;
}
@@ -41,19 +45,19 @@ public class ClassEditorBuilder {
return interceptorBuilder;
}
- public InterceptorBuilder interceptConstructor(Class>... parameterTypes) {
- InterceptorBuilder interceptorBuilder = new InterceptorBuilder(null, parameterTypes, null);
+ public InterceptorBuilder interceptConstructor(String... parameterTypeNames) {
+ InterceptorBuilder interceptorBuilder = new InterceptorBuilder(null, parameterTypeNames, null);
interceptorBuilders.add(interceptorBuilder);
return interceptorBuilder;
}
- public MetadataBuilder inject(Class extends TraceValue> metadataType) {
- MetadataBuilder metadataBuilder = new MetadataBuilder(metadataType);
+ public MetadataBuilder inject(String metadataAccessorName) {
+ MetadataBuilder metadataBuilder = new MetadataBuilder(metadataAccessorName);
metadataBuilders.add(metadataBuilder);
return metadataBuilder;
}
- public ClassEditor build() {
+ public DedicatedClassEditor build() {
List metadataInjectors = new ArrayList(metadataBuilders.size());
for (MetadataBuilder builder : metadataBuilders) {
@@ -66,7 +70,7 @@ public class ClassEditorBuilder {
interceptorInjectors.add(builder.build());
}
- ClassEditor editor = new BasicClassEditor(metadataInjectors, interceptorInjectors);
+ DedicatedClassEditor editor = new BasicClassEditor(targetClassName, metadataInjectors, interceptorInjectors);
if (condition != null) {
editor = new ConditionalClassEditor(condition, editor);
@@ -80,16 +84,16 @@ public class ClassEditorBuilder {
private final String[] parameterTypes;
private final MethodFilter filter;
- private Class extends Interceptor> interceptorClass;
+ private String interceptorClassName;
private Condition condition;
private String scopeName;
private Object[] constructorArguments;
private ParameterExtractorFactory parameterExtractorFactory;
private boolean singleton;
- public InterceptorBuilder(String methodName, Class>[] parameterTypes, MethodFilter filter) {
+ public InterceptorBuilder(String methodName, String[] parameterTypeNames, MethodFilter filter) {
this.methodName = methodName;
- this.parameterTypes = TypeUtils.toClassNames(parameterTypes);
+ this.parameterTypes = parameterTypeNames;
this.filter = filter;
}
@@ -98,8 +102,8 @@ public class ClassEditorBuilder {
return this;
}
- public InterceptorBuilder with(Class extends Interceptor> interceptorClass) {
- this.interceptorClass = interceptorClass;
+ public InterceptorBuilder with(String interceptorClassName) {
+ this.interceptorClassName = interceptorClassName;
return this;
}
@@ -124,7 +128,7 @@ public class ClassEditorBuilder {
}
private InterceptorInjector build() {
- InterceptorFactory interceptorFactory = new DefaultInterceptorFactory(instrumentor, traceContext, interceptorClass, constructorArguments, parameterExtractorFactory, scopeName);
+ InterceptorFactory interceptorFactory = new DefaultInterceptorFactory(instrumentor, traceContext, interceptorClassName, constructorArguments, parameterExtractorFactory, scopeName);
InterceptorInjector injector;
@@ -145,11 +149,11 @@ public class ClassEditorBuilder {
}
public class MetadataBuilder {
- private final Class extends TraceValue> metadataType;
+ private final String metadataAccessorTypeName;
private MetadataInitializationStrategy initializationStrategy;
- public MetadataBuilder(Class extends TraceValue> metadataType) {
- this.metadataType = metadataType;
+ public MetadataBuilder(String metadataAccessorTypeName) {
+ this.metadataAccessorTypeName = metadataAccessorTypeName;
}
public MetadataBuilder initializeWithDefaultConstructorOf(String className) {
@@ -158,7 +162,7 @@ public class ClassEditorBuilder {
}
private MetadataInjector build() {
- return new DefaultMetadataInjector(metadataType, initializationStrategy);
+ return new DefaultMetadataInjector(metadataAccessorTypeName, initializationStrategy);
}
}
}
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ConditionalClassEditor.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ConditionalClassEditor.java
index 23e6132ef..c24efdf34 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ConditionalClassEditor.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ConditionalClassEditor.java
@@ -2,11 +2,11 @@ package com.nhn.pinpoint.bootstrap.plugin;
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
-public class ConditionalClassEditor implements ClassEditor {
+public class ConditionalClassEditor implements DedicatedClassEditor {
private final Condition condition;
- private final ClassEditor delegate;
+ private final DedicatedClassEditor delegate;
- public ConditionalClassEditor(Condition condition, ClassEditor delegate) {
+ public ConditionalClassEditor(Condition condition, DedicatedClassEditor delegate) {
this.condition = condition;
this.delegate = delegate;
}
@@ -19,4 +19,9 @@ public class ConditionalClassEditor implements ClassEditor {
return null;
}
+
+ @Override
+ public String getTargetClassName() {
+ return delegate.getTargetClassName();
+ }
}
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultInterceptorFactory.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultInterceptorFactory.java
index a2cfe3bf5..31b0b88cf 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultInterceptorFactory.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultInterceptorFactory.java
@@ -22,17 +22,17 @@ public class DefaultInterceptorFactory implements InterceptorFactory {
private final ByteCodeInstrumentor instrumentor;
private final TraceContext traceContext;
- private final Class extends Interceptor> interceptorClass;
+ private final String interceptorClassName;
private final Object[] providedArguments;
private final ParameterExtractorFactory parameterExtractorFactory;
private final String scopeName;
- public DefaultInterceptorFactory(ByteCodeInstrumentor instrumentor, TraceContext traceContext, Class extends Interceptor> interceptorClass, Object[] providedArguments, ParameterExtractorFactory parameterExtractorFactory, String scopeName) {
+ public DefaultInterceptorFactory(ByteCodeInstrumentor instrumentor, TraceContext traceContext, String interceptorClassName, Object[] providedArguments, ParameterExtractorFactory parameterExtractorFactory, String scopeName) {
this.instrumentor = instrumentor;
this.traceContext = traceContext;
- this.interceptorClass = interceptorClass;
+ this.interceptorClassName = interceptorClassName;
this.providedArguments = providedArguments == null ? NO_ARGS : providedArguments;
this.parameterExtractorFactory = parameterExtractorFactory;
this.scopeName = scopeName;
@@ -40,7 +40,7 @@ public class DefaultInterceptorFactory implements InterceptorFactory {
@Override
public Interceptor getInterceptor(ClassLoader classLoader, InstrumentClass target, MethodInfo targetMethod) {
- Interceptor interceptor = createInstance(traceContext, classLoader, target, targetMethod);
+ Interceptor interceptor = createInstance(classLoader, traceContext, target, targetMethod);
if (scopeName != null) {
interceptor = wrapWithScope(interceptor);
@@ -48,8 +48,16 @@ public class DefaultInterceptorFactory implements InterceptorFactory {
return interceptor;
}
-
- private Interceptor createInstance(TraceContext traceContext, ClassLoader classLoader, InstrumentClass target, MethodInfo targetMethod) {
+
+ private Interceptor createInstance(ClassLoader classLoader, TraceContext traceContext, InstrumentClass target, MethodInfo targetMethod) {
+ Class> interceptorClass;
+
+ try {
+ interceptorClass = classLoader.loadClass(interceptorClassName);
+ } catch (ClassNotFoundException e) {
+ throw new PinpointException("Cannot load interceptor class: " + interceptorClassName, e);
+ }
+
Constructor>[] constructors = interceptorClass.getConstructors();
Arrays.sort(constructors, CONSTRUCTOR_COMPARATOR);
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultMetadataInjector.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultMetadataInjector.java
index 919632ec0..f3d16c6ca 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultMetadataInjector.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultMetadataInjector.java
@@ -4,27 +4,42 @@ import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
import com.nhn.pinpoint.bootstrap.instrument.InstrumentException;
import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue;
import com.nhn.pinpoint.bootstrap.plugin.MetadataInitializationStrategy.ByConstructor;
+import com.nhn.pinpoint.exception.PinpointException;
public class DefaultMetadataInjector implements MetadataInjector {
- private final Class extends TraceValue> metadataType;
+ private final String metadataAccessorTypeName;
private final MetadataInitializationStrategy strategy;
- public DefaultMetadataInjector(Class extends TraceValue> metadataType, MetadataInitializationStrategy strategy) {
- this.metadataType = metadataType;
+ public DefaultMetadataInjector(String metadataAccessorTypeName, MetadataInitializationStrategy strategy) {
+ this.metadataAccessorTypeName = metadataAccessorTypeName;
this.strategy = strategy;
}
+ @SuppressWarnings("unchecked")
@Override
public void inject(ClassLoader classLoader, InstrumentClass target) throws InstrumentException {
+ Class> type;
+ try {
+ type = classLoader.loadClass(metadataAccessorTypeName);
+ } catch (ClassNotFoundException e) {
+ throw new PinpointException("Fail to load metadata accessor: " + metadataAccessorTypeName, e);
+ }
+
+ if (!TraceValue.class.isAssignableFrom(type)) {
+ throw new PinpointException("Given type " + metadataAccessorTypeName + " is not a subtype of TraceValue");
+ }
+
+ Class extends TraceValue> metadataAccessorType = (Class extends TraceValue>)type;
+
if (strategy == null) {
- target.addTraceValue(metadataType);
+ target.addTraceValue(metadataAccessorType);
} else {
if (strategy instanceof ByConstructor) {
String javaExpression = "new " + ((ByConstructor)strategy).getClassName() + "();";
- target.addTraceValue(metadataType, javaExpression);
+ target.addTraceValue(metadataAccessorType, javaExpression);
} else {
- throw new IllegalArgumentException("Unsupported strategy: " + strategy);
+ throw new PinpointException("Unsupported strategy: " + strategy);
}
}
}
diff --git a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ProfilerPlugin.java b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ProfilerPlugin.java
index 67af74da6..feca85f5f 100644
--- a/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ProfilerPlugin.java
+++ b/bootstrap/src/main/java/com/navercorp/pinpoint/bootstrap/plugin/ProfilerPlugin.java
@@ -3,5 +3,5 @@ package com.nhn.pinpoint.bootstrap.plugin;
import java.util.List;
public interface ProfilerPlugin {
- public List getClassEditorMappings(ProfilerPluginContext context);
+ public List getClassEditors(ProfilerPluginContext context);
}
diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptorTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptorTest.java
index 00f074d2f..70af937e8 100644
--- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptorTest.java
+++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/interceptor/SpanSimpleAroundInterceptorTest.java
@@ -1,13 +1,14 @@
package com.nhn.pinpoint.bootstrap.interceptor;
-import com.nhn.pinpoint.bootstrap.context.RecordableTrace;
-import com.nhn.pinpoint.bootstrap.context.Trace;
+import static org.mockito.Mockito.*;
import junit.framework.Assert;
+
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import static org.mockito.Mockito.*;
+import com.nhn.pinpoint.bootstrap.context.RecordableTrace;
+import com.nhn.pinpoint.bootstrap.context.Trace;
public class SpanSimpleAroundInterceptorTest {
diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/plugin/ClassEditorBuilderTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/plugin/ClassEditorBuilderTest.java
index c4480d12f..dd4dd00cf 100644
--- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/plugin/ClassEditorBuilderTest.java
+++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/plugin/ClassEditorBuilderTest.java
@@ -40,8 +40,8 @@ public class ClassEditorBuilderTest {
ProfilerPluginContext helper = new ProfilerPluginContext(instrumentor, traceContext);
ClassEditorBuilder builder = helper.newClassEditorBuilder();
- builder.intercept(methodName, parameterTypes).with(TestInterceptor.class).constructedWith("provided").in(scopeName);
- builder.inject(TestMetadata.class).initializeWithDefaultConstructorOf("java.util.HashMap");
+ builder.intercept(methodName, parameterTypeNames).with("com.nhn.pinpoint.bootstrap.plugin.TestInterceptor").constructedWith("provided").in(scopeName);
+ builder.inject("com.nhn.pinpoint.bootstrap.plugin.ClassEditorBuilderTest.TestMetadata").initializeWithDefaultConstructorOf("java.util.HashMap");
ClassEditor editor = builder.build();
editor.edit(classLoader, aClass);
diff --git a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultInterceptorFactoryTest.java b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultInterceptorFactoryTest.java
index a98795b82..c2d701770 100644
--- a/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultInterceptorFactoryTest.java
+++ b/bootstrap/src/test/java/com/navercorp/pinpoint/bootstrap/plugin/DefaultInterceptorFactoryTest.java
@@ -39,7 +39,7 @@ public class DefaultInterceptorFactoryTest {
@Test
public void test0() throws Exception {
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor0.class, null, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor0", null, null, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor0.class, interceptor.getClass());
@@ -49,7 +49,7 @@ public class DefaultInterceptorFactoryTest {
public void test1() throws Exception {
Object[] args = new Object[] { "arg0" };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor0.class, args, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor0", args, null, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor0.class, interceptor.getClass());
@@ -60,7 +60,7 @@ public class DefaultInterceptorFactoryTest {
public void test2() throws Exception {
Object[] args = new Object[] { 1 };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor0.class, args, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor0", args, null, null);
factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
}
@@ -68,7 +68,7 @@ public class DefaultInterceptorFactoryTest {
public void test3() throws Exception {
Object[] args = new Object[] { "arg0", (byte)1, (short)2, (float)3.0 };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor1.class, interceptor.getClass());
@@ -82,7 +82,7 @@ public class DefaultInterceptorFactoryTest {
public void test4() throws Exception {
Object[] args = new Object[] { (byte)1, (short)2, (float)3.0, "arg0" };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor1.class, interceptor.getClass());
@@ -96,7 +96,7 @@ public class DefaultInterceptorFactoryTest {
public void test5() throws Exception {
Object[] args = new Object[] { (short)2, (float)3.0, "arg0", (byte)1 };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor1.class, interceptor.getClass());
@@ -110,7 +110,7 @@ public class DefaultInterceptorFactoryTest {
public void test6() throws Exception {
Object[] args = new Object[] { (float)3.0, (short)2, (byte)1, "arg0" };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor1.class, interceptor.getClass());
@@ -124,13 +124,13 @@ public class DefaultInterceptorFactoryTest {
public void test7() throws Exception {
Object[] args = new Object[] { (double)3.0, (short)2, (byte)1, "arg0" };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, args, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", args, null, null);
factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
}
@Test(expected=PinpointException.class)
public void test8() throws Exception {
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor1.class, null, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor1", null, null, null);
factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
}
@@ -138,7 +138,7 @@ public class DefaultInterceptorFactoryTest {
public void test9() throws Exception {
Object[] args = new Object[] { "arg0", 1, 2.0, true, 3L };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, args, extractorFactory, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", args, extractorFactory, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor2.class, interceptor.getClass());
@@ -156,7 +156,7 @@ public class DefaultInterceptorFactoryTest {
public void test10() throws Exception {
Object[] args = new Object[] { "arg0", 1, 2.0 };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, args, extractorFactory, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", args, extractorFactory, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor2.class, interceptor.getClass());
@@ -174,7 +174,7 @@ public class DefaultInterceptorFactoryTest {
public void test11() throws Exception {
Object[] args = new Object[] { "arg0", 1 };
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, args, extractorFactory, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", args, extractorFactory, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor2.class, interceptor.getClass());
@@ -190,7 +190,7 @@ public class DefaultInterceptorFactoryTest {
@Test
public void test12() throws Exception {
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, null, extractorFactory, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", null, extractorFactory, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor2.class, interceptor.getClass());
@@ -206,7 +206,7 @@ public class DefaultInterceptorFactoryTest {
@Test
public void test13() throws Exception {
- DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, TestInterceptor2.class, null, null, null);
+ DefaultInterceptorFactory factory = new DefaultInterceptorFactory(instrumentor, traceContext, "com.nhn.pinpoint.bootstrap.plugin.TestInterceptors.TestInterceptor2", null, null, null);
Interceptor interceptor = factory.getInterceptor(getClass().getClassLoader(), aClass, aMethod);
assertEquals(TestInterceptor2.class, interceptor.getClass());
diff --git a/plugins/.gitignore b/plugins/.gitignore
deleted file mode 100644
index 0c2b833ee..000000000
--- a/plugins/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/.settings/
-/.project
diff --git a/plugins/pom.xml b/plugins/pom.xml
deleted file mode 100644
index 103d548b0..000000000
--- a/plugins/pom.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-
- 4.0.0
-
- com.nhn.pinpoint
- pom
- 1.0.4-SNAPSHOT
-
-
- pinpoint-plugins
- pinpoint-plugins
- pom
-
-
- arcus
-
-
-
-
-
-
-
diff --git a/pom.xml b/pom.xml
index 5a8b2cc3c..ecaa4df2a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -68,13 +68,20 @@
profiler
profiler-optional
rpc
+ test
thrift
web
+
+
+ arcus
1.0.4-SNAPSHOT
-
+
+ build/pinpoint-agent
+ ${pinpoint.agent.directory}/plugin
+
UTF-8
1.6
1.7.5
@@ -668,19 +675,6 @@
maven-antrun-plugin
1.7
-
- com.nhncorp.maven
- maven-revision-plugin
- 1.0.0
-
-
- compile
-
- create
-
-
-
-
org.apache.maven.plugins
maven-surefire-plugin
@@ -724,7 +718,7 @@
maven-klocwork-plugin
1.0.0
-
+
diff --git a/profiler/pom.xml b/profiler/pom.xml
index 7117ffbff..72f15c128 100644
--- a/profiler/pom.xml
+++ b/profiler/pom.xml
@@ -12,7 +12,7 @@
jar
- ${basedir}/target/pinpoint-agent/
+ ../${pinpoint.agent.directory}
diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/ClassFileTransformerDispatcher.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/ClassFileTransformerDispatcher.java
index 4648533e1..a41f45bad 100644
--- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/ClassFileTransformerDispatcher.java
+++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/ClassFileTransformerDispatcher.java
@@ -11,7 +11,8 @@ import org.slf4j.LoggerFactory;
import com.nhn.pinpoint.bootstrap.config.ProfilerConfig;
import com.nhn.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
-import com.nhn.pinpoint.bootstrap.plugin.ClassEditorFactoryMapping;
+import com.nhn.pinpoint.bootstrap.plugin.ClassEditor;
+import com.nhn.pinpoint.bootstrap.plugin.DedicatedClassEditor;
import com.nhn.pinpoint.bootstrap.plugin.PluginClassLoaderFactory;
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPlugin;
import com.nhn.pinpoint.bootstrap.plugin.ProfilerPluginContext;
@@ -63,13 +64,22 @@ public class ClassFileTransformerDispatcher implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader classLoader, String className, Class> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classFileBuffer) throws IllegalClassFormatException {
-
+ if (className.contains("CacheManager")) {
+ logger.debug("Start CacheManager");
+ }
+
if (skipFilter.doFilter(classLoader, className, classBeingRedefined, protectionDomain, classFileBuffer)) {
+ if (className.equals("net/spy/memcached/CacheManager")) {
+ logger.debug("skip CacheManager");
+ }
return null;
}
AbstractModifier findModifier = this.modifierRegistry.findModifier(className);
if (findModifier == null) {
+ if (className.equals("net/spy/memcached/CacheManager")) {
+ logger.debug("no modifier for CacheManager");
+ }
// TODO : 디버그 용도로 추가함
// TODO : modifier가 중복 적용되면 어떻게 되지???
if (this.profilerConfig.getProfilableClassFilter().filter(className)) {
@@ -171,8 +181,16 @@ public class ClassFileTransformerDispatcher implements ClassFileTransformer {
ProfilerPluginContext pluginContext = new ProfilerPluginContext(byteCodeInstrumentor, agent.getTraceContext());
for (ProfilerPlugin plugin : plugins) {
- for (ClassEditorFactoryMapping mapping : plugin.getClassEditorMappings(pluginContext)) {
- modifierRepository.addModifier(new ClassEditorAdaptor(byteCodeInstrumentor, agent, mapping, pluginContext, classLoaderFactory));
+ logger.info("Loading plugin: {}", plugin.getClass().getName());
+
+ for (ClassEditor editor : plugin.getClassEditors(pluginContext)) {
+ if (editor instanceof DedicatedClassEditor) {
+ DedicatedClassEditor dedicated = (DedicatedClassEditor)editor;
+ logger.info("Registering class editor {} for {} ", dedicated.getClass().getName(), dedicated.getTargetClassName());
+ modifierRepository.addModifier(new ClassEditorAdaptor(byteCodeInstrumentor, agent, dedicated, classLoaderFactory));
+ } else {
+ logger.warn("Ignore class editor {}", editor.getClass().getName());
+ }
}
}
}
diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java
index bae81deda..8e11b9704 100644
--- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java
+++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/DefaultAgent.java
@@ -115,12 +115,6 @@ public class DefaultAgent implements Agent {
logger.info("DefaultAgent classLoader:{}", this.getClass().getClassLoader());
}
- ClassFileRetransformer retransformer = new ClassFileRetransformer(instrumentation);
- instrumentation.addTransformer(retransformer, true);
- this.classFileTransformer = new ClassFileTransformerDispatcher(this, byteCodeInstrumentor, retransformer);
- instrumentation.addTransformer(this.classFileTransformer);
-
-
final AgentInformationFactory agentInformationFactory = new AgentInformationFactory();
this.agentInformation = agentInformationFactory.createAgentInformation(typeResolver.getServerType());
logger.info("agentInformation:{}", agentInformation);
@@ -145,6 +139,13 @@ public class DefaultAgent implements Agent {
// JVM 통계 등을 주기적으로 수집하여 collector에 전송하는 monitor를 초기화한다.
this.agentStatMonitor = new AgentStatMonitor(this.statDataSender, this.agentInformation.getAgentId(), this.agentInformation.getStartTime());
+
+
+ ClassFileRetransformer retransformer = new ClassFileRetransformer(instrumentation);
+ instrumentation.addTransformer(retransformer, true);
+ this.classFileTransformer = new ClassFileTransformerDispatcher(this, byteCodeInstrumentor, retransformer);
+ instrumentation.addTransformer(this.classFileTransformer);
+
preLoadClass();
diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClass.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClass.java
index b01a6f02d..d08ca8ea5 100644
--- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClass.java
+++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/JavaAssistClass.java
@@ -5,13 +5,12 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import com.nhn.pinpoint.bootstrap.context.TraceContext;
-import com.nhn.pinpoint.bootstrap.interceptor.*;
import javassist.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.nhn.pinpoint.bootstrap.context.TraceContext;
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
import com.nhn.pinpoint.bootstrap.instrument.InstrumentException;
import com.nhn.pinpoint.bootstrap.instrument.MethodFilter;
@@ -19,6 +18,17 @@ import com.nhn.pinpoint.bootstrap.instrument.MethodInfo;
import com.nhn.pinpoint.bootstrap.instrument.NotFoundInstrumentException;
import com.nhn.pinpoint.bootstrap.instrument.Scope;
import com.nhn.pinpoint.bootstrap.instrument.Type;
+import com.nhn.pinpoint.bootstrap.interceptor.ByteCodeMethodDescriptorSupport;
+import com.nhn.pinpoint.bootstrap.interceptor.Interceptor;
+import com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry;
+import com.nhn.pinpoint.bootstrap.interceptor.LoggingInterceptor;
+import com.nhn.pinpoint.bootstrap.interceptor.MethodDescriptor;
+import com.nhn.pinpoint.bootstrap.interceptor.SimpleAfterInterceptor;
+import com.nhn.pinpoint.bootstrap.interceptor.SimpleAroundInterceptor;
+import com.nhn.pinpoint.bootstrap.interceptor.SimpleBeforeInterceptor;
+import com.nhn.pinpoint.bootstrap.interceptor.SimpleInterceptor;
+import com.nhn.pinpoint.bootstrap.interceptor.StaticAroundInterceptor;
+import com.nhn.pinpoint.bootstrap.interceptor.TraceContextSupport;
import com.nhn.pinpoint.bootstrap.interceptor.tracevalue.TraceValue;
import com.nhn.pinpoint.profiler.interceptor.DebugScopeDelegateSimpleInterceptor;
import com.nhn.pinpoint.profiler.interceptor.DebugScopeDelegateStaticInterceptor;
@@ -283,16 +293,17 @@ public class JavaAssistClass implements InstrumentClass {
throw new IllegalArgumentException("interceptor is null");
}
final CtConstructor behavior = getCtConstructor(args);
- return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, false);
+ return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
}
@Override
+ // TODO remove parameter type
public int addConstructorInterceptor(String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException {
if (interceptor == null) {
throw new IllegalArgumentException("interceptor is null");
}
final CtConstructor behavior = getCtConstructor(args);
- return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false);
+ return addInterceptor0(behavior, null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
}
@Override
@@ -301,6 +312,7 @@ public class JavaAssistClass implements InstrumentClass {
}
@Override
+ // TODO remove parameter type
public int addAllConstructorInterceptor(Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException {
if (interceptor == null) {
throw new IllegalArgumentException("interceptor is null");
@@ -312,11 +324,11 @@ public class JavaAssistClass implements InstrumentClass {
}
int interceptorId = 0;
if (length > 0) {
- interceptorId = addInterceptor0(constructorList[0], null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false);
+ interceptorId = addInterceptor0(constructorList[0], null, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
}
if (length > 1) {
for (int i = 1; i< length; i++) {
- addInterceptor0(constructorList[i], null, null, interceptorId, Type.around, false);
+ addInterceptor0(constructorList[i], null, null, interceptorId, false);
}
}
return interceptorId;
@@ -329,16 +341,17 @@ public class JavaAssistClass implements InstrumentClass {
throw new IllegalArgumentException("interceptor is null");
}
final CtBehavior behavior = getMethod(methodName, args);
- return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, true);
+ return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, true);
}
@Override
+ // TODO remove parameter type
public int addInterceptorCallByContextClassLoader(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException {
if (interceptor == null) {
throw new IllegalArgumentException("interceptor is null");
}
final CtBehavior behavior = getMethod(methodName, args);
- return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, true);
+ return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, true);
}
@Override
@@ -350,7 +363,7 @@ public class JavaAssistClass implements InstrumentClass {
throw new IllegalArgumentException("interceptor is null");
}
final CtBehavior behavior = getMethod(methodName, args);
- return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, Type.around, false);
+ return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
}
@Override
@@ -431,33 +444,35 @@ public class JavaAssistClass implements InstrumentClass {
@Override
public int reuseInterceptor(String methodName, String[] args, int interceptorId) throws InstrumentException, NotFoundInstrumentException {
final CtBehavior behavior = getMethod(methodName, args);
- return addInterceptor0(behavior, methodName, null, interceptorId, Type.around, false);
+ return addInterceptor0(behavior, methodName, null, interceptorId, false);
}
@Override
+ // TODO remove parameter type
public int reuseInterceptor(String methodName, String[] args, int interceptorId, Type type) throws InstrumentException, NotFoundInstrumentException {
final CtBehavior behavior = getMethod(methodName, args);
- return addInterceptor0(behavior, methodName, null, interceptorId, type, false);
+ return addInterceptor0(behavior, methodName, null, interceptorId, false);
}
@Override
+ // TODO remove parameter type
public int addInterceptor(String methodName, String[] args, Interceptor interceptor, Type type) throws InstrumentException, NotFoundInstrumentException {
if (interceptor == null) {
throw new IllegalArgumentException("interceptor is null");
}
final CtBehavior behavior = getMethod(methodName, args);
- return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, type, false);
+ return addInterceptor0(behavior, methodName, interceptor, NOT_DEFINE_INTERCEPTOR_ID, false);
}
- private int addInterceptor0(CtBehavior behavior, String methodName, Interceptor interceptor, int interceptorId, Type type, boolean useContextClassLoader) throws InstrumentException, NotFoundInstrumentException {
+ private int addInterceptor0(CtBehavior behavior, String methodName, Interceptor interceptor, int interceptorId, boolean useContextClassLoader) throws InstrumentException, NotFoundInstrumentException {
try {
if (interceptor != null) {
if(interceptor instanceof StaticAroundInterceptor) {
StaticAroundInterceptor staticAroundInterceptor = (StaticAroundInterceptor) interceptor;
interceptorId = InterceptorRegistry.addInterceptor(staticAroundInterceptor);
- } else if(interceptor instanceof SimpleAroundInterceptor) {
- SimpleAroundInterceptor simpleAroundInterceptor = (SimpleAroundInterceptor) interceptor;
+ } else if(interceptor instanceof SimpleInterceptor) {
+ SimpleInterceptor simpleAroundInterceptor = (SimpleInterceptor) interceptor;
interceptorId = InterceptorRegistry.addSimpleInterceptor(simpleAroundInterceptor);
} else {
throw new InstrumentException("unsupported Interceptor Type:" + interceptor);
@@ -469,32 +484,28 @@ public class JavaAssistClass implements InstrumentClass {
}
// 이제는 aroundType 인터셉터만 받고 코드 인젝션을 별도 type으로 받아야 함.
if (interceptor instanceof StaticAroundInterceptor) {
- switch (type) {
- case around:
+// switch (type) {
+// case around:
addStaticAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
- break;
- case before:
- addStaticBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
- break;
- case after:
- addStaticAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
- break;
- default:
- throw new UnsupportedOperationException("unsupport type");
- }
- } else if(interceptor instanceof SimpleAroundInterceptor) {
- switch (type) {
- case around:
- addSimpleAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
- break;
- case before:
- addSimpleBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
- break;
- case after:
- addSimpleAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
- break;
- default:
- throw new UnsupportedOperationException("unsupport type");
+// break;
+// case before:
+// addStaticBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
+// break;
+// case after:
+// addStaticAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
+// break;
+// default:
+// throw new UnsupportedOperationException("unsupport type");
+// }
+ } else if(interceptor instanceof SimpleInterceptor) {
+ if (interceptor instanceof SimpleAroundInterceptor) {
+ addSimpleAroundInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
+ } else if (interceptor instanceof SimpleBeforeInterceptor) {
+ addSimpleBeforeInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
+ } else if (interceptor instanceof SimpleAfterInterceptor) {
+ addSimpleAfterInterceptor(methodName, interceptorId, behavior, useContextClassLoader);
+ } else {
+ throw new UnsupportedOperationException("unsupport type");
}
} else {
throw new IllegalArgumentException("unsupported");
@@ -629,7 +640,7 @@ public class JavaAssistClass implements InstrumentClass {
after.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getInterceptor(%2$d);", StaticAroundInterceptor.class.getName(), id);
after.format(" interceptor.after(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s, %6$s, null);", target, ctClass.getName(), methodName, parameterTypeString, parameterIdentifier, returnType);
} else {
- after.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id);
+ after.format(" %1$s interceptor = (%1$s)com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id);
after.format(" interceptor.after(%1$s, %2$s, %3$s, null);", target, parameterIdentifier, returnType);
}
after.end();
@@ -765,14 +776,14 @@ public class JavaAssistClass implements InstrumentClass {
code.format(" interceptor.before(%1$s, \"%2$s\", \"%3$s\", \"%4$s\", %5$s);", target, ctClass.getName(), methodName, parameterDescription, parameterIdentifier);
} else {
// simpleInterceptor인덱스에서 검색하여 typecasting을 제거한다.
- code.format(" %1$s interceptor = com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleAroundInterceptor.class.getName(), id);
+ code.format(" %1$s interceptor = (%1$s)com.nhn.pinpoint.bootstrap.interceptor.InterceptorRegistry.getSimpleInterceptor(%2$d);", SimpleBeforeInterceptor.class.getName(), id);
code.format(" interceptor.before(%1$s, %2$s);", target, parameterIdentifier);
}
code.end();
}
String buildBefore = code.toString();
if (isDebug) {
- logger.debug("addStaticBeforeInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildBefore);
+ logger.debug("addBeforeInterceptor catch behavior:{} code:{}", behavior.getLongName(), buildBefore);
}
if (behavior instanceof CtConstructor) {
diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/ClassEditorAdaptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/ClassEditorAdaptor.java
index 59d12eb1d..9a7994daa 100644
--- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/ClassEditorAdaptor.java
+++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/plugin/ClassEditorAdaptor.java
@@ -2,52 +2,47 @@ package com.nhn.pinpoint.profiler.plugin;
import java.security.ProtectionDomain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import com.nhn.pinpoint.bootstrap.Agent;
import com.nhn.pinpoint.bootstrap.instrument.ByteCodeInstrumentor;
import com.nhn.pinpoint.bootstrap.instrument.InstrumentClass;
-import com.nhn.pinpoint.bootstrap.plugin.ClassEditor;
-import com.nhn.pinpoint.bootstrap.plugin.ClassEditorFactory;
-import com.nhn.pinpoint.bootstrap.plugin.ClassEditorFactoryMapping;
+import com.nhn.pinpoint.bootstrap.plugin.DedicatedClassEditor;
import com.nhn.pinpoint.bootstrap.plugin.PluginClassLoaderFactory;
-import com.nhn.pinpoint.bootstrap.plugin.ProfilerPluginContext;
import com.nhn.pinpoint.exception.PinpointException;
import com.nhn.pinpoint.profiler.modifier.AbstractModifier;
public class ClassEditorAdaptor extends AbstractModifier {
- private final ClassEditorFactoryMapping mapping;
- private final ProfilerPluginContext pluginContext;
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+ private final DedicatedClassEditor editor;
private final PluginClassLoaderFactory classLoaderFactory;
- public ClassEditorAdaptor(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent, ClassEditorFactoryMapping mapping, ProfilerPluginContext pluginContext, PluginClassLoaderFactory classLoaderFactory) {
+ public ClassEditorAdaptor(ByteCodeInstrumentor byteCodeInstrumentor, Agent agent, DedicatedClassEditor editor, PluginClassLoaderFactory classLoaderFactory) {
super(byteCodeInstrumentor, agent);
- this.mapping = mapping;
- this.pluginContext = pluginContext;
+ this.editor = editor;
this.classLoaderFactory = classLoaderFactory;
}
@Override
public byte[] modify(ClassLoader classLoader, String className, ProtectionDomain protectionDomain, byte[] classFileBuffer) {
+ logger.debug("Editing class {}", className);
+
ClassLoader forPlugin = classLoaderFactory.get(classLoader);
ClassLoader old = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(forPlugin);
try {
- Class> editorFactoryClass = forPlugin.loadClass(mapping.getEditorFactoryClassName());
-
- if (!ClassEditorFactory.class.isAssignableFrom(editorFactoryClass)) {
- throw new PinpointException("Illegal class editor factory mapping. factory class[" + editorFactoryClass + "] did not implent ClassEditorFactory");
- }
-
- ClassEditorFactory editorFactory = (ClassEditorFactory)editorFactoryClass.newInstance();
- ClassEditor editor = editorFactory.get(pluginContext);
-
InstrumentClass target = byteCodeInstrumentor.getClass(classLoader, className, classFileBuffer);
-
return editor.edit(classLoader, target);
+ } catch (PinpointException e) {
+ throw e;
} catch (Exception e) {
- throw new PinpointException("Fail to invoke plugin class editor for " + mapping.getTargetClassName() + ", editor factory: " + mapping.getEditorFactoryClassName(), e);
+ String msg = "Fail to invoke plugin class editor " + editor.getClass().getName() + " for " + editor.getTargetClassName();
+ logger.warn(msg, e);
+ throw new PinpointException(msg, e);
} finally {
Thread.currentThread().setContextClassLoader(old);
}
@@ -56,6 +51,6 @@ public class ClassEditorAdaptor extends AbstractModifier {
@Override
public String getTargetClass() {
- return mapping.getTargetClassName();
+ return editor.getTargetClassName().replace('.', '/');
}
}
diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/ForkedJUnit.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/ForkedJUnit.java
new file mode 100644
index 000000000..b98b26ce9
--- /dev/null
+++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/ForkedJUnit.java
@@ -0,0 +1,100 @@
+package com.nhn.pinpoint.profiler.util;
+
+import java.util.regex.Pattern;
+
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+public class ForkedJUnit {
+ static final String JUNIT_OUTPUT_DELIMETER = "#####";
+ static final String JUNIT_OUTPUT_DELIMETER_REGEXP = Pattern.quote(JUNIT_OUTPUT_DELIMETER);
+ private static boolean forked = false;
+
+ public static boolean isForked() {
+ return forked;
+ }
+
+
+ public static void main(String[] args) throws ClassNotFoundException {
+ forked = true;
+
+ Class>[] classes = new Class>[args.length];
+
+ for (int i = 0; i < args.length; i++) {
+ classes[i] = Class.forName(args[i]);
+ }
+
+ JUnitCore junit = new JUnitCore();
+ junit.addListener(new PrintListener());
+ Result result = junit.run(classes);
+
+ System.exit(result.getFailureCount());
+ }
+
+ private static class PrintListener extends RunListener {
+
+ @Override
+ public void testRunStarted(Description description) throws Exception {
+ System.out.println(JUNIT_OUTPUT_DELIMETER + "testRunStarted");
+ }
+
+ @Override
+ public void testRunFinished(Result result) throws Exception {
+ System.out.println(JUNIT_OUTPUT_DELIMETER + "testRunFinished");
+ }
+
+ @Override
+ public void testStarted(Description description) throws Exception {
+ System.out.println(JUNIT_OUTPUT_DELIMETER + "testStarted" + JUNIT_OUTPUT_DELIMETER + description.getDisplayName());
+ }
+
+ @Override
+ public void testFinished(Description description) throws Exception {
+ System.out.println(JUNIT_OUTPUT_DELIMETER + "testFinished" + JUNIT_OUTPUT_DELIMETER + description.getDisplayName());
+ }
+
+ @Override
+ public void testFailure(Failure failure) throws Exception {
+ System.out.println(JUNIT_OUTPUT_DELIMETER + "testFailure" + JUNIT_OUTPUT_DELIMETER + failureToString(failure));
+ }
+
+ @Override
+ public void testAssumptionFailure(Failure failure) {
+ System.out.println(JUNIT_OUTPUT_DELIMETER + "testAssumptionFailure" + JUNIT_OUTPUT_DELIMETER + failureToString(failure));
+ }
+
+ @Override
+ public void testIgnored(Description description) throws Exception {
+ System.out.println(JUNIT_OUTPUT_DELIMETER + "testIgnored" + JUNIT_OUTPUT_DELIMETER + description.getDisplayName());
+ }
+
+ private String failureToString(Failure failure) {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append(failure.getTestHeader());
+ builder.append(JUNIT_OUTPUT_DELIMETER);
+ builder.append(failure.getException().getClass().getName());
+ builder.append(JUNIT_OUTPUT_DELIMETER);
+ builder.append(failure.getMessage());
+ builder.append(JUNIT_OUTPUT_DELIMETER);
+
+ for (StackTraceElement e : failure.getException().getStackTrace()) {
+ builder.append(e.getClassName());
+ builder.append(',');
+ builder.append(e.getMethodName());
+ builder.append(',');
+ builder.append(e.getFileName());
+ builder.append(',');
+ builder.append(e.getLineNumber());
+
+ builder.append(JUNIT_OUTPUT_DELIMETER);
+ }
+
+ return builder.toString();
+ }
+ }
+
+}
diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PinpointAgent.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PinpointAgent.java
new file mode 100644
index 000000000..7fc6da228
--- /dev/null
+++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PinpointAgent.java
@@ -0,0 +1,12 @@
+package com.nhn.pinpoint.profiler.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface PinpointAgent {
+ String value();
+}
diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PinpointConfig.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PinpointConfig.java
new file mode 100644
index 000000000..df5d6d208
--- /dev/null
+++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/PinpointConfig.java
@@ -0,0 +1,12 @@
+package com.nhn.pinpoint.profiler.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface PinpointConfig {
+ String value();
+}
diff --git a/test/pom.xml b/test/pom.xml
index ff8171bce..91dfc8865 100644
--- a/test/pom.xml
+++ b/test/pom.xml
@@ -8,7 +8,7 @@
pinpoint-test
- pinpoint test helper libraries
+ pinpoint test helper
jar
@@ -16,6 +16,12 @@
com.nhn.pinpoint
pinpoint-profiler
+
+
+ junit
+ junit
+ compile
+
diff --git a/test/src/main/java/com/nhn/pinpoint/test/fork/ExcludeLibraries.java b/test/src/main/java/com/nhn/pinpoint/test/fork/ExcludeLibraries.java
new file mode 100644
index 000000000..aa0b54156
--- /dev/null
+++ b/test/src/main/java/com/nhn/pinpoint/test/fork/ExcludeLibraries.java
@@ -0,0 +1,12 @@
+package com.nhn.pinpoint.test.fork;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ExcludeLibraries {
+ String[] value() default {};
+}
diff --git a/test/src/main/java/com/nhn/pinpoint/test/fork/ForkRunner.java b/test/src/main/java/com/nhn/pinpoint/test/fork/ForkRunner.java
index 7427c0d21..371b10f58 100644
--- a/test/src/main/java/com/nhn/pinpoint/test/fork/ForkRunner.java
+++ b/test/src/main/java/com/nhn/pinpoint/test/fork/ForkRunner.java
@@ -1,7 +1,9 @@
-package com.nhn.pinpoint.profiler.util;
+package com.nhn.pinpoint.test.fork;
import java.io.File;
import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
@@ -20,19 +22,24 @@ import org.junit.runners.model.Statement;
import com.nhn.pinpoint.common.Version;
public class ForkRunner extends BlockJUnit4ClassRunner {
+ private static final String[] REQUIRED_CLASS_PATHS = new String[] {
+ "junit",
+ "pinpoint-test",
+ "pinpoint/test"
+ };
+
private final String agentJar;
private final String configPath;
+ private final boolean testOnChildClassLoader;
+ private final String[] excludedLibraries;
+ private final String[] includedLibraries;
public ForkRunner(Class> klass) throws InitializationError {
super(klass);
- PinpointAgent path = klass.getAnnotation(PinpointAgent.class);
-
- if (path != null && path.value() != null) {
- agentJar = path.value();
- } else {
- agentJar = "target/pinpoint-agent/pinpoint-bootstrap-" + Version.VERSION + ".jar";
- }
+ PinpointAgentPath path = klass.getAnnotation(PinpointAgentPath.class);
+ String agentPath = (path != null && path.value() != null) ? path.value() : "target/pinpoint-agent";
+ agentJar = agentPath + "/pinpoint-bootstrap-" + Version.VERSION + ".jar";
PinpointConfig config = klass.getAnnotation(PinpointConfig.class);
@@ -41,6 +48,14 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
} else {
configPath = null;
}
+
+ testOnChildClassLoader = klass.isAnnotationPresent(OnChildClassLoader.class);
+
+ ExcludeLibraries exclude = klass.getAnnotation(ExcludeLibraries.class);
+ excludedLibraries = exclude == null ? new String[0] : exclude.value();
+
+ WithLibraries include = klass.getAnnotation(WithLibraries.class);
+ includedLibraries = include == null ? new String[0] : include.value();
}
@Override
@@ -67,6 +82,9 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
builder.command(buildCommand());
builder.redirectErrorStream(true);
+
+ System.out.println("Working directory: " + System.getProperty("user.dir"));
+ System.out.println("Command: " + builder.command());
Process process;
try {
@@ -120,26 +138,44 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
}
}
- private String[] buildCommand() {
+ private String[] buildCommand() throws URISyntaxException {
List list = new ArrayList();
list.add(getJavaExecutable());
list.add("-cp");
list.add(getClassPath());
list.add(getAgent());
+
list.add("-Dpinpoint.agentId=build.test.0");
list.add("-Dpinpoint.applicationName=test");
+
+ if (isDebugMode()) {
+ list.addAll(getDebugOptions());
+ }
if (configPath != null) {
list.add("-Dpinpoint.config=" + configPath);
}
list.add(ForkedJUnit.class.getName());
+
+ if (testOnChildClassLoader) {
+ list.add(getChildClassPath());
+ }
+
list.add(getTestClass().getName());
return list.toArray(new String[list.size()]);
}
-
+
+ private boolean isDebugMode() {
+ return ManagementFactory.getRuntimeMXBean().getInputArguments().toString().contains("jdwp");
+ }
+
+ private List getDebugOptions() {
+ return Arrays.asList("-Xdebug", "-agentlib:jdwp=transport=dt_socket,address=1296,server=y,suspend=y");
+ }
+
private String getAgent() {
return "-javaagent:" + agentJar;
}
@@ -159,19 +195,63 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
return builder.toString();
}
-
- private String getClassPath() {
- URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
+
+ private String getClassPath() throws URISyntaxException {
StringBuilder classPath = new StringBuilder();
- for (URL url : cl.getURLs()) {
- classPath.append(url.getPath());
- classPath.append(File.pathSeparatorChar);
+ if (testOnChildClassLoader) {
+ URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
+
+ outer:
+ for (URL url : cl.getURLs()) {
+ for (String required : REQUIRED_CLASS_PATHS) {
+ if (url.getFile().contains(required)) {
+ classPath.append(new File(url.toURI()).getAbsolutePath());
+ classPath.append(File.pathSeparatorChar);
+ continue outer;
+ }
+ }
+ }
+ } else {
+ appendClassPath(classPath);
}
return classPath.toString();
}
+
+ private void appendClassPath(StringBuilder classPath) throws URISyntaxException {
+ URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader();
+
+ outer:
+ for (URL url : cl.getURLs()) {
+ String urlAsString = url.toString();
+ for (String exclude : excludedLibraries) {
+ if (urlAsString.contains(exclude)) {
+ continue outer;
+ }
+ }
+
+ classPath.append(new File(url.toURI()).getAbsolutePath());
+ classPath.append(File.pathSeparatorChar);
+ }
+
+ for (String include : includedLibraries) {
+ classPath.append(include);
+ classPath.append(File.pathSeparatorChar);
+ }
+
+ }
+
+ private String getChildClassPath() throws URISyntaxException {
+ StringBuilder classPath = new StringBuilder();
+
+ classPath.append(ForkedJUnit.CHILD_CLASS_PATH_PREFIX);
+ appendClassPath(classPath);
+
+ return classPath.toString();
+ }
+
private Description findDescription(Description description, String displayName) {
if (displayName.equals(description.getDisplayName())) {
return description;
@@ -201,7 +281,6 @@ public class ForkRunner extends BlockJUnit4ClassRunner {
for (int i = 0; i < traceInText.size(); i++) {
String trace = traceInText.get(i);
- System.out.println(trace);
String[] tokens = trace.split(",");
stackTrace[i] = new StackTraceElement(tokens[0], tokens[1], tokens[2], Integer.valueOf(tokens[3]));
diff --git a/test/src/main/java/com/nhn/pinpoint/test/fork/ForkedJUnit.java b/test/src/main/java/com/nhn/pinpoint/test/fork/ForkedJUnit.java
index b98b26ce9..b3309fe2a 100644
--- a/test/src/main/java/com/nhn/pinpoint/test/fork/ForkedJUnit.java
+++ b/test/src/main/java/com/nhn/pinpoint/test/fork/ForkedJUnit.java
@@ -1,5 +1,12 @@
-package com.nhn.pinpoint.profiler.util;
+package com.nhn.pinpoint.test.fork;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import java.util.regex.Pattern;
import org.junit.runner.Description;
@@ -9,6 +16,7 @@ import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
public class ForkedJUnit {
+ static final String CHILD_CLASS_PATH_PREFIX = "-child=";
static final String JUNIT_OUTPUT_DELIMETER = "#####";
static final String JUNIT_OUTPUT_DELIMETER_REGEXP = Pattern.quote(JUNIT_OUTPUT_DELIMETER);
private static boolean forked = false;
@@ -18,21 +26,61 @@ public class ForkedJUnit {
}
- public static void main(String[] args) throws ClassNotFoundException {
+ public static void main(String[] args) throws ClassNotFoundException, MalformedURLException {
forked = true;
- Class>[] classes = new Class>[args.length];
+ int from = 0;
+ ClassLoader classLoader = ClassLoader.getSystemClassLoader();
- for (int i = 0; i < args.length; i++) {
- classes[i] = Class.forName(args[i]);
+ if (args[0].startsWith(CHILD_CLASS_PATH_PREFIX)) {
+ String jars = args[0].substring(CHILD_CLASS_PATH_PREFIX.length());
+ List urls = getJarUrls(jars);
+ classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]), classLoader);
+ from = 1;
}
- JUnitCore junit = new JUnitCore();
- junit.addListener(new PrintListener());
- Result result = junit.run(classes);
+ List testClassNames = Arrays.asList(args).subList(from, args.length);
+ List> classes = loadTestClasses(classLoader, testClassNames);
+
+ Result result = runTests(classes);
System.exit(result.getFailureCount());
}
+
+
+ private static Result runTests(List> classes) {
+ JUnitCore junit = new JUnitCore();
+ junit.addListener(new PrintListener());
+ Result result = junit.run(classes.toArray(new Class>[classes.size()]));
+ return result;
+ }
+
+
+ private static List getJarUrls(String jars) throws MalformedURLException {
+ String[] tokens = jars.split(File.pathSeparator);
+
+ List urls = new ArrayList(tokens.length);
+ for (String token : tokens) {
+ File file = new File(token);
+ urls.add(file.toURI().toURL());
+ }
+ return urls;
+ }
+
+
+ private static List> loadTestClasses(ClassLoader classLoader, List testClassNames) throws ClassNotFoundException {
+ List> classes = new ArrayList>(testClassNames.size());
+
+ ClassLoader old = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ for (String testClassName : testClassNames) {
+ classes.add(classLoader.loadClass(testClassName));
+ }
+
+ Thread.currentThread().setContextClassLoader(old);
+ return classes;
+ }
private static class PrintListener extends RunListener {
diff --git a/test/src/main/java/com/nhn/pinpoint/test/fork/OnChildClassLoader.java b/test/src/main/java/com/nhn/pinpoint/test/fork/OnChildClassLoader.java
new file mode 100644
index 000000000..09f9bf959
--- /dev/null
+++ b/test/src/main/java/com/nhn/pinpoint/test/fork/OnChildClassLoader.java
@@ -0,0 +1,11 @@
+package com.nhn.pinpoint.test.fork;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface OnChildClassLoader {
+}
diff --git a/test/src/main/java/com/nhn/pinpoint/test/fork/PinpointAgentPath.java b/test/src/main/java/com/nhn/pinpoint/test/fork/PinpointAgentPath.java
index 7fc6da228..54185919b 100644
--- a/test/src/main/java/com/nhn/pinpoint/test/fork/PinpointAgentPath.java
+++ b/test/src/main/java/com/nhn/pinpoint/test/fork/PinpointAgentPath.java
@@ -1,4 +1,4 @@
-package com.nhn.pinpoint.profiler.util;
+package com.nhn.pinpoint.test.fork;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -7,6 +7,6 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
-public @interface PinpointAgent {
- String value();
+public @interface PinpointAgentPath {
+ String value() default "target/pinpoint-agent";
}
diff --git a/test/src/main/java/com/nhn/pinpoint/test/fork/PinpointConfig.java b/test/src/main/java/com/nhn/pinpoint/test/fork/PinpointConfig.java
index df5d6d208..86063829c 100644
--- a/test/src/main/java/com/nhn/pinpoint/test/fork/PinpointConfig.java
+++ b/test/src/main/java/com/nhn/pinpoint/test/fork/PinpointConfig.java
@@ -1,4 +1,4 @@
-package com.nhn.pinpoint.profiler.util;
+package com.nhn.pinpoint.test.fork;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/test/src/main/java/com/nhn/pinpoint/test/fork/WithLibraries.java b/test/src/main/java/com/nhn/pinpoint/test/fork/WithLibraries.java
new file mode 100644
index 000000000..e3a26504d
--- /dev/null
+++ b/test/src/main/java/com/nhn/pinpoint/test/fork/WithLibraries.java
@@ -0,0 +1,12 @@
+package com.nhn.pinpoint.test.fork;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface WithLibraries {
+ String[] value() default {};
+}