Search in sources :

Example 1 with ProxettaException

use of jodd.proxetta.ProxettaException in project jodd by oblac.

the class TargetClassInfoReader method visitEnd.

/**
	 * Stores signatures for all super public methods not already overridden by target class.
	 * All this methods will be accepted for proxyfication.
	 */
@Override
public void visitEnd() {
    // prepare class annotations
    if (classAnnotations != null) {
        annotations = classAnnotations.toArray(new AnnotationInfo[classAnnotations.size()]);
        classAnnotations = null;
    }
    List<String> superList = new ArrayList<>();
    Set<String> allInterfaces = new HashSet<>();
    if (nextInterfaces != null) {
        allInterfaces.addAll(nextInterfaces);
    }
    // check all public super methods that are not overridden in superclass
    while (nextSupername != null) {
        InputStream inputStream = null;
        ClassReader cr = null;
        try {
            inputStream = ClassLoaderUtil.getClassAsStream(nextSupername, classLoader);
            cr = new ClassReader(inputStream);
        } catch (IOException ioex) {
            throw new ProxettaException("Unable to inspect super class: " + nextSupername, ioex);
        } finally {
            StreamUtil.close(inputStream);
        }
        superList.add(nextSupername);
        // remember the super class reader
        superClassReaders.add(cr);
        cr.accept(new SuperClassVisitor(), 0);
        if (cr.getInterfaces() != null) {
            Collections.addAll(allInterfaces, cr.getInterfaces());
        }
    }
    superClasses = superList.toArray(new String[superList.size()]);
    // check all interface methods that are not overridden in super-interface
    for (String next : allInterfaces) {
        InputStream inputStream = null;
        ClassReader cr = null;
        try {
            inputStream = ClassLoaderUtil.getClassAsStream(next, classLoader);
            cr = new ClassReader(inputStream);
        } catch (IOException ioex) {
            throw new ProxettaException("Unable to inspect super interface: " + next, ioex);
        } finally {
            StreamUtil.close(inputStream);
        }
        // remember the super class reader
        superClassReaders.add(cr);
        cr.accept(new SuperClassVisitor(), 0);
    }
}
Also used : ProxettaException(jodd.proxetta.ProxettaException) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) ClassReader(jodd.asm5.ClassReader) IOException(java.io.IOException) AnnotationInfo(jodd.proxetta.AnnotationInfo) HashSet(java.util.HashSet)

Example 2 with ProxettaException

use of jodd.proxetta.ProxettaException in project jodd by oblac.

the class DelegateAdviceUtil method injectTargetIntoProxy.

/**
	 * Injects target into proxy.
	 */
public static void injectTargetIntoProxy(Object proxy, Object target) {
    Class proxyClass = proxy.getClass();
    try {
        Field field = proxyClass.getField("$___target$0");
        field.set(proxy, target);
    } catch (Exception ex) {
        throw new ProxettaException(ex);
    }
}
Also used : Field(java.lang.reflect.Field) ProxettaException(jodd.proxetta.ProxettaException) ProxettaException(jodd.proxetta.ProxettaException)

Example 3 with ProxettaException

use of jodd.proxetta.ProxettaException in project jodd by oblac.

the class AnnotationTxAdviceManager method getTxMode.

/**
	 * Reads transaction mode from method annotation. Annotations are cached for better performances.
	 * @param type target class
	 * @param methodName target method name over which the transaction should be wrapped
	 * @param methodArgTypes types of arguments, used to find the method
	 * @param unique unique method fingerprint that contains return and arguments type information
	 */
public synchronized JtxTransactionMode getTxMode(Class type, String methodName, Class[] methodArgTypes, String unique) {
    String signature = type.getName() + '#' + methodName + '%' + unique;
    JtxTransactionMode txMode = txmap.get(signature);
    if (txMode == null) {
        if (!txmap.containsKey(signature)) {
            Method m;
            try {
                m = type.getMethod(methodName, methodArgTypes);
            } catch (NoSuchMethodException nsmex) {
                throw new ProxettaException(nsmex);
            }
            TransactionAnnotationData txAnn = getTransactionAnnotation(m);
            if (txAnn != null) {
                txMode = new JtxTransactionMode();
                txMode.setPropagationBehaviour(txAnn.getPropagation());
                txMode.setIsolationLevel(txAnn.getIsolation());
                txMode.setReadOnly(txAnn.isReadOnly());
                txMode.setTransactionTimeout(txAnn.getTimeout());
            } else {
                txMode = defaultTransactionMode;
            }
            txmap.put(signature, txMode);
        }
    }
    return txMode;
}
Also used : TransactionAnnotationData(jodd.jtx.meta.TransactionAnnotationData) ProxettaException(jodd.proxetta.ProxettaException) JtxTransactionMode(jodd.jtx.JtxTransactionMode) Method(java.lang.reflect.Method)

Example 4 with ProxettaException

use of jodd.proxetta.ProxettaException in project jodd by oblac.

the class InvokeReplacerMethodAdapter method visitMethodInsn.

/**
	 * Invoked on INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC, INVOKEINTERFACE or INVOKEDYNAMIC.
	 */
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
    // replace NEW.<init>
    if ((newInvokeReplacer != null) && (opcode == INVOKESPECIAL)) {
        String exOwner = owner;
        owner = newInvokeReplacer.getOwner();
        name = newInvokeReplacer.getMethodName();
        desc = changeReturnType(desc, 'L' + exOwner + ';');
        super.visitMethodInsn(INVOKESTATIC, owner, name, desc, isInterface);
        newInvokeReplacer = null;
        return;
    }
    InvokeInfo invokeInfo = new InvokeInfo(owner, name, desc);
    // to targets subclass with target (FOO.<init>).
    if (methodInfo.getMethodName().equals(INIT)) {
        if ((!firstSuperCtorInitCalled) && (opcode == INVOKESPECIAL) && name.equals(INIT) && owner.equals(wd.nextSupername)) {
            firstSuperCtorInitCalled = true;
            owner = wd.superReference;
            super.visitMethodInsn(opcode, owner, name, desc, isInterface);
            return;
        }
    }
    // detection of super calls
    if ((opcode == INVOKESPECIAL) && (owner.equals(wd.nextSupername) && (!name.equals(INIT)))) {
        throw new ProxettaException("Super call detected in class " + methodInfo.getClassname() + " method: " + methodInfo.getSignature() + "\nProxetta can't handle super calls due to VM limitations.");
    }
    InvokeReplacer ir = null;
    // find first matching aspect
    for (InvokeAspect aspect : aspects) {
        ir = aspect.pointcut(invokeInfo);
        if (ir != null) {
            break;
        }
    }
    if (ir == null || ir.isNone()) {
        if (ProxettaAsmUtil.isCreateArgumentsArrayMethod(name, desc)) {
            ProxyTargetReplacement.createArgumentsArray(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (ProxettaAsmUtil.isCreateArgumentsClassArrayMethod(name, desc)) {
            ProxyTargetReplacement.createArgumentsClassArray(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (ProxettaAsmUtil.isArgumentsCountMethod(name, desc)) {
            ProxyTargetReplacement.argumentsCount(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (ProxettaAsmUtil.isTargetMethodNameMethod(name, desc)) {
            ProxyTargetReplacement.targetMethodName(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (ProxettaAsmUtil.isTargetMethodDescriptionMethod(name, desc)) {
            ProxyTargetReplacement.targetMethodDescription(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (ProxettaAsmUtil.isTargetMethodSignatureMethod(name, desc)) {
            ProxyTargetReplacement.targetMethodSignature(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (ProxettaAsmUtil.isReturnTypeMethod(name, desc)) {
            ProxyTargetReplacement.returnType(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (ProxettaAsmUtil.isTargetClassMethod(name, desc)) {
            ProxyTargetReplacement.targetClass(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (isArgumentTypeMethod(name, desc)) {
            int argIndex = this.getArgumentIndex();
            ProxyTargetReplacement.argumentType(mv, methodInfo, argIndex);
            wd.proxyApplied = true;
            return;
        }
        if (isArgumentMethod(name, desc)) {
            int argIndex = this.getArgumentIndex();
            ProxyTargetReplacement.argument(mv, methodInfo, argIndex);
            wd.proxyApplied = true;
            return;
        }
        if (isInfoMethod(name, desc)) {
            proxyInfoRequested = true;
            // we are NOT calling the replacement here, as we would expect.
            // NO, we need to wait for the very next ASTORE method so we
            // can read the index and use it for replacement method!!!
            //ProxyTargetReplacement.info(mv, methodInfo);
            wd.proxyApplied = true;
            return;
        }
        if (isTargetMethodAnnotationMethod(name, desc)) {
            String[] args = getLastTwoStringArguments();
            // pop current two args
            mv.visitInsn(POP);
            mv.visitInsn(POP);
            ProxyTargetReplacement.targetMethodAnnotation(mv, methodInfo, args);
            wd.proxyApplied = true;
            return;
        }
        if (isTargetClassAnnotationMethod(name, desc)) {
            String[] args = getLastTwoStringArguments();
            // pop current two args
            mv.visitInsn(POP);
            mv.visitInsn(POP);
            ProxyTargetReplacement.targetClassAnnotation(mv, methodInfo.getClassInfo(), args);
            wd.proxyApplied = true;
            return;
        }
        super.visitMethodInsn(opcode, owner, name, desc, isInterface);
        return;
    }
    wd.proxyApplied = true;
    String exOwner = owner;
    owner = ir.getOwner();
    name = ir.getMethodName();
    switch(opcode) {
        case INVOKEINTERFACE:
            desc = prependArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_OBJECT);
            break;
        case INVOKEVIRTUAL:
            desc = prependArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_OBJECT);
            break;
        case INVOKESTATIC:
            break;
        default:
            throw new ProxettaException("Unsupported opcode: " + opcode);
    }
    // additional arguments
    if (ir.isPassOwnerName()) {
        desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_STRING);
        super.visitLdcInsn(exOwner);
    }
    if (ir.isPassMethodName()) {
        desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_STRING);
        super.visitLdcInsn(methodInfo.getMethodName());
    }
    if (ir.isPassMethodSignature()) {
        desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_STRING);
        super.visitLdcInsn(methodInfo.getSignature());
    }
    if (ir.isPassTargetClass()) {
        desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_CLASS);
        super.mv.visitLdcInsn(Type.getType('L' + wd.superReference + ';'));
    }
    if (ir.isPassThis()) {
        desc = appendArgument(desc, AsmUtil.L_SIGNATURE_JAVA_LANG_OBJECT);
        super.mv.visitVarInsn(ALOAD, 0);
    }
    super.visitMethodInsn(INVOKESTATIC, owner, name, desc, false);
}
Also used : ProxettaException(jodd.proxetta.ProxettaException) InvokeInfo(jodd.proxetta.InvokeInfo) InvokeAspect(jodd.proxetta.InvokeAspect) InvokeReplacer(jodd.proxetta.InvokeReplacer)

Example 5 with ProxettaException

use of jodd.proxetta.ProxettaException in project jodd by oblac.

the class ProxyAspectData method readAdviceData.

// ---------------------------------------------------------------- read
/**
	 * Parse advice class to gather some advice data. Should be called before any advice use.
	 * Must be called only *once* per advice.
	 */
private void readAdviceData() {
    if (ready) {
        return;
    }
    adviceClassReader.accept(new EmptyClassVisitor() {

        /**
			 * Stores advice reference.
			 */
        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            adviceReference = name;
            super.visit(version, access, name, signature, superName, interfaces);
        }

        /**
			 * Prevents advice to have inner classes.
			 */
        @Override
        public void visitInnerClass(String name, String outerName, String innerName, int access) {
            if (outerName.equals(adviceReference)) {
                throw new ProxettaException("Proxetta doesn't allow inner classes in/for advice: " + advice.getName());
            }
            super.visitInnerClass(name, outerName, innerName, access);
        }

        /**
			 * Clones advices fields to destination.
			 */
        @Override
        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
            // [A5]
            wd.dest.visitField(access, adviceFieldName(name, aspectIndex), desc, signature, value);
            return super.visitField(access, name, desc, signature, value);
        }

        /**
			 * Copies advices methods to destination.
			 */
        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            if (name.equals(CLINIT)) {
                // [A6]
                if (!desc.equals(DESC_VOID)) {
                    throw new ProxettaException("Invalid static initialization block description for advice: " + advice.getName());
                }
                name = clinitMethodName + methodDivider + aspectIndex;
                access |= AsmUtil.ACC_PRIVATE | AsmUtil.ACC_FINAL;
                wd.addAdviceClinitMethod(name);
                return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) {

                    @Override
                    public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
                    }

                    @Override
                    public void visitLineNumber(int line, Label start) {
                    }

                    @Override
                    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
                        if (opcode == INVOKESTATIC) {
                            if (owner.equals(adviceReference)) {
                                owner = wd.thisReference;
                                name = adviceMethodName(name, aspectIndex);
                            }
                        }
                        super.visitMethodInsn(opcode, owner, name, desc, isInterface);
                    }

                    @Override
                    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
                        // [F6]
                        if (owner.equals(adviceReference)) {
                            // [F5]
                            owner = wd.thisReference;
                            name = adviceFieldName(name, aspectIndex);
                        }
                        super.visitFieldInsn(opcode, owner, name, desc);
                    }
                };
            } else if (name.equals(INIT)) {
                // [A7]
                if (!desc.equals(DESC_VOID)) {
                    throw new ProxettaException("Advices can have only default constructors. Invalid advice: " + advice.getName());
                }
                name = initMethodName + methodDivider + aspectIndex;
                access = ProxettaAsmUtil.makePrivateFinalAccess(access);
                wd.addAdviceInitMethod(name);
                return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) {

                    @Override
                    public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
                    }

                    @Override
                    public void visitLineNumber(int line, Label start) {
                    }

                    // used to detect and to ignore the first super call()
                    int state;

                    @Override
                    public void visitVarInsn(int opcode, int var) {
                        // [F7]
                        if ((state == 0) && (opcode == ALOAD) && (var == 0)) {
                            state++;
                            return;
                        }
                        super.visitVarInsn(opcode, var);
                    }

                    @Override
                    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
                        if ((state == 1) && (opcode == INVOKESPECIAL)) {
                            state++;
                            return;
                        }
                        if ((opcode == INVOKEVIRTUAL) || (opcode == INVOKEINTERFACE)) {
                            if (owner.equals(adviceReference)) {
                                owner = wd.thisReference;
                                name = adviceMethodName(name, aspectIndex);
                            }
                        } else if (opcode == INVOKESTATIC) {
                            if (owner.equals(adviceReference)) {
                                owner = wd.thisReference;
                                name = adviceMethodName(name, aspectIndex);
                            }
                        }
                        super.visitMethodInsn(opcode, owner, name, desc, isInterface);
                    }

                    @Override
                    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
                        // [F7]
                        if (owner.equals(adviceReference)) {
                            // [F5]
                            owner = wd.thisReference;
                            name = adviceFieldName(name, aspectIndex);
                        }
                        super.visitFieldInsn(opcode, owner, name, desc);
                    }
                };
            } else // other methods
            if (!name.equals(executeMethodName)) {
                name = adviceMethodName(name, aspectIndex);
                return new MethodAdapter(wd.dest.visitMethod(access, name, desc, signature, exceptions)) {

                    @Override
                    public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
                    }

                    @Override
                    public void visitLineNumber(int line, Label start) {
                    }

                    @Override
                    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
                        if ((opcode == INVOKEVIRTUAL) || (opcode == INVOKEINTERFACE)) {
                            if (owner.equals(adviceReference)) {
                                owner = wd.thisReference;
                                name = adviceMethodName(name, aspectIndex);
                            }
                        } else if (opcode == INVOKESTATIC || opcode == INVOKESPECIAL) {
                            if (owner.equals(adviceReference)) {
                                owner = wd.thisReference;
                                name = adviceMethodName(name, aspectIndex);
                            }
                        }
                        super.visitMethodInsn(opcode, owner, name, desc, isInterface);
                    }

                    @Override
                    public void visitFieldInsn(int opcode, String owner, String name, String desc) {
                        // replace field references
                        if (owner.equals(adviceReference)) {
                            owner = wd.thisReference;
                            name = adviceFieldName(name, aspectIndex);
                        }
                        super.visitFieldInsn(opcode, owner, name, desc);
                    }
                };
            }
            //return new MethodAdapter(new EmptyMethodVisitor()) {		// toask may we replace this with the following code?
            return new EmptyMethodVisitor() {

                @Override
                public void visitVarInsn(int opcode, int var) {
                    if (isStoreOpcode(opcode)) {
                        if (var > maxLocalVarOffset) {
                            // find max local var offset
                            maxLocalVarOffset = var;
                        }
                    }
                    super.visitVarInsn(opcode, var);
                }
            };
        //					return super.visitMethod(access, name, desc, signature, exceptions);
        }
    }, 0);
    // increment offset by 2 because var on last index may be a dword value
    maxLocalVarOffset += 2;
    ready = true;
}
Also used : ProxettaException(jodd.proxetta.ProxettaException) Label(jodd.asm5.Label) FieldVisitor(jodd.asm5.FieldVisitor) EmptyClassVisitor(jodd.asm.EmptyClassVisitor) EmptyMethodVisitor(jodd.asm.EmptyMethodVisitor) MethodVisitor(jodd.asm5.MethodVisitor) MethodAdapter(jodd.asm.MethodAdapter) EmptyMethodVisitor(jodd.asm.EmptyMethodVisitor)

Aggregations

ProxettaException (jodd.proxetta.ProxettaException)6 Field (java.lang.reflect.Field)2 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1 EmptyClassVisitor (jodd.asm.EmptyClassVisitor)1 EmptyMethodVisitor (jodd.asm.EmptyMethodVisitor)1 MethodAdapter (jodd.asm.MethodAdapter)1 ClassReader (jodd.asm5.ClassReader)1 FieldVisitor (jodd.asm5.FieldVisitor)1 Label (jodd.asm5.Label)1 MethodVisitor (jodd.asm5.MethodVisitor)1 JtxTransactionMode (jodd.jtx.JtxTransactionMode)1 TransactionAnnotationData (jodd.jtx.meta.TransactionAnnotationData)1 AnnotationInfo (jodd.proxetta.AnnotationInfo)1 InvokeAspect (jodd.proxetta.InvokeAspect)1 InvokeInfo (jodd.proxetta.InvokeInfo)1 InvokeReplacer (jodd.proxetta.InvokeReplacer)1