Search in sources :

Example 76 with CtConstructor

use of javassist.CtConstructor in project UniverseCore by EB-wilson.

the class Expr method where.

/**
 * Returns the constructor or method containing the expression.
 */
public CtBehavior where() {
    MethodInfo mi = thisMethod;
    CtBehavior[] cb = thisClass.getDeclaredBehaviors();
    for (int i = cb.length - 1; i >= 0; --i) if (cb[i].getMethodInfo2() == mi)
        return cb[i];
    CtConstructor init = thisClass.getClassInitializer();
    if (init != null && init.getMethodInfo2() == mi)
        return init;
    /* getDeclaredBehaviors() returns a list of methods/constructors.
         * Although the list is cached in a CtClass object, it might be
         * recreated for some reason.  Thus, the member name and the signature
         * must be also checked.
         */
    for (int i = cb.length - 1; i >= 0; --i) {
        if (thisMethod.getName().equals(cb[i].getMethodInfo2().getName()) && thisMethod.getDescriptor().equals(cb[i].getMethodInfo2().getDescriptor())) {
            return cb[i];
        }
    }
    throw new RuntimeException("fatal: not found");
}
Also used : CtBehavior(javassist.CtBehavior) MethodInfo(javassist.bytecode.MethodInfo) CtConstructor(javassist.CtConstructor)

Example 77 with CtConstructor

use of javassist.CtConstructor in project skywalking by apache.

the class OALRuntime method generateMetricsClass.

/**
 * Generate metrics class, and inject it to classloader
 */
private Class generateMetricsClass(AnalysisResult metricsStmt) throws OALCompileException {
    String className = metricsClassName(metricsStmt, false);
    CtClass parentMetricsClass = null;
    try {
        parentMetricsClass = classPool.get(METRICS_FUNCTION_PACKAGE + metricsStmt.getMetricsClassName());
    } catch (NotFoundException e) {
        log.error("Can't find parent class for " + className + ".", e);
        throw new OALCompileException(e.getMessage(), e);
    }
    CtClass metricsClass = classPool.makeClass(metricsClassName(metricsStmt, true), parentMetricsClass);
    try {
        metricsClass.addInterface(classPool.get(WITH_METADATA_INTERFACE));
    } catch (NotFoundException e) {
        log.error("Can't find WithMetadata interface for " + className + ".", e);
        throw new OALCompileException(e.getMessage(), e);
    }
    ClassFile metricsClassClassFile = metricsClass.getClassFile();
    ConstPool constPool = metricsClassClassFile.getConstPool();
    /**
     * Create empty construct
     */
    try {
        CtConstructor defaultConstructor = CtNewConstructor.make("public " + className + "() {}", metricsClass);
        metricsClass.addConstructor(defaultConstructor);
    } catch (CannotCompileException e) {
        log.error("Can't add empty constructor in " + className + ".", e);
        throw new OALCompileException(e.getMessage(), e);
    }
    /**
     * Add fields with annotations.
     *
     * private ${sourceField.typeName} ${sourceField.fieldName};
     */
    for (SourceColumn field : metricsStmt.getFieldsFromSource()) {
        try {
            CtField newField = CtField.make("private " + field.getType().getName() + " " + field.getFieldName() + ";", metricsClass);
            metricsClass.addField(newField);
            metricsClass.addMethod(CtNewMethod.getter(field.getFieldGetter(), newField));
            metricsClass.addMethod(CtNewMethod.setter(field.getFieldSetter(), newField));
            AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
            /**
             * Add @Column(columnName = "${sourceField.columnName}")
             */
            Annotation columnAnnotation = new Annotation(Column.class.getName(), constPool);
            columnAnnotation.addMemberValue("columnName", new StringMemberValue(field.getColumnName(), constPool));
            if (field.getType().equals(String.class)) {
                columnAnnotation.addMemberValue("length", new IntegerMemberValue(constPool, field.getLength()));
            }
            annotationsAttribute.addAnnotation(columnAnnotation);
            newField.getFieldInfo().addAttribute(annotationsAttribute);
        } catch (CannotCompileException e) {
            log.error("Can't add field(including set/get) " + field.getFieldName() + " in " + className + ".", e);
            throw new OALCompileException(e.getMessage(), e);
        }
    }
    /**
     * Generate methods
     */
    for (String method : METRICS_CLASS_METHODS) {
        StringWriter methodEntity = new StringWriter();
        try {
            configuration.getTemplate("metrics/" + method + ".ftl").process(metricsStmt, methodEntity);
            metricsClass.addMethod(CtNewMethod.make(methodEntity.toString(), metricsClass));
        } catch (Exception e) {
            log.error("Can't generate method " + method + " for " + className + ".", e);
            throw new OALCompileException(e.getMessage(), e);
        }
    }
    /**
     * Add following annotation to the metrics class
     *
     * at Stream(name = "${tableName}", scopeId = ${sourceScopeId}, builder = ${metricsName}Metrics.Builder.class, processor = MetricsStreamProcessor.class)
     */
    AnnotationsAttribute annotationsAttribute = new AnnotationsAttribute(constPool, AnnotationsAttribute.visibleTag);
    Annotation streamAnnotation = new Annotation(Stream.class.getName(), constPool);
    streamAnnotation.addMemberValue("name", new StringMemberValue(metricsStmt.getTableName(), constPool));
    streamAnnotation.addMemberValue("scopeId", new IntegerMemberValue(constPool, metricsStmt.getFrom().getSourceScopeId()));
    streamAnnotation.addMemberValue("builder", new ClassMemberValue(metricsBuilderClassName(metricsStmt, true), constPool));
    streamAnnotation.addMemberValue("processor", new ClassMemberValue(METRICS_STREAM_PROCESSOR, constPool));
    annotationsAttribute.addAnnotation(streamAnnotation);
    metricsClassClassFile.addAttribute(annotationsAttribute);
    Class targetClass;
    try {
        if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_1_8)) {
            targetClass = metricsClass.toClass(currentClassLoader, null);
        } else {
            targetClass = metricsClass.toClass(MetricClassPackageHolder.class);
        }
    } catch (CannotCompileException e) {
        log.error("Can't compile/load " + className + ".", e);
        throw new OALCompileException(e.getMessage(), e);
    }
    log.debug("Generate metrics class, " + metricsClass.getName());
    writeGeneratedFile(metricsClass, metricsClass.getSimpleName(), "metrics");
    return targetClass;
}
Also used : ConstPool(javassist.bytecode.ConstPool) ClassFile(javassist.bytecode.ClassFile) OALCompileException(org.apache.skywalking.oap.server.core.oal.rt.OALCompileException) StringMemberValue(javassist.bytecode.annotation.StringMemberValue) AnnotationsAttribute(javassist.bytecode.AnnotationsAttribute) SourceColumn(org.apache.skywalking.oal.rt.parser.SourceColumn) NotFoundException(javassist.NotFoundException) FileNotFoundException(java.io.FileNotFoundException) MetricClassPackageHolder(org.apache.skywalking.oap.server.core.source.oal.rt.metrics.MetricClassPackageHolder) CannotCompileException(javassist.CannotCompileException) Annotation(javassist.bytecode.annotation.Annotation) NotFoundException(javassist.NotFoundException) FileNotFoundException(java.io.FileNotFoundException) OALCompileException(org.apache.skywalking.oap.server.core.oal.rt.OALCompileException) ModuleStartException(org.apache.skywalking.oap.server.library.module.ModuleStartException) StorageException(org.apache.skywalking.oap.server.core.storage.StorageException) CannotCompileException(javassist.CannotCompileException) IOException(java.io.IOException) ClassMemberValue(javassist.bytecode.annotation.ClassMemberValue) CtConstructor(javassist.CtConstructor) CtClass(javassist.CtClass) IntegerMemberValue(javassist.bytecode.annotation.IntegerMemberValue) StringWriter(java.io.StringWriter) Column(org.apache.skywalking.oap.server.core.storage.annotation.Column) SourceColumn(org.apache.skywalking.oal.rt.parser.SourceColumn) CtField(javassist.CtField) DataOutputStream(java.io.DataOutputStream) Stream(org.apache.skywalking.oap.server.core.analysis.Stream) FileOutputStream(java.io.FileOutputStream) CtClass(javassist.CtClass)

Example 78 with CtConstructor

use of javassist.CtConstructor in project skywalking by apache.

the class MeterSystem method create.

/**
 * Create streaming calculation of the given metrics name. This methods is synchronized due to heavy implementation
 * including creating dynamic class. Don't use this in concurrency runtime.
 *
 * @param metricsName  The name used as the storage eneity and in the query stage.
 * @param functionName The function provided through {@link MeterFunction}.
 * @throws IllegalArgumentException if the parameter can't match the expectation.
 * @throws UnexpectedException      if binary code manipulation fails or stream core failure.
 */
public synchronized <T> void create(String metricsName, String functionName, ScopeType type, Class<T> dataType) throws IllegalArgumentException {
    /**
     * Create a new meter class dynamically.
     */
    final Class<? extends AcceptableValue> meterFunction = functionRegister.get(functionName);
    if (meterFunction == null) {
        throw new IllegalArgumentException("Function " + functionName + " can't be found.");
    }
    boolean foundDataType = false;
    String acceptance = null;
    for (final Type genericInterface : meterFunction.getGenericInterfaces()) {
        if (genericInterface instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
            if (parameterizedType.getRawType().getTypeName().equals(AcceptableValue.class.getName())) {
                Type[] arguments = parameterizedType.getActualTypeArguments();
                if (arguments[0].equals(dataType)) {
                    foundDataType = true;
                } else {
                    acceptance = arguments[0].getTypeName();
                }
            }
            if (foundDataType) {
                break;
            }
        }
    }
    if (!foundDataType) {
        throw new IllegalArgumentException("Function " + functionName + " requires <" + acceptance + "> in AcceptableValue" + " but using " + dataType.getName() + " in the creation");
    }
    final CtClass parentClass;
    try {
        parentClass = classPool.get(meterFunction.getCanonicalName());
        if (!Metrics.class.isAssignableFrom(meterFunction)) {
            throw new IllegalArgumentException("Function " + functionName + " doesn't inherit from Metrics.");
        }
    } catch (NotFoundException e) {
        throw new IllegalArgumentException("Function " + functionName + " can't be found by javaassist.");
    }
    final String className = formatName(metricsName);
    /**
     * Check whether the metrics class is already defined or not
     */
    try {
        CtClass existingMetric = classPool.get(METER_CLASS_PACKAGE + className);
        if (existingMetric.getSuperclass() != parentClass || type != meterPrototypes.get(metricsName).getScopeType()) {
            throw new IllegalArgumentException(metricsName + " has been defined, but calculate function or/are scope type is/are different.");
        }
        log.info("Metric {} is already defined, so skip the metric creation.", metricsName);
        return;
    } catch (NotFoundException e) {
    }
    CtClass metricsClass = classPool.makeClass(METER_CLASS_PACKAGE + className, parentClass);
    /**
     * Create empty construct
     */
    try {
        CtConstructor defaultConstructor = CtNewConstructor.make("public " + className + "() {}", metricsClass);
        metricsClass.addConstructor(defaultConstructor);
    } catch (CannotCompileException e) {
        log.error("Can't add empty constructor in " + className + ".", e);
        throw new UnexpectedException(e.getMessage(), e);
    }
    /**
     * Generate `AcceptableValue<T> createNew()` method.
     */
    try {
        metricsClass.addMethod(CtNewMethod.make("" + "public org.apache.skywalking.oap.server.core.analysis.meter.function.AcceptableValue createNew() {" + "    org.apache.skywalking.oap.server.core.analysis.meter.function.AcceptableValue meterVar = new " + METER_CLASS_PACKAGE + className + "();" + "    ((org.apache.skywalking.oap.server.core.analysis.meter.Meter)meterVar).initMeta(\"" + metricsName + "\", " + type.getScopeId() + ");" + "    return meterVar;" + " }", metricsClass));
    } catch (CannotCompileException e) {
        log.error("Can't generate createNew method for " + className + ".", e);
        throw new UnexpectedException(e.getMessage(), e);
    }
    Class targetClass;
    try {
        if (SystemUtils.isJavaVersionAtMost(JavaVersion.JAVA_1_8)) {
            targetClass = metricsClass.toClass(MeterSystem.class.getClassLoader(), null);
        } else {
            targetClass = metricsClass.toClass(MeterClassPackageHolder.class);
        }
        AcceptableValue prototype = (AcceptableValue) targetClass.newInstance();
        meterPrototypes.put(metricsName, new MeterDefinition(type, prototype, dataType));
        log.debug("Generate metrics class, " + metricsClass.getName());
        MetricsStreamProcessor.getInstance().create(manager, new StreamDefinition(metricsName, type.getScopeId(), prototype.builder(), MetricsStreamProcessor.class), targetClass);
    } catch (CannotCompileException | IllegalAccessException | InstantiationException | StorageException e) {
        log.error("Can't compile/load/init " + className + ".", e);
        throw new UnexpectedException(e.getMessage(), e);
    }
}
Also used : UnexpectedException(org.apache.skywalking.oap.server.core.UnexpectedException) StreamDefinition(org.apache.skywalking.oap.server.core.analysis.StreamDefinition) NotFoundException(javassist.NotFoundException) CannotCompileException(javassist.CannotCompileException) MetricsStreamProcessor(org.apache.skywalking.oap.server.core.analysis.worker.MetricsStreamProcessor) CtConstructor(javassist.CtConstructor) ParameterizedType(java.lang.reflect.ParameterizedType) CtClass(javassist.CtClass) MeterClassPackageHolder(org.apache.skywalking.oap.server.core.analysis.meter.dynamic.MeterClassPackageHolder) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Metrics(org.apache.skywalking.oap.server.core.analysis.metrics.Metrics) AcceptableValue(org.apache.skywalking.oap.server.core.analysis.meter.function.AcceptableValue) CtClass(javassist.CtClass) StorageException(org.apache.skywalking.oap.server.core.storage.StorageException)

Example 79 with CtConstructor

use of javassist.CtConstructor in project DRouter by didi.

the class InterceptorCollect method generate.

@Override
public void generate(File routerDir) throws Exception {
    CtClass ctClass = pool.makeClass(getPackageName() + ".InterceptorLoader");
    CtClass superClass = pool.get("com.didi.drouter.store.MetaLoader");
    ctClass.setSuperclass(superClass);
    StringBuilder builder = new StringBuilder();
    builder.append("public void load(java.util.Map data) {\n");
    for (CtClass interceptorCc : interceptorClass.values()) {
        try {
            if (isNonStaticInnerClass(interceptorCc)) {
                throw new Exception("Annotation can not use non static inner class");
            }
            if (!checkSuper(interceptorCc, "com.didi.drouter.router.IRouterInterceptor")) {
                throw new Exception("@Interceptor class does not implement IRouterInterceptor interface");
            }
            Interceptor interceptor = (Interceptor) interceptorCc.getAnnotation(Interceptor.class);
            CtClass proxyCc = null;
            CtConstructor constructor = interceptorCc.getDeclaredConstructor(null);
            if (constructor != null) {
                CtClass proxyInterface = pool.get("com.didi.drouter.store.IRouterProxy");
                proxyCc = pool.makeClass(PROXY + interceptorCc.getName().replace(".", "_"));
                proxyCc.addInterface(proxyInterface);
                String method1 = String.format("public java.lang.Object newInstance(android.content.Context context) {" + "{  return new %s();} }", interceptorCc.getName());
                generatorClass(routerDir, proxyCc, method1, METHOD2);
            }
            // class is the key
            StringBuilder itemBuilder = new StringBuilder();
            itemBuilder.append("    data.put(");
            itemBuilder.append(interceptorCc.getName());
            itemBuilder.append(".class");
            itemBuilder.append(", com.didi.drouter.store.RouterMeta.build(");
            itemBuilder.append("com.didi.drouter.store.RouterMeta.INTERCEPTOR)");
            itemBuilder.append(".assembleInterceptor(");
            itemBuilder.append(interceptorCc.getName());
            itemBuilder.append(".class, ");
            itemBuilder.append(proxyCc != null ? "new " + proxyCc.getName() + "()" : "null");
            itemBuilder.append(",");
            itemBuilder.append(interceptor.priority());
            itemBuilder.append(",");
            itemBuilder.append(interceptor.global());
            itemBuilder.append(",");
            itemBuilder.append(interceptor.cache());
            itemBuilder.append("));\n");
            String name = interceptor.name();
            if (!TextUtil.isEmpty(name)) {
                // name is the key
                itemBuilder.append("    data.put(\"");
                itemBuilder.append(name);
                itemBuilder.append("\", com.didi.drouter.store.RouterMeta.build(");
                itemBuilder.append("com.didi.drouter.store.RouterMeta.INTERCEPTOR)");
                itemBuilder.append(".assembleInterceptor(");
                itemBuilder.append(interceptorCc.getName());
                itemBuilder.append(".class, ");
                itemBuilder.append(proxyCc != null ? "new " + proxyCc.getName() + "()" : "null");
                itemBuilder.append(",");
                itemBuilder.append(interceptor.priority());
                itemBuilder.append(",");
                itemBuilder.append(interceptor.global());
                itemBuilder.append(",");
                itemBuilder.append(interceptor.cache());
                itemBuilder.append("));\n");
                String duplicate = StoreUtil.insertUri(name, interceptorCc);
                if (duplicate != null) {
                    throw new Exception("\"name=" + name + "\" on " + interceptorCc.getName() + "\nhas duplication of name with class: " + duplicate);
                }
            }
            items.add(itemBuilder.toString());
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("Class: === " + interceptorCc.getName() + " ===\nCause: " + e.getMessage());
        }
    }
    Collections.sort(items);
    for (String item : items) {
        builder.append(item);
    }
    builder.append("}");
    Logger.d("\nclass InterceptorLoader" + "\n" + builder.toString());
    generatorClass(routerDir, ctClass, builder.toString());
}
Also used : CtClass(javassist.CtClass) Interceptor(com.didi.drouter.annotation.Interceptor) CtConstructor(javassist.CtConstructor)

Example 80 with CtConstructor

use of javassist.CtConstructor in project DRouter by didi.

the class ServiceCollect method generate.

@Override
public void generate(File routerDir) throws Exception {
    CtClass ctClass = pool.makeClass(getPackageName() + ".ServiceLoader");
    CtClass superClass = pool.get("com.didi.drouter.store.MetaLoader");
    ctClass.setSuperclass(superClass);
    StringBuilder builder = new StringBuilder();
    builder.append("public void load(java.util.Map data) {\n");
    CtClass featureInterface = pool.get("com.didi.drouter.service.IFeatureMatcher");
    for (CtClass serviceCc : serviceClass.values()) {
        try {
            if (isNonStaticInnerClass(serviceCc)) {
                throw new Exception("Annotation can not use non static inner class");
            }
            Annotation annotation = getAnnotation(serviceCc, Service.class);
            ArrayMemberValue functionValue = (ArrayMemberValue) annotation.getMemberValue("function");
            String[] aliasValue = ((Service) serviceCc.getAnnotation(Service.class)).alias();
            ArrayMemberValue featureValue = (ArrayMemberValue) annotation.getMemberValue("feature");
            int priority = ((Service) serviceCc.getAnnotation(Service.class)).priority();
            int cacheValue = ((Service) serviceCc.getAnnotation(Service.class)).cache();
            boolean anyAbility = false;
            List<CtClass> functionCcList = new ArrayList<>();
            for (int i = 0; i < functionValue.getValue().length; i++) {
                ClassMemberValue functionCmv = (ClassMemberValue) functionValue.getValue()[i];
                if ("com.didi.drouter.service.AnyAbility".equals(functionCmv.getValue())) {
                    anyAbility = true;
                } else {
                    CtClass functionCc = getCtClass(functionCmv.getValue());
                    functionCcList.add(functionCc);
                    String[] superClassNames;
                    if ("com.didi.drouter.service.ICallService".equals(functionCmv.getValue())) {
                        superClassNames = new String[11];
                        for (int j = 0; j < 10; j++) {
                            superClassNames[j] = "com.didi.drouter.service.ICallService" + j;
                        }
                        superClassNames[10] = "com.didi.drouter.service.ICallServiceN";
                    } else {
                        superClassNames = new String[] { functionCc.getName() };
                    }
                    // ICallService should use unique alias, for using alias to determine which service
                    if (functionCmv.getValue().startsWith("com.didi.drouter.service.ICallService")) {
                        if (i <= aliasValue.length - 1) {
                            String duplicate = StoreUtil.insertCallAlias(aliasValue[i], serviceCc);
                            if (duplicate != null) {
                                throw new Exception("ICallService can't use the same alias with" + duplicate);
                            }
                        }
                    }
                    if (!checkSuper(serviceCc, superClassNames)) {
                        throw new Exception("@Service with function does not match interface");
                    }
                }
            }
            if (anyAbility) {
                functionCcList.clear();
                functionCcList.addAll(collectSuper(serviceCc));
                if (aliasValue.length > 1) {
                    throw new Exception("only use one alias at most to match AnyAbility");
                }
                if (featureValue != null && featureValue.getValue().length > 1) {
                    throw new Exception("only use one feature at most to match AnyAbility");
                }
            }
            // traverse all the function argument, one function corresponding one function->(impl,feature) data
            for (int i = 0; i < functionCcList.size(); i++) {
                CtClass functionCc = functionCcList.get(i);
                String alias = "";
                if (aliasValue.length == 1) {
                    alias = aliasValue[0];
                } else if (i < aliasValue.length) {
                    // affirm no AnyAbility
                    alias = aliasValue[i];
                }
                // one feature generator one feature matcher class
                CtClass featureCc = null;
                CtClass featureMatchCc = null;
                if (featureValue != null) {
                    if (featureValue.getValue().length == 1) {
                        ClassMemberValue featureCmv = (ClassMemberValue) featureValue.getValue()[0];
                        featureCc = pool.get(featureCmv.getValue());
                    } else if (i < featureValue.getValue().length) {
                        // affirm no AnyAbility
                        ClassMemberValue featureCmv = (ClassMemberValue) featureValue.getValue()[i];
                        featureCc = pool.get(featureCmv.getValue());
                    }
                }
                if (featureCc != null) {
                    // avoid class duplication
                    String featureMatcher = MATCH + serviceCc.getName().replace(".", "_") + "__" + featureCc.getSimpleName();
                    featureMatchCc = pool.getOrNull(featureMatcher);
                    if (featureMatchCc == null) {
                        featureMatchCc = pool.makeClass(featureMatcher);
                        featureMatchCc.addInterface(featureInterface);
                        StringBuilder featureBuilder = new StringBuilder();
                        featureBuilder.append("\npublic boolean match(Object obj) {");
                        featureBuilder.append("\n    return obj instanceof ");
                        featureBuilder.append(featureCc.getName());
                        completeMatchMethod(serviceCc, featureCc, featureBuilder);
                        featureBuilder.append(";\n}");
                        // Logger.d(featureBuilder.toString());
                        generatorClass(routerDir, featureMatchCc, featureBuilder.toString());
                    }
                }
                CtClass methodProxyCc = null;
                String constructorMethod = null;
                String executeMethod = null;
                try {
                    CtConstructor constructor = serviceCc.getDeclaredConstructor(null);
                    if (constructor != null) {
                        constructorMethod = String.format("public java.lang.Object newInstance(android.content.Context context) {" + "{  return new %s();} }", serviceCc.getName());
                    }
                } catch (NotFoundException ignore) {
                }
                CtMethod[] ctMethods = serviceCc.getMethods();
                if (ctMethods != null) {
                    StringBuilder allIfStr = new StringBuilder();
                    Set<String> methodNames = new HashSet<>();
                    for (CtMethod method : ctMethods) {
                        boolean add = methodNames.add(method.getName() + "_$$_" + method.getParameterTypes().length);
                        Remote remote = (Remote) method.getAnnotation(Remote.class);
                        if (remote != null) {
                            if (!add) {
                                throw new Exception(String.format("The method \"%s\" with @Remote " + "can't be same name and same parameter count", method.getName()));
                            }
                            CtClass returnCc = method.getReturnType();
                            checkPrimitiveType(method.getName(), returnCc);
                            CtClass[] paraTypeCts = method.getParameterTypes();
                            StringBuilder para = new StringBuilder();
                            if (paraTypeCts != null) {
                                // argument type
                                for (int j = 0; j < paraTypeCts.length; j++) {
                                    checkPrimitiveType(method.getName(), paraTypeCts[j]);
                                    para.append(String.format("(%s) (args[%s])", paraTypeCts[j].getName(), j));
                                    if (j != paraTypeCts.length - 1) {
                                        para.append(",");
                                    }
                                }
                            }
                            // return type
                            if (!"void".equals(returnCc.getName())) {
                                allIfStr.append(String.format("if (\"%s\".equals(methodName)) { return ((%s)instance).%s(%s); }", method.getName() + "_$$_" + method.getParameterTypes().length, serviceCc.getName(), method.getName(), para));
                            } else {
                                allIfStr.append(String.format("if (\"%s\".equals(methodName)) { ((%s)instance).%s(%s); return null; }", method.getName() + "_$$_" + method.getParameterTypes().length, serviceCc.getName(), method.getName(), para));
                            }
                        }
                    }
                    executeMethod = String.format("public java.lang.Object execute(Object instance, String methodName, Object[] " + "args) {" + "%s" + "throw " + "new com.didi.drouter.store.IRouterProxy.RemoteMethodMatchException();" + "}", allIfStr);
                }
                if (constructorMethod != null || executeMethod != null) {
                    CtClass proxyInterface = pool.get("com.didi.drouter.store.IRouterProxy");
                    String path = PROXY + serviceCc.getName().replace(".", "_");
                    methodProxyCc = pool.getOrNull(path);
                    if (methodProxyCc == null) {
                        methodProxyCc = pool.makeClass(path);
                        methodProxyCc.addInterface(proxyInterface);
                        generatorClass(routerDir, methodProxyCc, constructorMethod == null ? METHOD1 : constructorMethod, executeMethod == null ? METHOD2 : executeMethod);
                    }
                }
                StringBuilder itemBuilder = new StringBuilder();
                itemBuilder.append("    put(");
                itemBuilder.append(functionCc.getName());
                itemBuilder.append(".class, com.didi.drouter.store.RouterMeta.build(");
                itemBuilder.append("com.didi.drouter.store.RouterMeta.SERVICE)");
                itemBuilder.append(".assembleService(");
                itemBuilder.append(serviceCc.getName());
                itemBuilder.append(".class, ");
                itemBuilder.append(methodProxyCc != null ? "new " + methodProxyCc.getName() + "()" : "null");
                itemBuilder.append(", \"");
                itemBuilder.append(alias);
                itemBuilder.append("\",");
                itemBuilder.append(featureMatchCc != null ? "new " + featureMatchCc.getName() + "()" : "null");
                itemBuilder.append(",");
                itemBuilder.append(priority);
                itemBuilder.append(",");
                itemBuilder.append(cacheValue);
                itemBuilder.append(")");
                itemBuilder.append(", data);\n");
                items.add(itemBuilder.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("Class: === " + serviceCc.getName() + " ===\nCause: " + e.getMessage());
        }
    }
    Collections.sort(items);
    for (String item : items) {
        builder.append(item);
    }
    builder.append("}");
    Logger.d("\nclass ServiceLoader" + "\n" + builder.toString());
    generatorClass(routerDir, ctClass, builder.toString());
}
Also used : ArrayList(java.util.ArrayList) Service(com.didi.drouter.annotation.Service) NotFoundException(javassist.NotFoundException) Remote(com.didi.drouter.annotation.Remote) NotFoundException(javassist.NotFoundException) Annotation(javassist.bytecode.annotation.Annotation) ClassMemberValue(javassist.bytecode.annotation.ClassMemberValue) CtConstructor(javassist.CtConstructor) CtClass(javassist.CtClass) ArrayMemberValue(javassist.bytecode.annotation.ArrayMemberValue) CtMethod(javassist.CtMethod) HashSet(java.util.HashSet)

Aggregations

CtConstructor (javassist.CtConstructor)88 CtClass (javassist.CtClass)64 CtMethod (javassist.CtMethod)36 NotFoundException (javassist.NotFoundException)31 ClassPool (javassist.ClassPool)30 CtField (javassist.CtField)30 CannotCompileException (javassist.CannotCompileException)29 IOException (java.io.IOException)13 Method (java.lang.reflect.Method)9 ArrayList (java.util.ArrayList)7 FileNotFoundException (java.io.FileNotFoundException)6 CtNewMethod (javassist.CtNewMethod)6 StorageException (org.apache.skywalking.oap.server.core.storage.StorageException)6 StringWriter (java.io.StringWriter)5 ConstPool (javassist.bytecode.ConstPool)5 MethodInfo (javassist.bytecode.MethodInfo)5 HashMap (java.util.HashMap)4 Annotation (javassist.bytecode.annotation.Annotation)4 OALCompileException (org.apache.skywalking.oap.server.core.oal.rt.OALCompileException)4 ModuleStartException (org.apache.skywalking.oap.server.library.module.ModuleStartException)4