diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/DeclaredMethodsForce.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/DeclaredMethodsForce.java new file mode 100644 index 000000000..57ecafa02 --- /dev/null +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/interceptor/bci/DeclaredMethodsForce.java @@ -0,0 +1,41 @@ +package com.nhn.pinpoint.profiler.interceptor.bci; + +import java.util.List; + +/** + * @author emeroad + */ +public class DeclaredMethodsForce { + + private final List declaredMethods; + + private final List failDeclaredMethods; + + public DeclaredMethodsForce(List successMethod, List failDeclaredMethods) { + this.declaredMethods = successMethod; + this.failDeclaredMethods = failDeclaredMethods; + } + + public List getDeclaredMethods() { + return declaredMethods; + } + + public List getFailDeclaredMethods() { + return failDeclaredMethods; + } + + public static class FailMethod extends Method { + + private final Throwable caused; + + public FailMethod(String methodName, String[] methodParams, Throwable caused) { + super(methodName, methodParams); + this.caused = caused; + } + + public Throwable getCaused() { + return caused; + } + + } +} diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java index 5a6e8f259..65cfab441 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/DefaultModifierRegistry.java @@ -60,13 +60,19 @@ import com.nhn.pinpoint.profiler.modifier.orm.ibatis.SqlMapClientImplModifier; import com.nhn.pinpoint.profiler.modifier.orm.ibatis.SqlMapSessionImplModifier; import com.nhn.pinpoint.profiler.modifier.orm.mybatis.DefaultSqlSessionModifier; import com.nhn.pinpoint.profiler.modifier.orm.mybatis.SqlSessionTemplateModifier; +import com.nhn.pinpoint.profiler.modifier.redis.BinaryJedisModifier; +import com.nhn.pinpoint.profiler.modifier.redis.BinaryRedisClusterModifier; +import com.nhn.pinpoint.profiler.modifier.redis.BinaryTriplesRedisClusterModifier; import com.nhn.pinpoint.profiler.modifier.redis.GatewayModifier; import com.nhn.pinpoint.profiler.modifier.redis.GatewayServerModifier; import com.nhn.pinpoint.profiler.modifier.redis.JedisClientModifier; import com.nhn.pinpoint.profiler.modifier.redis.JedisModifier; +import com.nhn.pinpoint.profiler.modifier.redis.JedisMultiKeyPipelineBaseModifier; +import com.nhn.pinpoint.profiler.modifier.redis.JedisPipelineBaseModifier; import com.nhn.pinpoint.profiler.modifier.redis.JedisPipelineModifier; import com.nhn.pinpoint.profiler.modifier.redis.RedisClusterModifier; import com.nhn.pinpoint.profiler.modifier.redis.RedisClusterPipelineModifier; +import com.nhn.pinpoint.profiler.modifier.redis.TriplesRedisClusterModifier; import com.nhn.pinpoint.profiler.modifier.servlet.HttpServletModifier; import com.nhn.pinpoint.profiler.modifier.servlet.SpringFrameworkServletModifier; import com.nhn.pinpoint.profiler.modifier.spring.beans.AbstractAutowireCapableBeanFactoryModifier; @@ -384,11 +390,14 @@ public class DefaultModifierRegistry implements ModifierRegistry { public void addRedisSupport() { if(profilerConfig.isRedisEnabled()) { + addModifier(new BinaryJedisModifier(byteCodeInstrumentor, agent)); addModifier(new JedisModifier(byteCodeInstrumentor, agent)); } if(profilerConfig.isRedisPipelineEnabled()) { addModifier(new JedisClientModifier(byteCodeInstrumentor, agent)); + addModifier(new JedisPipelineBaseModifier(byteCodeInstrumentor, agent)); + addModifier(new JedisMultiKeyPipelineBaseModifier(byteCodeInstrumentor, agent)); addModifier(new JedisPipelineModifier(byteCodeInstrumentor, agent)); } } @@ -400,6 +409,9 @@ public class DefaultModifierRegistry implements ModifierRegistry { if(profilerConfig.isNbaseArcEnabled()) { addModifier(new RedisClusterModifier(byteCodeInstrumentor, agent)); + addModifier(new BinaryRedisClusterModifier(byteCodeInstrumentor, agent)); + addModifier(new TriplesRedisClusterModifier(byteCodeInstrumentor, agent)); + addModifier(new BinaryTriplesRedisClusterModifier(byteCodeInstrumentor, agent)); } if(profilerConfig.isNbaseArcPipelineEnabled()) { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/GatewayModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/GatewayModifier.java index 6958cd528..913a78a3e 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/GatewayModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/GatewayModifier.java @@ -61,7 +61,7 @@ public class GatewayModifier extends AbstractModifier { return instrumentClass.toBytecode(); } catch (Exception e) { if (logger.isWarnEnabled()) { - logger.warn("redis.GatewayModifier(nBase-ARC) fail. Target class is " + getTargetClass() + ", Caused " + e.getMessage(), e); + logger.warn("Failed to modifier. caused={}", e.getMessage(), e); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/GatewayServerModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/GatewayServerModifier.java index 1d64d09f7..9d33b4158 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/GatewayServerModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/GatewayServerModifier.java @@ -59,7 +59,7 @@ public class GatewayServerModifier extends AbstractModifier { return instrumentClass.toBytecode(); } catch (Exception e) { if (logger.isWarnEnabled()) { - logger.warn("redis.GatewayServerModifier(nBase-ARC) fail. Target class is " + getTargetClass() + ", Caused " + e.getMessage(), e); + logger.warn("Failed to modifier. caused={}", e.getMessage(), e); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisClientModifier.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisClientModifier.java index c87c5ac7d..7efb21261 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisClientModifier.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisClientModifier.java @@ -52,7 +52,7 @@ public class JedisClientModifier extends AbstractModifier { return instrumentClass.toBytecode(); } catch (Exception e) { if (logger.isWarnEnabled()) { - logger.warn("redis.JedisClientModifier(Jedis) fail. Target class is " + getTargetClass() + ". Caused " + e.getMessage(), e); + logger.warn("Failed to modifier. caused={}", e.getMessage(), e); } } diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/filter/NameBasedMethodFilter.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/filter/NameBasedMethodFilter.java index fb9f3d05c..b6878c6ff 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/filter/NameBasedMethodFilter.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/filter/NameBasedMethodFilter.java @@ -13,16 +13,18 @@ import com.nhn.pinpoint.bootstrap.instrument.MethodFilter; * */ public class NameBasedMethodFilter implements MethodFilter { + private static final int SYNTHETIC = 0x00001000; private final Set methodNames; - - public NameBasedMethodFilter(Set methodNames) { + + public NameBasedMethodFilter(final Set methodNames) { this.methodNames = methodNames; } - + @Override public boolean filter(MethodInfo ctMethod) { final int modifiers = ctMethod.getModifiers(); - if (!Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + + if (isSynthetic(modifiers) || !Modifier.isPublic(modifiers) || Modifier.isStatic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { return true; } @@ -32,4 +34,8 @@ public class NameBasedMethodFilter implements MethodFilter { return true; } + + private boolean isSynthetic(int mod) { + return (mod & SYNTHETIC) != 0; + } } \ No newline at end of file diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/GatewayConstructorInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/GatewayConstructorInterceptor.java index 86d7b0aec..4eb46a069 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/GatewayConstructorInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/GatewayConstructorInterceptor.java @@ -11,8 +11,7 @@ import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; import com.nhncorp.redis.cluster.gateway.GatewayConfig; /** - * Gateway(nBase-ARC client) constructor interceptor - * - trace destinationId + * Gateway(nBase-ARC client) constructor interceptor - trace destinationId * * @author jaehong.kim * @@ -43,8 +42,11 @@ public class GatewayConstructorInterceptor implements SimpleAroundInterceptor, T // over 1.1.x traceValue.put("destinationId", config.getClusterName()); } - } catch (Exception ignored) { + } catch (Exception e) { // backward compatibility error or expect 'class not found exception - GatewayConfig' + if (logger.isWarnEnabled()) { + logger.warn("Failed to trace destinationId('not found getClusterName' is compatibility error). caused={}", e.getMessage(), e); + } } ((MapTraceValue) target).__setTraceBindValue(traceValue); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/JedisConstructorInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/JedisConstructorInterceptor.java index c81e8d51c..c190e468f 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/JedisConstructorInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/JedisConstructorInterceptor.java @@ -58,8 +58,11 @@ public class JedisConstructorInterceptor implements SimpleAroundInterceptor, Tar endPoint.append(":"); endPoint.append(info.getPort()); } - } catch (Exception ignored) { + } catch (Exception e) { // expect 'class not found exception - JedisShardInfo' + if (logger.isWarnEnabled()) { + logger.warn("Failed to trace endPoint('not found JedisShardInfo' is compatibility error). caused={}", e.getMessage(), e); + } } final Map traceValue = new HashMap(); diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/RedisClusterPipelineConstructorInterceptor.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/RedisClusterPipelineConstructorInterceptor.java index ef2b1f90e..3458779ee 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/RedisClusterPipelineConstructorInterceptor.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/modifier/redis/interceptor/RedisClusterPipelineConstructorInterceptor.java @@ -11,8 +11,7 @@ import com.nhn.pinpoint.bootstrap.logging.PLoggerFactory; import com.nhncorp.redis.cluster.gateway.GatewayServer; /** - * RedisCluster pipeline(nBase-ARC client) constructor interceptor - * - trace destinationId & endPoint + * RedisCluster pipeline(nBase-ARC client) constructor interceptor - trace destinationId & endPoint * * @author jaehong.kim * @@ -39,8 +38,11 @@ public class RedisClusterPipelineConstructorInterceptor implements SimpleAroundI try { final GatewayServer server = (GatewayServer) args[0]; traceValue.put("endPoint", server.getAddress().getHost() + ":" + server.getAddress().getPort()); - } catch(Exception ignored) { + } catch (Exception e) { // expect 'class not found exception - GatewayServer' + if (logger.isWarnEnabled()) { + logger.warn("Failed to trace endPoint('not found GatewayServer' is compatibility error). caused={}", e.getMessage(), e); + } } if (args[0] instanceof MapTraceValue) { diff --git a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtils.java b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtils.java index dc8bb4312..c2ef05ae2 100644 --- a/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtils.java +++ b/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtils.java @@ -41,8 +41,137 @@ public final class JavaAssistUtils { return sb.toString(); } + public static String[] parseParameterDescriptor(String descriptor) { + if (descriptor == null) { + throw new NullPointerException("descriptor must not be null"); + } + final String[] parameterDesc = splitParameterDesc(descriptor); + final String[] objectType = new String[parameterDesc.length]; + for (int i = 0; i < parameterDesc.length; i++) { + String description = parameterDesc[i]; + objectType[i] = byteCodeDescToObjectType(description); + } + return objectType; + } - public static String[] getParameterType(Class[] paramsClass) { + private static String byteCodeDescToObjectType(String description) { + final char scheme = description.charAt(0); + switch (scheme) { + case 'B': + return "byte"; + case 'C': + return "char"; + case 'D': + return "double"; + case 'F': + return "float"; + case 'I': + return "int"; + case 'J': + return "long"; + case 'S': + return "short"; + case 'V': + return "void"; + case 'Z': + return "boolean"; + case 'L': + return toObjectType(description, 1); + case '[': { + return toArrayType(description); + } + } + throw new IllegalArgumentException("invalid description :" + description); + } + + private static String toArrayType(String description) { + final int arraySize = getArraySize(description); + + final char scheme = description.charAt(arraySize); + switch (scheme) { + case 'B': + return arrayType("byte", arraySize); + case 'C': + return arrayType("char", arraySize); + case 'D': + return arrayType("double", arraySize); + case 'F': + return arrayType("float", arraySize); + case 'I': + return arrayType("int", arraySize); + case 'J': + return arrayType("long", arraySize); + case 'S': + return arrayType("short", arraySize); + case 'V': + return arrayType("void", arraySize); + case 'Z': + return arrayType("boolean", arraySize); + case 'L': + final String objectType = toObjectType(description, arraySize + 1); + return arrayType(objectType, arraySize); + case '[': { + throw new IllegalArgumentException("invalid description" + description); + } + } + throw new IllegalArgumentException("invalid description :" + description); + } + + private static String arrayType(String objectType, int arraySize) { + final String array = "[]"; + final int arrayStringLength = array.length() * arraySize; + StringBuilder sb = new StringBuilder(objectType.length() + arrayStringLength); + sb.append(objectType); + for (int i = 0; i < arraySize; i++) { + sb.append(array); + } + return sb.toString(); + } + + private static int getArraySize(String description) { + int arraySize = 0; + for (int i = 0; i < description.length(); i++) { + final char c = description.charAt(i); + if (c == '[') { + arraySize++; + } else { + break; + } + } + return arraySize; + } + + private static String toObjectType(String description, int startIndex) { + final String assistClass = description.substring(startIndex, description.length()); + final String objectName = assistClass.replace('/', '.'); + if (objectName.isEmpty()) { + throw new IllegalArgumentException("invalid description. objectName not found :" + description); + } + return objectName; + } + + private static String[] splitParameterDesc(String descriptor) { + final String parameterDesc = getParameterDesc(descriptor); + if (parameterDesc.isEmpty()) { + return EMPTY_STRING_ARRAY; + } + return parameterDesc.split(";"); + } + + + private static String getParameterDesc(String descriptor) { + final int start = descriptor.indexOf('('); + if (start == -1) { + throw new IllegalArgumentException("'(' not found. descriptor:" + descriptor); + } + final int end = descriptor.indexOf(')', start + 1); + if (end == -1) { + throw new IllegalArgumentException("')' not found. descriptor:" + descriptor); + } + return descriptor.substring(start + 1, end); + } + + public static String[] getParameterType(Class[] paramsClass) { if (paramsClass == null) { return null; } diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisModifierTest.java index 70c71ceac..f764dd22c 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisModifierTest.java @@ -50,6 +50,22 @@ public class JedisModifierTest extends BasePinpointTest { assertNull(event.getExceptionMessage()); } + @Test + public void traceBinaryMethod() { + // get 명령을 실행하고 event 결과를 확인한다. + jedis.get("foo".getBytes()); + + final List spanEvents = getCurrentSpanEvents(); + assertEquals(1, spanEvents.size()); + SpanEventBo event = spanEvents.get(0); + + assertEquals(HOST + ":" + PORT, event.getEndPoint()); + assertEquals("REDIS", event.getDestinationId()); + assertEquals(ServiceType.REDIS, event.getServiceType()); + assertNull(event.getExceptionMessage()); + } + + @Test public void traceMethodThrowException() { // 에러가 발생한 경우에 대한 event 결과를 확인한다. @@ -66,4 +82,4 @@ public class JedisModifierTest extends BasePinpointTest { assertNotNull(event.getExceptionMessage()); } -} +} \ No newline at end of file diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisPipelineModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisPipelineModifierTest.java index ab1824e52..e8c09037e 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisPipelineModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/JedisPipelineModifierTest.java @@ -37,7 +37,25 @@ public class JedisPipelineModifierTest extends BasePinpointTest { } @Test - public void traceMethod() { + public void traceMultikeyMethod() { + // get 명령을 실행하고 event 결과를 확인한다. + Pipeline pipeline = jedis.pipelined(); + pipeline.mget("foo"); + pipeline.syncAndReturnAll(); + + final List spanEvents = getCurrentSpanEvents(); + assertEquals(2, spanEvents.size()); + SpanEventBo event = spanEvents.get(0); + + System.out.println(event); + assertEquals(HOST + ":" + PORT, event.getEndPoint()); + assertEquals("REDIS", event.getDestinationId()); + assertEquals(ServiceType.REDIS, event.getServiceType()); + assertNull(event.getExceptionMessage()); + } + + @Test + public void traceBaseMethod() { // get 명령을 실행하고 event 결과를 확인한다. Pipeline pipeline = jedis.pipelined(); pipeline.get("foo"); @@ -46,13 +64,14 @@ public class JedisPipelineModifierTest extends BasePinpointTest { final List spanEvents = getCurrentSpanEvents(); assertEquals(2, spanEvents.size()); SpanEventBo event = spanEvents.get(0); - + System.out.println(event); assertEquals(HOST + ":" + PORT, event.getEndPoint()); assertEquals("REDIS", event.getDestinationId()); assertEquals(ServiceType.REDIS, event.getServiceType()); assertNull(event.getExceptionMessage()); } + @Test public void traceMethodThrowException() { // 에러가 발생한 경우에 대한 event 결과를 확인한다. diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/RedisClusterModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/RedisClusterModifierTest.java index d52d968bf..019319dc5 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/RedisClusterModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/RedisClusterModifierTest.java @@ -29,7 +29,6 @@ public class RedisClusterModifierTest extends BasePinpointTest { @Before public void before() { redis = new RedisCluster(HOST, PORT); - } @Test @@ -45,6 +44,20 @@ public class RedisClusterModifierTest extends BasePinpointTest { assertEquals(ServiceType.NBASE_ARC, event.getServiceType()); assertNull(event.getExceptionMessage()); } + + @Test + public void traceBinaryMethod() { + redis.get("foo".getBytes()); + + final List spanEvents = getCurrentSpanEvents(); + assertEquals(1, spanEvents.size()); + SpanEventBo event = spanEvents.get(0); + + assertEquals("NBASE_ARC", event.getDestinationId()); + assertEquals(HOST + ":" + PORT, event.getEndPoint()); + assertEquals(ServiceType.NBASE_ARC, event.getServiceType()); + assertNull(event.getExceptionMessage()); + } @Test public void traceDestinationId() { diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/RedisClusterPipelineModifierTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/RedisClusterPipelineModifierTest.java index e067e2e05..f546bc9e4 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/RedisClusterPipelineModifierTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/modifier/redis/RedisClusterPipelineModifierTest.java @@ -51,6 +51,25 @@ public class RedisClusterPipelineModifierTest extends BasePinpointTest { assertNull(event.getExceptionMessage()); } + @Test + public void traceBinaryMethod() { + pipeline.get("foo".getBytes()); + pipeline.syncAndReturnAll(); + + final List spanEvents = getCurrentSpanEvents(); + for (SpanEventBo bo : spanEvents) { + System.out.println("### " + bo); + } + + assertEquals(2, spanEvents.size()); + SpanEventBo event = spanEvents.get(0); + + assertEquals("NBASE_ARC", event.getDestinationId()); + assertEquals(HOST + ":" + PORT, event.getEndPoint()); + assertEquals(ServiceType.NBASE_ARC, event.getServiceType()); + assertNull(event.getExceptionMessage()); + } + @Test public void traceDestinationId() { GatewayConfig config = new GatewayConfig(); diff --git a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtilsTest.java b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtilsTest.java index b7b39109b..d04d32b3e 100644 --- a/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtilsTest.java +++ b/profiler/src/test/java/com/navercorp/pinpoint/profiler/util/JavaAssistUtilsTest.java @@ -33,8 +33,39 @@ public class JavaAssistUtilsTest { String clsDescription = JavaAssistUtils.getParameterDescription(new Class[]{int.class}); logger.info(clsDescription); Assert.assertEquals(ctDescription, clsDescription); + } + @Test + public void testParseParameterDescriptor() throws Exception { + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("()V"), new String[]{}); + + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(I)I"), new String[]{"int"}); + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(I;D)I"), new String[]{"int", "double"}); + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(B;F;S)I"), new String[]{"byte", "float", "short"}); + + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(Ljava/lang/String)I"), new String[]{"java.lang.String"}); + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(Ljava/lang/String;J)I"), new String[]{"java.lang.String", "long"}); + + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(J;Ljava/lang/Object;Z)I"), new String[]{"long", "java.lang.Object", "boolean"}); + + } + + @Test + public void testParseParameterDescriptor_array() throws Exception { + + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([I)I"), new String[]{"int[]"}); + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([I;J)I"), new String[]{"int[]", "long"}); + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([J;[I)I"), new String[]{"long[]", "int[]"}); + + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([Ljava/lang/String)"), new String[]{"java.lang.String[]"}); + + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(Ljava/lang/String;[[J)"), new String[]{"java.lang.String", "long[][]"}); + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("(Ljava/lang/Object;[[Ljava/lang/String)"), new String[]{"java.lang.Object", "java.lang.String[][]"}); + + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([[[Ljava/lang/String)"), new String[]{"java.lang.String[][][]"}); + + Assert.assertArrayEquals(JavaAssistUtils.parseParameterDescriptor("([[[I)"), new String[]{"int[][][]"}); } @Test