This is an automated email from the ASF dual-hosted git repository. wujimin pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git
commit dac247e48329d07ab7cd6c43da600145704c98ca Author: wujimin <wuji...@huawei.com> AuthorDate: Thu May 10 15:24:33 2018 +0800 [SCB-532] convert CtClass to fake JavaType, and JavassistUtils extract return CtClass method --- .../servicecomb/common/javassist/CtType.java | 12 +++++ .../common/javassist/CtTypeJavaType.java | 52 ++++++++++++++++++++++ .../common/javassist/JavassistUtils.java | 45 +++++++++++++++++-- .../servicecomb/common/javassist/TestCtType.java | 25 +++++++++++ .../common/javassist/TestCtTypeJavaType.java | 48 ++++++++++++++++++++ 5 files changed, 178 insertions(+), 4 deletions(-) diff --git a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/CtType.java b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/CtType.java index d0da1e0..4c53818 100644 --- a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/CtType.java +++ b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/CtType.java @@ -22,6 +22,7 @@ import javassist.ClassPool; import javassist.CtClass; import javassist.CtPrimitiveType; import javassist.NotFoundException; +import javassist.bytecode.SignatureAttribute.ClassType; public class CtType { private static final ClassPool PRIMITIVE_CLASSPOOL = JavassistUtils.getOrCreateClassPool(int.class.getClassLoader()); @@ -32,11 +33,22 @@ public class CtType { private String genericSignature; + public CtType(CtClass ctClass) { + ClassType classType = new ClassType(ctClass.getName(), null); + init(ctClass, false, classType.encode()); + } + public CtType(CtClass ctClass, boolean hasGenericTypes, String genericSignature) { init(ctClass, hasGenericTypes, genericSignature); } public CtType(JavaType javaType) { + if (CtTypeJavaType.class.isInstance(javaType)) { + CtType ctType = ((CtTypeJavaType) javaType).getType(); + init(ctType.ctClass, ctType.hasGenericTypes, ctType.genericSignature); + return; + } + ClassLoader classLoader = javaType.getRawClass().getClassLoader(); try { ClassPool classPool = JavassistUtils.getOrCreateClassPool(classLoader); diff --git a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/CtTypeJavaType.java b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/CtTypeJavaType.java new file mode 100644 index 0000000..6e03bd9 --- /dev/null +++ b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/CtTypeJavaType.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.common.javassist; + +import com.fasterxml.jackson.databind.type.SimpleType; + +/** + * just a wrapper for CtType + * pending create class from CtClass to support recursive dependency class + */ +public class CtTypeJavaType extends SimpleType { + private CtType type; + + public CtTypeJavaType(CtType type) { + super(CtTypeJavaType.class); + this.type = type; + } + + public CtType getType() { + return type; + } + + @Override + protected String buildCanonicalName() { + return type.getCtClass().getName(); + } + + @Override + public String getGenericSignature() { + return type.getGenericSignature(); + } + + + @Override + public StringBuilder getGenericSignature(StringBuilder sb) { + return sb.append(type.getGenericSignature()); + } +} diff --git a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java index 025ea94..66bb661 100644 --- a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java +++ b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java @@ -139,7 +139,7 @@ public final class JavassistUtils { return createClass(null, config); } - public static Class<?> createClass(ClassLoader classLoader, ClassConfig config) { + public static CtClass createCtClass(ClassLoader classLoader, ClassConfig config) { if (classLoader == null) { classLoader = Thread.currentThread().getContextClassLoader(); } @@ -185,10 +185,47 @@ public final class JavassistUtils { } } - LOGGER.info("generate {} in classLoader {}.", config.getClassName(), classLoader); - return ctClass.toClass(classLoader, null); + LOGGER.info("create CtClass {} in classLoader {}.", config.getClassName(), classLoader); + return ctClass; + } catch (Throwable e) { + throw new IllegalStateException( + String.format("Failed to create CtClass %s in classLoader %s.", config.getClassName(), + classLoader), e); + } + } + + public static Class<?> createClass(ClassLoader classLoader, ClassConfig config) { + if (classLoader == null) { + classLoader = Thread.currentThread().getContextClassLoader(); + } + + CtClass ctClass = createCtClass(classLoader, config); + return createClass(classLoader, ctClass); + } + + public static Class<?> createClass(ClassLoader classLoader, CtClass ctClass) { + if (classLoader == null) { + classLoader = Thread.currentThread().getContextClassLoader(); + } + + String clsName = ctClass.getName(); + try { + // must try load from classloader first + // because class A depend on class B + // when load class A, will load class B + // after this, if CtClass B invoke toClass again, will cause problem. + return classLoader.loadClass(clsName); + } catch (ClassNotFoundException e) { + // ignore it + } + + try { + Class<?> cls = ctClass.toClass(classLoader, null); + LOGGER.info("create class {} in classLoader {}.", clsName, classLoader); + return cls; } catch (Throwable e) { - throw new Error(String.format("Failed to create %s in classLoader %s.", config.getClassName(), classLoader), e); + throw new IllegalStateException( + String.format("Failed to create %s in classLoader %s.", clsName, classLoader), e); } } diff --git a/common/common-javassist/src/test/java/org/apache/servicecomb/common/javassist/TestCtType.java b/common/common-javassist/src/test/java/org/apache/servicecomb/common/javassist/TestCtType.java index 40ecd7b..1bf1907 100644 --- a/common/common-javassist/src/test/java/org/apache/servicecomb/common/javassist/TestCtType.java +++ b/common/common-javassist/src/test/java/org/apache/servicecomb/common/javassist/TestCtType.java @@ -25,6 +25,7 @@ import org.mockito.Mockito; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.type.TypeFactory; +import javassist.ClassPool; import javassist.CtClass; import javassist.NotFoundException; @@ -34,6 +35,17 @@ public class TestCtType { @Test public void fromCtClass() { CtClass ctClass = Mockito.mock(CtClass.class); + Mockito.when(ctClass.getName()).thenReturn("a.b.c"); + ctType = new CtType(ctClass); + + Assert.assertSame(ctClass, ctType.getCtClass()); + Assert.assertFalse(ctType.hasGenericTypes()); + Assert.assertEquals("La/b/c;", ctType.getGenericSignature()); + } + + @Test + public void fromCtClass_fullInfo() { + CtClass ctClass = Mockito.mock(CtClass.class); ctType = new CtType(ctClass, true, "Ljava/util/List<[B;>;"); Assert.assertSame(ctClass, ctType.getCtClass()); @@ -87,4 +99,17 @@ public class TestCtType { Assert.assertTrue(ctType.hasGenericTypes()); Assert.assertEquals("Ljava/util/List<[B>;", ctType.getGenericSignature()); } + + @Test + public void fromCtTypeJavaType() throws NotFoundException { + CtClass ctClass = ClassPool.getDefault().get(String.class.getCanonicalName()); + CtType otherCtType = new CtType(ctClass, false, "Ljava/lang/String;"); + CtTypeJavaType ctTypeJavaType = new CtTypeJavaType(otherCtType); + + ctType = new CtType(ctTypeJavaType); + + Assert.assertSame(ctClass, ctType.getCtClass()); + Assert.assertFalse(ctType.hasGenericTypes()); + Assert.assertEquals("Ljava/lang/String;", ctType.getGenericSignature()); + } } diff --git a/common/common-javassist/src/test/java/org/apache/servicecomb/common/javassist/TestCtTypeJavaType.java b/common/common-javassist/src/test/java/org/apache/servicecomb/common/javassist/TestCtTypeJavaType.java new file mode 100644 index 0000000..46213a3 --- /dev/null +++ b/common/common-javassist/src/test/java/org/apache/servicecomb/common/javassist/TestCtTypeJavaType.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.servicecomb.common.javassist; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.type.TypeFactory; + +public class TestCtTypeJavaType { + Class<?> cls = TestCtTypeJavaType.class; + + JavaType javaType = TypeFactory.defaultInstance().constructType(cls); + + CtType ctType = new CtType(javaType); + + CtTypeJavaType ctTypeJavaType = new CtTypeJavaType(ctType); + + @Test + public void construct() { + Assert.assertSame(ctType, ctTypeJavaType.getType()); + Assert.assertEquals(cls.getTypeName(), ctTypeJavaType.buildCanonicalName()); + } + + @Test + public void getGenericSignature() { + JavaType listJavaType = TypeFactory.defaultInstance().constructCollectionType(List.class, ctTypeJavaType); + Assert.assertEquals("Ljava/util/List<Lorg/apache/servicecomb/common/javassist/TestCtTypeJavaType;>;", + listJavaType.getGenericSignature()); + } +} -- To stop receiving notification emails like this one, please contact wuji...@apache.org.