List of usage examples for org.objectweb.asm.commons Method Method
public Method(final String name, final String descriptor)
From source file:nl.hardijzer.fw.checkabstract.ClassInfo.java
License:Open Source License
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { Method m = new Method(name, desc); boolean bAbstract = ((access & Opcodes.ACC_ABSTRACT) != 0); if (bAbstract) info.setAbstractMethods.add(m);//from ww w. ja va 2s. co m else info.setMethods.add(m); info.mapMethodOwner.put(m, info.strName); return super.visitMethod(access, name, desc, signature, exceptions); }
From source file:org.apache.aries.proxy.impl.common.AbstractWovenProxyAdapter.java
License:Apache License
/** * This method is called on each method implemented on this object (but not * for superclass methods) Each of these methods is visited in turn and the * code here generates the byte code for the calls to the InovcationListener * around the existing method// w ww .jav a 2s .c o m */ public final MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { LOGGER.debug(Constants.LOG_ENTRY, "visitMethod", new Object[] { access, name, desc, signature, exceptions }); Method currentMethod = new Method(name, desc); getKnownMethods().add(currentMethod); MethodVisitor methodVisitorToReturn = null; // Only weave "real" instance methods. Not constructors, initializers or // compiler generated ones. if ((access & (ACC_STATIC | ACC_PRIVATE | ACC_SYNTHETIC | ACC_NATIVE | ACC_BRIDGE)) == 0 && !!!name.equals("<init>") && !!!name.equals("<clinit>")) { // found a method we should weave //Create a field name and store it for later String methodStaticFieldName = "methodField" + getSanitizedUUIDString(); transformedMethods.put(methodStaticFieldName, new TypeMethod(currentMethodDeclaringType, currentMethod)); // Surround the MethodVisitor with our weaver so we can manipulate the code methodVisitorToReturn = getWeavingMethodVisitor(access, name, desc, signature, exceptions, currentMethod, methodStaticFieldName, currentMethodDeclaringType, currentMethodDeclaringTypeIsInterface); } else if (name.equals("<clinit>")) { //there is an existing clinit method, change the fields we use //to write our init code to static_init_UUID instead staticInitMethod = new Method("static_init_" + UU_ID, Type.VOID_TYPE, NO_ARGS); staticInitMethodFlags = staticInitMethodFlags | ACC_FINAL; methodVisitorToReturn = new AdviceAdapter(Opcodes.ASM5, cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc) { @Override protected void onMethodEnter() { //add into the <clinit> a call to our synthetic static_init_UUID invokeStatic(typeBeingWoven, staticInitMethod); super.onMethodEnter(); } }; } else { if (currentMethod.getArgumentTypes().length == 0 && name.equals("<init>")) hasNoArgsConstructor = true; //This isn't a method we want to weave, so just get the default visitor methodVisitorToReturn = cv.visitMethod(access, name, desc, signature, exceptions); } LOGGER.debug(Constants.LOG_EXIT, "visitMethod", methodVisitorToReturn); return methodVisitorToReturn; }
From source file:org.apache.aries.proxy.impl.common.MethodCopyingClassAdapter.java
License:Apache License
@Override public final MethodVisitor visitMethod(final int access, String name, String desc, String sig, String[] exceptions) {/* ww w.j ava2 s . co m*/ MethodVisitor mv = null; //As in WovenProxyAdapter, we only care about "real" methods, but also not //abstract ones!. if (!!!name.equals("<init>") && !!!name.equals("<clinit>") && (access & (ACC_STATIC | ACC_PRIVATE | ACC_SYNTHETIC | ACC_ABSTRACT | ACC_NATIVE | ACC_BRIDGE)) == 0) { // identify the target method parameters and return type Method currentTransformMethod = new Method(name, desc); // We don't want to duplicate a method we already overrode! if (!!!knownMethods.add(currentTransformMethod)) return null; // found a method we should weave // We can't override a final method if ((access & ACC_FINAL) != 0) throw new RuntimeException(new FinalModifierException(superToCopy, name)); // We can't call up to a default access method if we aren't in the same // package if ((access & (ACC_PUBLIC | ACC_PROTECTED | ACC_PRIVATE)) == 0) { if (!!!samePackage) throw new RuntimeException(NLS.MESSAGES.getMessage("method.from.superclass.is.hidden", name, superToCopy.getName(), overridingClassType.getClassName()), new UnableToProxyException(superToCopy)); } //Safe to copy a call to this method! Type superType = Type.getType(superToCopy); // identify the target method parameters and return type String methodStaticFieldName = "methodField" + AbstractWovenProxyAdapter.getSanitizedUUIDString(); transformedMethods.put(methodStaticFieldName, new TypeMethod(superType, currentTransformMethod)); //Remember we need to copy the fake method *and* weave it, use a //WovenProxyMethodAdapter as well as a CopyingMethodAdapter MethodVisitor weaver = wovenProxyAdapter.getWeavingMethodVisitor(access, name, desc, sig, exceptions, currentTransformMethod, methodStaticFieldName, superType, false); if (weaver instanceof AbstractWovenProxyMethodAdapter) { //If we are weaving this method then we might have a problem. If it's a protected method and we //aren't in the same package then we can't dispatch the call to another object. This may sound //odd, but if class Super has a protected method foo(), then class Sub, that extends Super, cannot //call ((Super)o).foo() in code (it can call super.foo()). If we are in the same package then this //gets around the problem, but if not the class will fail verification. if (!samePackage && (access & ACC_PROTECTED) != 0) throw new RuntimeException(NLS.MESSAGES.getMessage("method.from.superclass.is.hidden", name, superToCopy.getName(), overridingClassType.getClassName()), new UnableToProxyException(superToCopy)); mv = new CopyingMethodAdapter((GeneratorAdapter) weaver, superType, currentTransformMethod); } else { //For whatever reason we aren't weaving this method. The call to super.xxx() will always work mv = new CopyingMethodAdapter(new GeneratorAdapter(access, currentTransformMethod, mv), superType, currentTransformMethod); } } return mv; }
From source file:org.apache.aries.proxy.impl.gen.ProxySubclassAdapter.java
License:Apache License
private void processMethod(int access, String name, String desc, String signature, String[] exceptions) { LOGGER.debug(Constants.LOG_ENTRY, "processMethod", new Object[] { access, name, desc, signature, exceptions }); LOGGER.debug("Processing method: {} with descriptor {}", name, desc); // identify the target method parameters and return type Method currentTransformMethod = new Method(name, desc); Type[] targetMethodParameters = currentTransformMethod.getArgumentTypes(); Type returnType = currentTransformMethod.getReturnType(); // we create a static field for each method we encounter with a name // like method_parm1_parm2... StringBuilder methodStaticFieldNameBuilder = new StringBuilder(name); // for each a parameter get the name and add it to the field removing // the dots first for (Type t : targetMethodParameters) { methodStaticFieldNameBuilder.append("_"); methodStaticFieldNameBuilder/*from ww w . java 2s. c o m*/ .append(t.getClassName().replaceAll("\\[\\]", "Array").replaceAll("\\.", "")); } String methodStaticFieldName = methodStaticFieldNameBuilder.toString(); // add a private static field for the method cv.visitField(ACC_PRIVATE | ACC_STATIC, methodStaticFieldName, METHOD_TYPE.getDescriptor(), null, null); // visit the method using the class writer, delegated through the method // visitor and generator // modify the method access so that any native methods aren't // described as native // since they won't be native in proxy form // also stop methods being marked synchronized on the proxy as they will // be sync // on the real object int newAccess = access & (~ACC_NATIVE) & (~ACC_SYNCHRONIZED); MethodVisitor mv = cv.visitMethod(newAccess, name, desc, signature, exceptions); // use a GeneratorAdapter to build the invoke call directly in byte code GeneratorAdapter methodAdapter = new GeneratorAdapter(mv, newAccess, name, desc); /* * Stage 1 creates the bytecode for adding the reflected method of the * superclass to a static field in the subclass: private static Method * methodName_parm1_parm2... = null; static{ methodName_parm1_parm2... = * superClass.getDeclaredMethod(methodName,new Class[]{method args}; } * * Stage 2 is to call the ih.invoke(this,methodName_parm1_parm2,args) in * the new subclass methods Stage 3 is to cast the return value to the * correct type */ /* * Stage 1 use superClass.getMethod(methodName,new Class[]{method args} * from the Class object on the stack */ // load the static superclass Class onto the stack staticAdapter.getStatic(newClassType, currentClassFieldName, CLASS_TYPE); // push the method name string arg onto the stack staticAdapter.push(name); // create an array of the method parm class[] arg staticAdapter.push(targetMethodParameters.length); staticAdapter.newArray(CLASS_TYPE); int index = 0; for (Type t : targetMethodParameters) { staticAdapter.dup(); staticAdapter.push(index); switch (t.getSort()) { case Type.BOOLEAN: staticAdapter.getStatic(Type.getType(java.lang.Boolean.class), "TYPE", CLASS_TYPE); break; case Type.BYTE: staticAdapter.getStatic(Type.getType(java.lang.Byte.class), "TYPE", CLASS_TYPE); break; case Type.CHAR: staticAdapter.getStatic(Type.getType(java.lang.Character.class), "TYPE", CLASS_TYPE); break; case Type.DOUBLE: staticAdapter.getStatic(Type.getType(java.lang.Double.class), "TYPE", CLASS_TYPE); break; case Type.FLOAT: staticAdapter.getStatic(Type.getType(java.lang.Float.class), "TYPE", CLASS_TYPE); break; case Type.INT: staticAdapter.getStatic(Type.getType(java.lang.Integer.class), "TYPE", CLASS_TYPE); break; case Type.LONG: staticAdapter.getStatic(Type.getType(java.lang.Long.class), "TYPE", CLASS_TYPE); break; case Type.SHORT: staticAdapter.getStatic(Type.getType(java.lang.Short.class), "TYPE", CLASS_TYPE); break; default: case Type.OBJECT: staticAdapter.push(t); break; } staticAdapter.arrayStore(CLASS_TYPE); index++; } // invoke the getMethod staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getDeclaredMethod", METHOD_TYPE, new Type[] { STRING_TYPE, Type.getType(java.lang.Class[].class) })); // store the reflected method in the static field staticAdapter.putStatic(newClassType, methodStaticFieldName, METHOD_TYPE); /* * Stage 2 call the ih.invoke(this,supermethod,parms) */ // load this to get the ih field methodAdapter.loadThis(); // load the invocation handler from the field (the location of the // InvocationHandler.invoke) methodAdapter.getField(newClassType, IH_FIELD, IH_TYPE); // loadThis (the first arg of the InvocationHandler.invoke) methodAdapter.loadThis(); // load the method to invoke (the second arg of the // InvocationHandler.invoke) methodAdapter.getStatic(newClassType, methodStaticFieldName, METHOD_TYPE); // load all the method arguments onto the stack as an object array (the // third arg of the InvocationHandler.invoke) methodAdapter.loadArgArray(); // generate the invoke method Method invocationHandlerInvokeMethod = new Method("invoke", OBJECT_TYPE, new Type[] { OBJECT_TYPE, METHOD_TYPE, Type.getType(java.lang.Object[].class) }); // call the invoke method of the invocation handler methodAdapter.invokeInterface(IH_TYPE, invocationHandlerInvokeMethod); /* * Stage 3 the returned object is now on the top of the stack We need to * check the type and cast as necessary */ switch (returnType.getSort()) { case Type.BOOLEAN: methodAdapter.cast(OBJECT_TYPE, Type.getType(Boolean.class)); methodAdapter.unbox(Type.BOOLEAN_TYPE); break; case Type.BYTE: methodAdapter.cast(OBJECT_TYPE, Type.getType(Byte.class)); methodAdapter.unbox(Type.BYTE_TYPE); break; case Type.CHAR: methodAdapter.cast(OBJECT_TYPE, Type.getType(Character.class)); methodAdapter.unbox(Type.CHAR_TYPE); break; case Type.DOUBLE: methodAdapter.cast(OBJECT_TYPE, Type.getType(Double.class)); methodAdapter.unbox(Type.DOUBLE_TYPE); break; case Type.FLOAT: methodAdapter.cast(OBJECT_TYPE, Type.getType(Float.class)); methodAdapter.unbox(Type.FLOAT_TYPE); break; case Type.INT: methodAdapter.cast(OBJECT_TYPE, Type.getType(Integer.class)); methodAdapter.unbox(Type.INT_TYPE); break; case Type.LONG: methodAdapter.cast(OBJECT_TYPE, Type.getType(Long.class)); methodAdapter.unbox(Type.LONG_TYPE); break; case Type.SHORT: methodAdapter.cast(OBJECT_TYPE, Type.getType(Short.class)); methodAdapter.unbox(Type.SHORT_TYPE); break; case Type.VOID: methodAdapter.cast(OBJECT_TYPE, Type.getType(Void.class)); methodAdapter.unbox(Type.VOID_TYPE); break; default: case Type.OBJECT: // in this case check the cast and cast the object to the return // type methodAdapter.checkCast(returnType); methodAdapter.cast(OBJECT_TYPE, returnType); break; } // return the (appropriately cast) result of the invocation from the // stack methodAdapter.returnValue(); // end the method methodAdapter.endMethod(); LOGGER.debug(Constants.LOG_EXIT, "processMethod"); }
From source file:org.apache.aries.proxy.impl.interfaces.InterfaceCombiningClassAdapter.java
License:Apache License
@Override public final MethodVisitor visitMethod(int access, String name, String desc, String sig, String[] arg4) { //If we already implement this method (from another interface) then we don't //want a duplicate. We also don't want to copy any static init blocks (these //initialize static fields on the interface that we don't copy if (adapter.getKnownMethods().contains(new Method(name, desc)) || "<clinit>".equals(name)) { return null; } else if (((access & (ACC_PRIVATE | ACC_SYNTHETIC)) == (ACC_PRIVATE | ACC_SYNTHETIC))) { // private, synthetic methods on interfaces don't need to be proxied. return null; } else {//We're going to implement this method, so make it non abstract! return adapter.visitMethod(access, name, desc, null, arg4); }//from w w w . j av a2 s. c o m }
From source file:org.apache.commons.weaver.normalizer.Normalizer.java
License:Apache License
/** * Create the normalized version of a given class in the configured target package. The {@link Normalizer} will * gladly do so in a package from which the normalized class will not actually be able to reference any types upon * which it relies; in such a situation you must specify the target package as the package of the supertype. * @param key used to generate the normalized classname. * @param classWrapper/*from w w w.ja v a 2 s .c om*/ * @return the generated classname. * @throws IOException */ private String copy(final Pair<String, String> key, final ClassWrapper classWrapper) throws IOException { env.debug("Copying %s to %s", key, targetPackage); final MessageDigest md5; try { md5 = MessageDigest.getInstance("MD5"); } catch (final NoSuchAlgorithmException e) { throw new IllegalStateException(e); } md5.update(key.getLeft().getBytes(StandardCharsets.UTF_8)); md5.update(key.getRight().getBytes(StandardCharsets.UTF_8)); final long digest = Conversion.byteArrayToLong(md5.digest(), 0, 0L, 0, Long.SIZE / Byte.SIZE); final String result = MessageFormat.format("{0}/$normalized{1,number,0;_0}", targetPackage, digest); env.debug("Copying class %s to %s", classWrapper.wrapped.getName(), result); try (InputStream bytecode = env.getClassfile(classWrapper.wrapped).getInputStream()) { final ClassReader reader = new ClassReader(bytecode); final ClassVisitor writeClass = new WriteClass(); // we're doing most of this by hand; we only read the original class to hijack signature, ctor exceptions, // etc.: reader.accept(new ClassVisitor(ASM_VERSION) { Type supertype; @Override @SuppressWarnings("PMD.UseVarargs") //overridden method public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { supertype = Type.getObjectType(superName); writeClass.visit(version, Opcodes.ACC_PUBLIC, result, signature, superName, interfaces); visitAnnotation(Type.getType(Marker.class).getDescriptor(), false); } @Override @SuppressWarnings("PMD.UseVarargs") //overridden method public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { if (INIT.equals(name)) { final Method staticCtor = new Method(INIT, key.getRight()); final Type[] argumentTypes = staticCtor.getArgumentTypes(); final Type[] exceptionTypes = toObjectTypes(exceptions); { final GeneratorAdapter mgen = new GeneratorAdapter(Opcodes.ACC_PUBLIC, staticCtor, signature, exceptionTypes, writeClass); mgen.visitCode(); mgen.loadThis(); for (int i = 0; i < argumentTypes.length; i++) { mgen.loadArg(i); } mgen.invokeConstructor(supertype, staticCtor); mgen.returnValue(); mgen.endMethod(); } /* * now declare a dummy constructor that will match, and discard, * any originally inner-class bound constructor i.e. that set up a this$0 field. * By doing this we can avoid playing with the stack that originally * invoked such a constructor and simply rewrite the method */ { final Method instanceCtor = new Method(INIT, Type.VOID_TYPE, ArrayUtils.insert(0, argumentTypes, OBJECT_TYPE)); final GeneratorAdapter mgen = new GeneratorAdapter(Opcodes.ACC_PUBLIC, instanceCtor, signature, exceptionTypes, writeClass); mgen.visitCode(); mgen.loadThis(); for (int i = 0; i < argumentTypes.length; i++) { mgen.loadArg(i + 1); } mgen.invokeConstructor(supertype, staticCtor); mgen.returnValue(); mgen.endMethod(); } return null; } return null; } @Override public void visitEnd() { writeClass.visitEnd(); } }, 0); } return result; }
From source file:org.apache.commons.weaver.privilizer.ActionGenerator.java
License:Apache License
/** * Create a new {@link ActionGenerator}. * @param access modifier//w w w . ja v a2 s .c om * @param methd {@link Method} to implement * @param exceptions thrown * @param owner of the action class */ ActionGenerator(final int access, final Method methd, final String[] exceptions, final PrivilizingVisitor owner) { owner.privilizer().super(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); this.methd = methd; this.exc = ArrayUtils.isNotEmpty(exceptions); this.exceptions = exc ? new Type[] { Type.getType(Exception.class) } : null; this.owner = owner; this.simpleName = generateName(methd); this.action = Type.getObjectType(owner.className + '$' + simpleName); int privilegedAccessIndex = -1; String implName = null; for (final Map.Entry<Method, String> entry : owner.privilegedMethods.entrySet()) { privilegedAccessIndex++; if (entry.getKey().equals(methd)) { implName = entry.getValue(); break; } } Validate.validState(implName != null); this.index = privilegedAccessIndex; this.impl = new Method(implName, methd.getDescriptor()); this.implIsStatic = Modifier.isStatic(access); final Type[] args = implIsStatic ? methd.getArgumentTypes() : ArrayUtils.insert(0, methd.getArgumentTypes(), owner.target); this.helper = new Method(privilizer().generateName("access$" + index), methd.getReturnType(), args); this.result = Privilizer.wrap(methd.getReturnType()); this.fields = fields(args); this.actionInterface = Type.getType(exc ? PrivilegedExceptionAction.class : PrivilegedAction.class); }
From source file:org.apache.commons.weaver.privilizer.BlueprintingVisitor.java
License:Apache License
private static Pair<Type, Method> methodKey(String owner, String name, String desc) { return Pair.of(Type.getObjectType(owner), new Method(name, desc)); }
From source file:org.apache.commons.weaver.privilizer.BlueprintingVisitor.java
License:Apache License
private TypeInfo typeInfo(Type type) { return typeInfoCache.computeIfAbsent(type, k -> { final ClassNode cn = read(k.getClassName()); return new TypeInfo(cn.access, cn.superName, cn.fields.stream().collect(Collectors.toMap(f -> f.name, Function.identity())), cn.methods.stream()//from w w w. j a v a 2 s . c o m .collect(Collectors.toMap(m -> new Method(m.name, m.desc), Function.identity()))); }); }
From source file:org.apache.commons.weaver.privilizer.PrivilizingVisitor.java
License:Apache License
@Override @SuppressWarnings("PMD.UseVarargs") //overridden method public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { annotate();/*from ww w .j a v a 2s . com*/ final MethodVisitor originalMethod = super.visitMethod(access, name, desc, signature, exceptions); final Method methd = new Method(name, desc); return new GeneratorAdapter(Privilizer.ASM_VERSION, originalMethod, access, name, desc) { @Override public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { if (Type.getType(Privileged.class).getDescriptor().equals(desc)) { final AccessLevel localAccessLevel = AccessLevel.of(access); if (accessLevel.compareTo(localAccessLevel) > 0) { throw new IllegalStateException(new IllegalAccessException( "Method " + className + "#" + methd + " must have maximum access level '" + accessLevel + "' but is defined wider ('" + localAccessLevel + "')")); } if (AccessLevel.PACKAGE.compareTo(accessLevel) > 0) { privilizer().env.warn("Possible security leak: granting privileges to %s method %s.%s", localAccessLevel, className, methd); } privilegedMethods.put(methd, privilizer().generateName(name)); } return super.visitAnnotation(desc, visible); } @Override public void visitCode() { super.visitCode(); if (!privilegedMethods.containsKey(methd)) { return; } final String impl = privilegedMethods.get(methd); final boolean instanceMethod = !Modifier.isStatic(access); if (policy.isConditional()) { privilizer().env.debug("setting up conditional execution due to policy %s", policy); // test, loading boolean if (policy == Policy.ON_INIT) { getStatic(target, privilizer().generateName("hasSecurityManager"), Type.BOOLEAN_TYPE); } else if (policy == Policy.DYNAMIC) { checkSecurityManager(this); } final Label doPrivileged = new Label(); // if true, goto doPrivileged: ifZCmp(NE, doPrivileged); final Method implMethod = new Method(impl, desc); if (instanceMethod) { loadThis(); loadArgs(); invokeVirtual(target, implMethod); } else { loadArgs(); invokeStatic(target, implMethod); } returnValue(); mark(doPrivileged); } else { privilizer().env.debug("setting up unconditional privileged execution due to policy %s", policy); } // generate action: final Type[] ctorArgs = instanceMethod ? ArrayUtils.insert(0, methd.getArgumentTypes(), target) : methd.getArgumentTypes(); final Type actionType = new ActionGenerator(access, methd, exceptions, PrivilizingVisitor.this) .build(); newInstance(actionType); dup(); if (instanceMethod) { loadThis(); } loadArgs(); invokeConstructor(actionType, new Method("<init>", Type.VOID_TYPE, ctorArgs)); final boolean exc = ArrayUtils.isNotEmpty(exceptions); // mark try if needed final Label privTry = exc ? mark() : null; // execute action final Type arg = exc ? Type.getType(PrivilegedExceptionAction.class) : Type.getType(PrivilegedAction.class); final Method doPrivileged = new Method("doPrivileged", Type.getType(Object.class), new Type[] { arg }); invokeStatic(Type.getType(AccessController.class), doPrivileged); unbox(methd.getReturnType()); returnValue(); if (exc) { final Type caught = Type.getType(PrivilegedActionException.class); // end try final Label privCatch = mark(); // catch catchException(privTry, privCatch, caught); // unwrap invokeVirtual(caught, new Method("getException", Type.getType(Exception.class), Privilizer.EMPTY_TYPE_ARRAY)); // throw throwException(); } // end original method endMethod(); // substitute an impl visitor and continue mv = cv.visitMethod(AccessLevel.PRIVATE.merge(access), impl, desc, signature, exceptions); mv.visitCode(); } }; }