Search in sources :

Example 11 with CtField

use of javassist.CtField in project powermock by powermock.

the class ClassMockTransformerTest method addSyntheticField.

private void addSyntheticField(ClassPool classPool, CtClass ctClass) throws CannotCompileException, NotFoundException {
    CtField field = new CtField(classPool.get(String.class.getName()), SYNTH_FIELD, ctClass);
    field.setModifiers(AccessFlag.SYNTHETIC);
    ctClass.addField(field, CtField.Initializer.constant(SYNTHETIC_FIELD_VALUE));
}
Also used : CtField(javassist.CtField)

Example 12 with CtField

use of javassist.CtField in project BIMserver by opensourceBIM.

the class RealtimeReflectorFactoryBuilder method build1.

private void build1(Class<? extends PublicInterface> interfaceClass, org.bimserver.shared.meta.SService sService) {
    try {
        CtClass reflectorImplClass = pool.makeClass(GENERATED_CLASSES_PACKAGE + "." + interfaceClass.getSimpleName() + "Impl" + implementationCounter);
        reflectorImplClass.addInterface(pool.get(interfaceClass.getName()));
        CtClass reflectorClass = pool.get(Reflector.class.getName());
        CtField reflectorField = new CtField(reflectorClass, "reflector", reflectorImplClass);
        reflectorImplClass.addField(reflectorField);
        CtConstructor constructor = new CtConstructor(new CtClass[] { reflectorClass }, reflectorImplClass);
        StringBuilder sb = new StringBuilder();
        reflectorImplClass.addConstructor(constructor);
        sb.append("{");
        sb.append("this.reflector = $1;");
        sb.append("}");
        constructor.setBody(sb.toString());
        for (SMethod sMethod : sService.getMethods()) {
            CtClass[] parameters = new CtClass[sMethod.getParameters().size()];
            int i = 0;
            for (org.bimserver.shared.meta.SParameter sParameter : sMethod.getParameters()) {
                parameters[i] = pool.get(sParameter.getType().toJavaCode());
                i++;
            }
            CtMethod method = new CtMethod(pool.get(sMethod.getReturnType().toJavaCode()), sMethod.getName(), parameters, reflectorImplClass);
            StringBuilder methodBuilder = new StringBuilder();
            methodBuilder.append("{");
            if (sMethod.getReturnType().isVoid()) {
            } else {
                methodBuilder.append("return (" + sMethod.getReturnType().toJavaCode() + ")");
            }
            methodBuilder.append("reflector.callMethod(\"" + interfaceClass.getSimpleName() + "\", \"" + sMethod.getName() + "\", " + sMethod.getReturnType().toJavaCode() + ".class");
            if (sMethod.getParameters().isEmpty()) {
                methodBuilder.append(", new " + KeyValuePair.class.getName() + "[0]");
            } else {
                methodBuilder.append(", new " + KeyValuePair.class.getName() + "[]{");
                int x = 1;
                for (SParameter sParameter : sMethod.getParameters()) {
                    methodBuilder.append("new " + KeyValuePair.class.getName() + "(\"" + sParameter.getName() + "\", $" + x + ")");
                    if (sMethod.getParameter(sMethod.getParameters().size() - 1) != sParameter) {
                        methodBuilder.append(", ");
                    }
                    x++;
                }
                methodBuilder.append("}");
            }
            methodBuilder.append(");");
            methodBuilder.append("}");
            method.setBody(methodBuilder.toString());
            reflectorImplClass.addMethod(method);
        }
        pool.toClass(reflectorImplClass, getClass().getClassLoader(), getClass().getProtectionDomain());
    } catch (Exception e) {
        LOGGER.error("", e);
    }
}
Also used : CannotCompileException(javassist.CannotCompileException) NotFoundException(javassist.NotFoundException) CtConstructor(javassist.CtConstructor) CtClass(javassist.CtClass) CtField(javassist.CtField) SParameter(org.bimserver.shared.meta.SParameter) SMethod(org.bimserver.shared.meta.SMethod) SParameter(org.bimserver.shared.meta.SParameter) CtMethod(javassist.CtMethod)

Example 13 with CtField

use of javassist.CtField in project BIMserver by opensourceBIM.

the class RealtimeReflectorFactoryBuilder method build2.

private void build2(Class<? extends PublicInterface> interfaceClass, org.bimserver.shared.meta.SService sService) {
    try {
        CtClass reflectorImplClass = pool.makeClass(GENERATED_CLASSES_PACKAGE + "." + interfaceClass.getSimpleName() + "Reflector" + implementationCounter);
        CtClass reflectorClass = pool.get(Reflector.class.getName());
        CtClass interfaceCtClass = pool.get(interfaceClass.getName());
        reflectorImplClass.addInterface(reflectorClass);
        CtField reflectorField = new CtField(interfaceCtClass, "publicInterface", reflectorImplClass);
        reflectorImplClass.addField(reflectorField);
        CtConstructor constructor = new CtConstructor(new CtClass[] { interfaceCtClass }, reflectorImplClass);
        StringBuilder sb = new StringBuilder();
        reflectorImplClass.addConstructor(constructor);
        sb.append("{");
        sb.append("this.publicInterface = $1;");
        sb.append("}");
        constructor.setBody(sb.toString());
        CtClass[] parameters = new CtClass[4];
        parameters[0] = pool.get(String.class.getName());
        parameters[1] = pool.get(String.class.getName());
        parameters[2] = pool.get(Class.class.getName());
        parameters[3] = pool.get(KeyValuePair.class.getName() + "[]");
        CtMethod method = new CtMethod(pool.get(Object.class.getName()), "callMethod", parameters, reflectorImplClass);
        StringBuilder methodBuilder = new StringBuilder();
        methodBuilder.append("{");
        methodBuilder.append("if  (1==0) {} ");
        for (SMethod sMethod : sService.getMethods()) {
            methodBuilder.append(" else if ($2.equals(\"" + sMethod.getName() + "\")) {");
            if (!sMethod.getReturnType().isVoid()) {
                methodBuilder.append("return ");
            }
            methodBuilder.append("publicInterface." + sMethod.getName() + "(");
            int i = 0;
            for (SParameter sParameter : sMethod.getParameters()) {
                methodBuilder.append("(" + sParameter.getType().toJavaCode() + ")$4[" + i + "].getValue()");
                if (i < sMethod.getParameters().size() - 1) {
                    methodBuilder.append(", ");
                }
                i++;
            }
            methodBuilder.append(");");
            methodBuilder.append("}");
        }
        methodBuilder.append("return null;");
        methodBuilder.append("}");
        method.setBody(methodBuilder.toString());
        reflectorImplClass.addMethod(method);
        pool.toClass(reflectorImplClass, getClass().getClassLoader(), getClass().getProtectionDomain());
    } catch (Exception e) {
        LOGGER.error("", e);
    }
}
Also used : CtClass(javassist.CtClass) CtField(javassist.CtField) SParameter(org.bimserver.shared.meta.SParameter) SMethod(org.bimserver.shared.meta.SMethod) CtMethod(javassist.CtMethod) CannotCompileException(javassist.CannotCompileException) NotFoundException(javassist.NotFoundException) CtConstructor(javassist.CtConstructor)

Example 14 with CtField

use of javassist.CtField in project turbo-rpc by hank-whu.

the class RemoteServiceFactory method generateRemoteObject.

private Object generateRemoteObject(App app, Class<?> clazz, Collection<MethodConfig> configs) throws Exception {
    if (app == null) {
        throw new RuntimeException("app must not be null");
    }
    if (clazz == null) {
        throw new RuntimeException("clazz must not be null");
    }
    if (configs == null || configs.isEmpty()) {
        throw new RuntimeException("configs must not be empty");
    }
    for (MethodConfig config : configs) {
        if (config == null) {
            throw new RuntimeException("config must not be null");
        }
        if (config.method == null) {
            throw new RuntimeException("config.method must not be null");
        }
        if (config.timeout < 1) {
            throw new RuntimeException("config.timeout must > 0");
        }
        if (config.timeout > 5 * 60 * 1000) {
            throw new RuntimeException("config.timeout must < 5 * 60 * 1000 (5 mintues)");
        }
    }
    Method[] allMethods = clazz.getMethods();
    List<Method> allPublicMethods = // 
    Stream.of(// 
    allMethods).filter(// 
    m -> Modifier.isPublic(m.getModifiers())).filter(// 
    m -> !Modifier.isStatic(m.getModifiers())).peek(m -> {
        if (!CompletableFuture.class.equals(m.getReturnType())) {
            throw new RuntimeException("method return-type must be CompletableFuture, " + InvokerUtils.getServiceMethodName("", "", m));
        }
    }).collect(Collectors.toList());
    if (configs.size() != allPublicMethods.size()) {
        throw new RuntimeException("configs must contains all the interface's methods");
    }
    for (Method method : allMethods) {
        if (!CompletableFuture.class.equals(method.getReturnType())) {
            throw new RuntimeException("method return-type must be CompletableFuture, " + method);
        }
        if (!configs.stream().anyMatch(config -> config.method.equals(method))) {
            throw new RuntimeException("configs must contains the method: " + method);
        }
    }
    final String remoteClassName = // 
    clazz.getName() + "_RemoteService_" + UUID.randomUUID().toString().replace("-", "");
    // 创建类
    ClassPool pool = ClassPool.getDefault();
    CtClass remoteCtClass = pool.makeClass(remoteClassName);
    CtClass[] interfaces = { pool.getCtClass(clazz.getName()), pool.getCtClass(RemoteInterface.class.getName()) };
    remoteCtClass.setInterfaces(interfaces);
    // 添加私有成员app
    CtField appField = new CtField(pool.get(App.class.getName()), "app", remoteCtClass);
    appField.setModifiers(Modifier.PRIVATE | Modifier.FINAL);
    remoteCtClass.addField(appField);
    // 添加get方法
    remoteCtClass.addMethod(CtNewMethod.getter("getApp", appField));
    // 添加有参的构造函数
    CtConstructor constructor1 = new CtConstructor(new CtClass[] { pool.get(App.class.getName()) }, remoteCtClass);
    constructor1.setBody("{$0.app = $1;}");
    remoteCtClass.addConstructor(constructor1);
    for (MethodConfig config : configs) {
        Method method = config.method;
        Class<? extends MethodParam> methodParamClass = MethodParamClassFactory.createClass(method);
        long timeout = config.timeout;
        // 添加私有成员failoverInvoker
        String failoverFieldName = getFailoverInvokerFieldName(app, method);
        CtField failoverField = new CtField(pool.get(Invoker.class.getName()), failoverFieldName, remoteCtClass);
        appField.setModifiers(Modifier.PRIVATE);
        remoteCtClass.addField(failoverField);
        StringBuilder methodBuilder = new StringBuilder();
        methodBuilder.append("public ");
        methodBuilder.append(method.getReturnType().getName());
        methodBuilder.append(" ");
        methodBuilder.append(method.getName());
        methodBuilder.append("(");
        Class<?>[] parameterTypes = method.getParameterTypes();
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> parameterType = parameterTypes[i];
            methodBuilder.append(parameterType.getName());
            methodBuilder.append(" param");
            methodBuilder.append(i);
            if (i != parameterTypes.length - 1) {
                methodBuilder.append(", ");
            }
        }
        methodBuilder.append("){\r\n");
        methodBuilder.append("  return ");
        if (config.ignore) {
            if (logger.isInfoEnabled()) {
                logger.info(InvokerUtils.getServiceMethodName(app.group, app.app, config.method) + " ignore");
            }
            methodBuilder.append("$remote_ignore()");
        } else {
            if (logger.isInfoEnabled()) {
                logger.info(// 
                InvokerUtils.getServiceMethodName(app.group, app.app, config.method) + " register, config:" + config);
            }
            methodBuilder.append("$remote_execute(");
            methodBuilder.append(app.getMethodId(method));
            methodBuilder.append(", ");
            methodBuilder.append(timeout);
            methodBuilder.append("L, ");
            methodBuilder.append("new ");
            methodBuilder.append(methodParamClass.getName());
            methodBuilder.append("(");
            for (int i = 0; i < parameterTypes.length; i++) {
                methodBuilder.append("param");
                methodBuilder.append(i);
                if (i != parameterTypes.length - 1) {
                    methodBuilder.append(",");
                }
            }
            methodBuilder.append("), ");
            methodBuilder.append(failoverFieldName);
            methodBuilder.append(")");
        }
        methodBuilder.append(";\r\n}");
        CtMethod m = CtNewMethod.make(methodBuilder.toString(), remoteCtClass);
        remoteCtClass.addMethod(m);
    }
    Class<?> invokerClass = remoteCtClass.toClass();
    return invokerClass.getConstructor(App.class).newInstance(app);
}
Also used : CtMethod(javassist.CtMethod) CompletableFuture(java.util.concurrent.CompletableFuture) CtClass(javassist.CtClass) CtNewMethod(javassist.CtNewMethod) App(rpc.turbo.transport.client.App) CtConstructor(javassist.CtConstructor) MethodConfig(rpc.turbo.config.MethodConfig) Method(java.lang.reflect.Method) Invoker(rpc.turbo.invoke.Invoker) TurboService(rpc.turbo.annotation.TurboService) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MethodParam(rpc.turbo.param.MethodParam) IOException(java.io.IOException) UUID(java.util.UUID) Field(java.lang.reflect.Field) Collectors(java.util.stream.Collectors) CtField(javassist.CtField) MethodParamClassFactory(rpc.turbo.param.MethodParamClassFactory) List(java.util.List) InvokerUtils(rpc.turbo.invoke.InvokerUtils) Stream(java.util.stream.Stream) Closeable(java.io.Closeable) Modifier(java.lang.reflect.Modifier) Log(org.apache.commons.logging.Log) LogFactory(org.apache.commons.logging.LogFactory) ClassPool(javassist.ClassPool) FailoverInvokerFactory(rpc.turbo.invoke.FailoverInvokerFactory) App(rpc.turbo.transport.client.App) ClassPool(javassist.ClassPool) CtMethod(javassist.CtMethod) CtNewMethod(javassist.CtNewMethod) Method(java.lang.reflect.Method) CtConstructor(javassist.CtConstructor) MethodConfig(rpc.turbo.config.MethodConfig) CtClass(javassist.CtClass) CompletableFuture(java.util.concurrent.CompletableFuture) CtField(javassist.CtField) CtClass(javassist.CtClass) CtMethod(javassist.CtMethod)

Example 15 with CtField

use of javassist.CtField in project turbo-rpc by hank-whu.

the class JavassistInvoker method generateRealInvoker.

private Invoker<T> generateRealInvoker() throws Exception {
    final String invokerClassName = // 
    "rpc.turbo.invoke.generate.Invoker_" + serviceId + // 
    "_" + UUID.randomUUID().toString().replace("-", "");
    // 创建类
    ClassPool pool = ClassPool.getDefault();
    CtClass invokerCtClass = pool.makeClass(invokerClassName);
    invokerCtClass.setInterfaces(new CtClass[] { pool.getCtClass(Invoker.class.getName()) });
    // 添加私有成员service
    CtField serviceField = new CtField(pool.get(service.getClass().getName()), "service", invokerCtClass);
    serviceField.setModifiers(Modifier.PRIVATE | Modifier.FINAL);
    invokerCtClass.addField(serviceField);
    // 添加有参的构造函数
    CtConstructor constructor = new CtConstructor(new CtClass[] { pool.get(service.getClass().getName()) }, invokerCtClass);
    constructor.setBody("{$0.service = $1;}");
    invokerCtClass.addConstructor(constructor);
    {
        // 添加MethodParam方法
        StringBuilder methodBuilder = new StringBuilder();
        StringBuilder resultBuilder = new StringBuilder();
        methodBuilder.append("public Object invoke(rpc.turbo.param.MethodParam methodParam) {\r\n");
        if (parameterTypes.length > 0) {
            // 强制类型转换
            methodBuilder.append(methodParamClass.getName());
            methodBuilder.append("  params = (");
            methodBuilder.append(methodParamClass.getName());
            methodBuilder.append(")methodParam;");
        }
        methodBuilder.append("  return ");
        resultBuilder.append("service.");
        resultBuilder.append(method.getName());
        resultBuilder.append("(");
        for (int i = 0; i < parameterTypes.length; i++) {
            resultBuilder.append("params.$param");
            resultBuilder.append(i);
            resultBuilder.append("()");
            if (i != parameterTypes.length - 1) {
                methodBuilder.append(", ");
            }
        }
        resultBuilder.append(")");
        String resultStr = box(method.getReturnType(), resultBuilder.toString());
        methodBuilder.append(resultStr);
        methodBuilder.append(";\r\n}");
        CtMethod m = CtNewMethod.make(methodBuilder.toString(), invokerCtClass);
        invokerCtClass.addMethod(m);
    }
    {
        // 添加通用方法
        StringBuilder methodBuilder = new StringBuilder();
        StringBuilder resultBuilder = new StringBuilder();
        methodBuilder.append("public Object invoke(Object[] params) {\r\n");
        methodBuilder.append("  return ");
        resultBuilder.append("service.");
        resultBuilder.append(method.getName());
        resultBuilder.append("(");
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> paramType = parameterTypes[i];
            resultBuilder.append("((");
            resultBuilder.append(forceCast(paramType));
            resultBuilder.append(")params[");
            resultBuilder.append(i);
            resultBuilder.append("])");
            resultBuilder.append(unbox(paramType));
        }
        resultBuilder.append(")");
        String resultStr = box(method.getReturnType(), resultBuilder.toString());
        methodBuilder.append(resultStr);
        methodBuilder.append(";\r\n}");
        CtMethod m = CtNewMethod.make(methodBuilder.toString(), invokerCtClass);
        invokerCtClass.addMethod(m);
    }
    if (parameterCount <= 6) {
        // just for benchmark
        StringBuilder methodBuilder = new StringBuilder();
        StringBuilder resultBuilder = new StringBuilder();
        methodBuilder.append("public Object invoke(");
        String params = // 
        IntStream.range(0, // 
        parameterCount).mapToObj(// 
        i -> "Object param" + i).collect(Collectors.joining(","));
        methodBuilder.append(params);
        methodBuilder.append(") {\r\n");
        methodBuilder.append("  return ");
        resultBuilder.append("service.");
        resultBuilder.append(method.getName());
        resultBuilder.append("(");
        for (int i = 0; i < parameterCount; i++) {
            Class<?> paramType = parameterTypes[i];
            resultBuilder.append("((");
            resultBuilder.append(forceCast(paramType));
            resultBuilder.append(")param");
            resultBuilder.append(i);
            resultBuilder.append(")");
            resultBuilder.append(unbox(paramType));
            if (i != parameterCount - 1) {
                resultBuilder.append(",");
            }
        }
        resultBuilder.append(")");
        String resultStr = box(method.getReturnType(), resultBuilder.toString());
        methodBuilder.append(resultStr);
        methodBuilder.append(";\r\n}");
        CtMethod m = CtNewMethod.make(methodBuilder.toString(), invokerCtClass);
        invokerCtClass.addMethod(m);
    }
    Class<?> invokerClass = invokerCtClass.toClass();
    // 通过反射创建有参的实例
    @SuppressWarnings("unchecked") Invoker<T> invoker = (Invoker<T>) invokerClass.getConstructor(service.getClass()).newInstance(service);
    return invoker;
}
Also used : IntStream(java.util.stream.IntStream) Arrays(java.util.Arrays) CtMethod(javassist.CtMethod) Modifier(javassist.Modifier) MethodParam(rpc.turbo.param.MethodParam) SourceCodeUtils.forceCast(rpc.turbo.util.SourceCodeUtils.forceCast) UUID(java.util.UUID) CtClass(javassist.CtClass) Collectors(java.util.stream.Collectors) EmptyMethodParam(rpc.turbo.param.EmptyMethodParam) CtField(javassist.CtField) CtNewMethod(javassist.CtNewMethod) MethodParamClassFactory(rpc.turbo.param.MethodParamClassFactory) TypeUtils(rpc.turbo.util.TypeUtils) SourceCodeUtils.unbox(rpc.turbo.util.SourceCodeUtils.unbox) Parameter(java.lang.reflect.Parameter) CtConstructor(javassist.CtConstructor) SourceCodeUtils.box(rpc.turbo.util.SourceCodeUtils.box) Method(java.lang.reflect.Method) ClassPool(javassist.ClassPool) ClassPool(javassist.ClassPool) CtConstructor(javassist.CtConstructor) CtClass(javassist.CtClass) CtField(javassist.CtField) CtClass(javassist.CtClass) CtMethod(javassist.CtMethod)

Aggregations

CtField (javassist.CtField)76 CtClass (javassist.CtClass)47 CtMethod (javassist.CtMethod)27 CannotCompileException (javassist.CannotCompileException)24 NotFoundException (javassist.NotFoundException)22 ClassPool (javassist.ClassPool)20 CtConstructor (javassist.CtConstructor)15 Test (org.junit.Test)12 ClassFile (javassist.bytecode.ClassFile)9 IOException (java.io.IOException)7 Method (java.lang.reflect.Method)7 ArrayList (java.util.ArrayList)6 AnnotationsAttribute (javassist.bytecode.AnnotationsAttribute)5 IllegalClassFormatException (java.lang.instrument.IllegalClassFormatException)4 ConstPool (javassist.bytecode.ConstPool)4 SMethod (org.bimserver.shared.meta.SMethod)4 SParameter (org.bimserver.shared.meta.SParameter)4 InsertableMethod (com.github.stephanenicolas.afterburner.inserts.InsertableMethod)3 SimpleInsertableMethod (com.github.stephanenicolas.afterburner.inserts.SimpleInsertableMethod)3 ByteArrayInputStream (java.io.ByteArrayInputStream)3