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);
}
}
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);
}
}
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;
}
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);
}
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;
}
Aggregations