List of usage examples for org.objectweb.asm ClassVisitor ClassVisitor
public ClassVisitor(final int api)
From source file:com.tencent.tinker.build.immutable.ClassSimDef.java
License:Open Source License
public void init() { methodCount = 0;/*from ww w . ja v a 2 s. c o m*/ fieldCount = 0; ClassReader cr = new ClassReader(bytes); ClassVisitor cv = new ClassVisitor(Opcodes.ASM4) { String className; @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { className = name; super.visit(version, access, name, signature, superName, interfaces); } @Override public MethodVisitor visitMethod(int access, String mtdName, String mtdDesc, String mtdSig, String[] exceptions) { String defMtd = className + ":" + mtdName + ":" + mtdDesc; if (!refMtdSet.contains(defMtd)) { refMtdSet.add(defMtd); methodCount++; } MethodVisitor mv = super.visitMethod(access, mtdName, mtdDesc, mtdSig, exceptions); mv = new MethodVisitor(Opcodes.ASM4, mv) { @Override public void visitFieldInsn(int opcode, String owner, String fName, String fDesc) { String invokeField = owner + ":" + fName + ":" + fDesc; if (!refFieldSet.contains(invokeField)) { refFieldSet.add(invokeField); fieldCount++; } super.visitFieldInsn(opcode, owner, fName, fDesc); } @Override public void visitMethodInsn(int opcode, String owner, String mName, String mDesc) { String invokeMtd = owner + ":" + mName + ":" + mDesc; if (!refMtdSet.contains(invokeMtd)) { refMtdSet.add(invokeMtd); methodCount++; } super.visitMethodInsn(opcode, owner, mName, mDesc); } }; return mv; } @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { String fieldDesc = className + ":" + name + ":" + desc; if (!refFieldSet.contains(fieldDesc)) { refFieldSet.add(fieldDesc); fieldCount++; } return super.visitField(access, name, desc, signature, value); } }; cr.accept(cv, 0); }
From source file:com.test.api.checker.tests.ASMHelloWorld.java
License:Apache License
/** * @param args/*w ww . j a v a2 s . c o m*/ * @throws IOException */ public static void main(String[] args) throws IOException { ClassVisitor cl = new ClassVisitor(Opcodes.ASM4) { /** * Called when a class is visited. This is the method called first */ @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { System.out.println("Visiting class: " + name); System.out.println("Class Major Version: " + version); System.out.println("Super class: " + superName); super.visit(version, access, name, signature, superName, interfaces); } /** * Invoked only when the class being visited is an inner class */ @Override public void visitOuterClass(String owner, String name, String desc) { System.out.println("Outer class: " + owner); super.visitOuterClass(owner, name, desc); } /** *Invoked when a class level annotation is encountered */ @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { System.out.println("Annotation: " + desc); return super.visitAnnotation(desc, visible); } /** * When a class attribute is encountered */ @Override public void visitAttribute(Attribute attr) { System.out.println("Class Attribute: " + attr.type); super.visitAttribute(attr); } /** *When an inner class is encountered */ @Override public void visitInnerClass(String name, String outerName, String innerName, int access) { System.out.println("Inner Class: " + innerName + " defined in " + outerName); super.visitInnerClass(name, outerName, innerName, access); } /** * When a field is encountered */ @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { System.out.println("Field: " + name + " " + desc + " value:" + value); return super.visitField(access, name, desc, signature, value); } @Override public void visitEnd() { System.out.println("Method ends here"); super.visitEnd(); } /** * When a method is encountered */ @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { System.out.println("Method: " + name + " " + desc); return super.visitMethod(access, name, desc, signature, exceptions); } /** * When the optional source is encountered */ @Override public void visitSource(String source, String debug) { System.out.println("Source: " + source); super.visitSource(source, debug); } }; InputStream in = ASMHelloWorld.class.getResourceAsStream("/java/lang/String.class"); ClassReader classReader = new ClassReader(in); classReader.accept(cl, 0); }
From source file:com.tsc9526.monalisa.tools.clazz.MelpAsm.java
License:Open Source License
public static String[] getMethodParamNames(final Method m) { final String[] paramNames = new String[m.getParameterTypes().length]; final String n = m.getDeclaringClass().getName(); ClassReader cr = null;//from w ww .j av a2 s . com try { cr = new ClassReader(n); } catch (IOException e) { throw new RuntimeException(e); } cr.accept(new ClassVisitor(Opcodes.ASM5) { public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { final Type[] args = Type.getArgumentTypes(desc); // ????? if (!name.equals(m.getName()) || !sameType(args, m.getParameterTypes())) { return super.visitMethod(access, name, desc, signature, exceptions); } MethodVisitor v = super.visitMethod(access, name, desc, signature, exceptions); return new MethodVisitor(Opcodes.ASM5, v) { public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { int i = index - 1; // ??? // ???"this"??? if (Modifier.isStatic(m.getModifiers())) { i = index; } if (i >= 0) { setParamName(paramNames, name); } super.visitLocalVariable(name, desc, signature, start, end, index); } }; } }, 0); return paramNames; }
From source file:com.wolvereness.renumerated.Renumerated.java
License:Open Source License
private void process() throws Throwable { validateInput();// ww w. j av a 2 s . c om final MultiProcessor executor = MultiProcessor.newMultiProcessor(cores - 1, new ThreadFactoryBuilder().setDaemon(true) .setNameFormat(Renumerated.class.getName() + "-processor-%d") .setUncaughtExceptionHandler(this).build()); final Future<?> fileCopy = executor.submit(new Callable<Object>() { @Override public Object call() throws Exception { if (original != null) { if (original.exists()) { original.delete(); } Files.copy(input, original); } return null; } }); final List<Pair<ZipEntry, Future<byte[]>>> fileEntries = newArrayList(); final List<Pair<MutableObject<ZipEntry>, Future<byte[]>>> classEntries = newArrayList(); { final ZipFile input = new ZipFile(this.input); final Enumeration<? extends ZipEntry> inputEntries = input.entries(); while (inputEntries.hasMoreElements()) { final ZipEntry entry = inputEntries.nextElement(); final Future<byte[]> future = executor.submit(new Callable<byte[]>() { @Override public byte[] call() throws Exception { return ByteStreams.toByteArray(input.getInputStream(entry)); } }); if (entry.getName().endsWith(".class")) { classEntries.add(new MutablePair<MutableObject<ZipEntry>, Future<byte[]>>( new MutableObject<ZipEntry>(entry), future)); } else { fileEntries.add(new ImmutablePair<ZipEntry, Future<byte[]>>(entry, future)); } } for (final Pair<MutableObject<ZipEntry>, Future<byte[]>> pair : classEntries) { final byte[] data = pair.getRight().get(); pair.setValue(executor.submit(new Callable<byte[]>() { String className; List<String> fields; @Override public byte[] call() throws Exception { try { return method(); } catch (final Exception ex) { throw new Exception(pair.getLeft().getValue().getName(), ex); } } private byte[] method() throws Exception { final ClassReader clazz = new ClassReader(data); clazz.accept(new ClassVisitor(ASM4) { @Override public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) { if (superName.equals("java/lang/Enum")) { className = name; } } @Override public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) { if (className != null && (access & 0x4000) != 0) { List<String> fieldNames = fields; if (fieldNames == null) { fieldNames = fields = newArrayList(); } fieldNames.add(name); } return null; } }, ClassReader.SKIP_CODE); if (className == null) return data; final String classDescriptor = Type.getObjectType(className).getDescriptor(); final ClassWriter writer = new ClassWriter(0); clazz.accept(new ClassVisitor(ASM4, writer) { @Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { final MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); if (!name.equals("<clinit>")) { return methodVisitor; } return new MethodVisitor(ASM4, methodVisitor) { final Iterator<String> it = fields.iterator(); boolean active; String lastName; @Override public void visitTypeInsn(final int opcode, final String type) { if (!active && it.hasNext()) { // Initiate state machine if (opcode != NEW) throw new AssertionError("Unprepared for " + opcode + " on " + type + " in " + className); active = true; } super.visitTypeInsn(opcode, type); } @Override public void visitLdcInsn(final Object cst) { if (active && lastName == null) { if (!(cst instanceof String)) throw new AssertionError( "Unprepared for " + cst + " in " + className); // Switch the first constant in the Enum constructor super.visitLdcInsn(lastName = it.next()); } else { super.visitLdcInsn(cst); } } @Override public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { if (opcode == PUTSTATIC && active && lastName != null && owner.equals(className) && desc.equals(classDescriptor) && name.equals(lastName)) { // Finish the current state machine active = false; lastName = null; } super.visitFieldInsn(opcode, owner, name, desc); } }; } }, ClassReader.EXPAND_FRAMES); final MutableObject<ZipEntry> key = pair.getLeft(); key.setValue(new ZipEntry(key.getValue().getName())); return writer.toByteArray(); } })); } for (final Pair<ZipEntry, Future<byte[]>> pair : fileEntries) { pair.getRight().get(); } input.close(); } fileCopy.get(); FileOutputStream fileOut = null; JarOutputStream jar = null; try { jar = new JarOutputStream(fileOut = new FileOutputStream(output)); for (final Pair<ZipEntry, Future<byte[]>> fileEntry : fileEntries) { jar.putNextEntry(fileEntry.getLeft()); jar.write(fileEntry.getRight().get()); } for (final Pair<MutableObject<ZipEntry>, Future<byte[]>> classEntry : classEntries) { final byte[] data = classEntry.getRight().get(); final ZipEntry entry = classEntry.getLeft().getValue(); entry.setSize(data.length); jar.putNextEntry(entry); jar.write(data); } } finally { if (jar != null) { try { jar.close(); } catch (final IOException ex) { } } if (fileOut != null) { try { fileOut.close(); } catch (final IOException ex) { } } } final Pair<Thread, Throwable> uncaught = this.uncaught; if (uncaught != null) throw new MojoExecutionException(String.format("Uncaught exception in %s", uncaught.getLeft()), uncaught.getRight()); }
From source file:de.thetaphi.forbiddenapis.ClassSignature.java
License:Apache License
public ClassSignature(final ClassReader classReader, boolean isRuntimeClass, boolean withReader) { this.reader = withReader ? classReader : null; this.isRuntimeClass = isRuntimeClass; this.className = classReader.getClassName(); this.superName = classReader.getSuperName(); this.interfaces = classReader.getInterfaces(); final Set<Method> methods = new HashSet<Method>(); final Set<String> fields = new HashSet<String>(); classReader.accept(new ClassVisitor(Opcodes.ASM5) { @Override/*www . ja va 2 s . c om*/ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { final Method m = new Method(name, desc); methods.add(m); return null; } @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { fields.add(name); return null; } }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); this.methods = Collections.unmodifiableSet(methods); this.fields = Collections.unmodifiableSet(fields); }
From source file:de.thetaphi.forbiddenapis.DeprecatedGen.java
License:Apache License
protected void parseClass(InputStream in) throws IOException { final ClassReader reader; try {/*from w w w. j av a2 s. c om*/ reader = new ClassReader(in); } catch (IllegalArgumentException iae) { // unfortunately the ASM IAE has no message, so add good info! throw new IllegalArgumentException( "The class file format of your runtime seems to be too recent to be parsed by ASM (may need to be upgraded)."); } final String className = Type.getObjectType(reader.getClassName()).getClassName(); // exclude internal classes like Unsafe,... and non-public classes! // Note: reader.getAccess() does no indicate if class is deprecated, as this is a special // attribute or annotation (both is handled later), we have to parse the class - this is just early exit! if ((reader.getAccess() & ACC_PUBLIC) == 0 || AsmUtils.isInternalClass(className)) { return; } reader.accept(new ClassVisitor(ASM5) { boolean classDeprecated = false; @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { if (isDeprecated(access)) { deprecated.add(className); classDeprecated = true; } } @Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { if (!classDeprecated && isDeprecated(access)) { final Type[] args = Type.getType(desc).getArgumentTypes(); final StringBuilder sb = new StringBuilder(className).append('#').append(name).append('('); boolean comma = false; for (final Type t : args) { if (comma) sb.append(','); sb.append(t.getClassName()); comma = true; } sb.append(')'); deprecated.add(sb.toString()); } return null; } @Override public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) { if (!classDeprecated && isDeprecated(access)) { deprecated.add(className + '#' + name); } return null; } }, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); }
From source file:edu.umd.cs.findbugs.classfile.engine.ClassParserUsingASM.java
License:Open Source License
@Override public void parse(final ClassNameAndSuperclassInfo.Builder cBuilder) throws InvalidClassFileFormatException { cBuilder.setCodeBaseEntry(codeBaseEntry); final TreeSet<ClassDescriptor> calledClassSet = new TreeSet<ClassDescriptor>(); classReader.accept(new ClassVisitor(FindBugsASM.ASM_VERSION) { // boolean isInnerClass = false; @Override/* w w w. j a v a 2 s. com*/ public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { ClassParserUsingASM.this.slashedClassName = name; cBuilder.setClassfileVersion(version >>> 16, version & 0xffff); cBuilder.setAccessFlags(access); cBuilder.setClassDescriptor(DescriptorFactory.createClassDescriptor(name)); cBuilder.setInterfaceDescriptorList(DescriptorFactory.createClassDescriptor(interfaces)); if (superName != null) { cBuilder.setSuperclassDescriptor(DescriptorFactory.createClassDescriptor(superName)); } if (cBuilder instanceof ClassInfo.Builder) { ((ClassInfo.Builder) cBuilder).setSourceSignature(signature); } } @Override public org.objectweb.asm.AnnotationVisitor visitAnnotation(String desc, boolean isVisible) { if (cBuilder instanceof ClassInfo.Builder) { AnnotationValue value = new AnnotationValue(desc); ((ClassInfo.Builder) cBuilder).addAnnotation(desc, value); return value.getAnnotationVisitor(); } return null; } @Override public void visitAttribute(Attribute arg0) { // } @Override public void visitEnd() { // } @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { // if (name.equals("this$0")) // isInnerClass = true; if (desc == null) { throw new NullPointerException("Description cannot be null"); } if (cBuilder instanceof ClassInfo.Builder) { final ClassInfo.Builder cBuilder2 = (ClassInfo.Builder) cBuilder; if ((access & Opcodes.ACC_VOLATILE) != 0 || desc.contains("util/concurrent")) { cBuilder2.setUsesConcurrency(); } final FieldInfo.Builder fBuilder = new FieldInfo.Builder(slashedClassName, name, desc, access); fBuilder.setSourceSignature(signature); return new AbstractFieldAnnotationVisitor() { @Override public org.objectweb.asm.AnnotationVisitor visitAnnotation(final String desc, boolean visible) { AnnotationValue value = new AnnotationValue(desc); fBuilder.addAnnotation(desc, value); return value.getAnnotationVisitor(); } @Override public void visitEnd() { cBuilder2.addFieldDescriptor(fBuilder.build()); } }; } return null; } @Override public void visitInnerClass(String name, String outerName, String innerName, int access) { if (name.equals(slashedClassName) && outerName != null) { if (cBuilder instanceof ClassInfo.Builder) { ClassDescriptor outerClassDescriptor = DescriptorFactory.createClassDescriptor(outerName); ((ClassInfo.Builder) cBuilder).setImmediateEnclosingClass(outerClassDescriptor); ((ClassInfo.Builder) cBuilder).setAccessFlags(access); } } } @Override public MethodVisitor visitMethod(final int access, final String methodName, final String methodDesc, String signature, String[] exceptions) { if (cBuilder instanceof ClassInfo.Builder) { final MethodInfo.Builder mBuilder = new MethodInfo.Builder(slashedClassName, methodName, methodDesc, access); mBuilder.setSourceSignature(signature); mBuilder.setThrownExceptions(exceptions); if ((access & Opcodes.ACC_SYNCHRONIZED) != 0) { mBuilder.setUsesConcurrency(); } return new ClassParserMethodVisitor(calledClassSet, mBuilder, methodName, access, methodDesc, cBuilder); } return null; } @Override public void visitOuterClass(String owner, String name, String desc) { } @Override public void visitSource(String arg0, String arg1) { if (cBuilder instanceof ClassInfo.Builder) { ((ClassInfo.Builder) cBuilder).setSource(arg0); } } }, ClassReader.SKIP_FRAMES); HashSet<ClassDescriptor> referencedClassSet = new HashSet<ClassDescriptor>(); // collect class references int constantPoolCount = classReader.readUnsignedShort(8); int offset = 10; char[] buf = new char[1024]; // System.out.println("constant pool count: " + constantPoolCount); for (int count = 1; count < constantPoolCount; count++) { int tag = classReader.readByte(offset); int size; switch (tag) { case Constants.CONSTANT_Methodref: case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Fieldref: case Constants.CONSTANT_Integer: case Constants.CONSTANT_Float: case Constants.CONSTANT_NameAndType: case Constants.CONSTANT_InvokeDynamic: size = 5; break; case Constants.CONSTANT_Long: case Constants.CONSTANT_Double: size = 9; count++; break; case Constants.CONSTANT_Utf8: size = 3 + classReader.readUnsignedShort(offset + 1); break; case Constants.CONSTANT_Class: @SlashedClassName String className = classReader.readUTF8(offset + 1, buf); if (className.indexOf('[') >= 0) { ClassParser.extractReferencedClassesFromSignature(referencedClassSet, className); } else if (ClassName.isValidClassName(className)) { ClassDescriptor classDescriptor = DescriptorFactory.instance().getClassDescriptor(className); referencedClassSet.add(classDescriptor); } size = 3; break; case Constants.CONSTANT_String: case Constants.CONSTANT_MethodType: size = 3; break; case Constants.CONSTANT_MethodHandle: size = 4; break; default: throw new IllegalStateException("Unexpected tag of " + tag + " at offset " + offset + " while parsing " + slashedClassName + " from " + codeBaseEntry); } // System.out.println(count + "@" + offset + " : [" + tag // +"] size="+size); offset += size; } cBuilder.setCalledClassDescriptors(calledClassSet); cBuilder.setReferencedClassDescriptors(referencedClassSet); }
From source file:edu.umd.cs.findbugs.classfile.engine.SelfMethodCalls.java
License:Open Source License
public static <T> MultiMap<T, T> getSelfCalls(final ClassDescriptor classDescriptor, final Map<String, T> methods) { final MultiMap<T, T> map = new MultiMap<T, T>(HashSet.class); FBClassReader reader;/* w w w . j av a2 s .com*/ try { reader = Global.getAnalysisCache().getClassAnalysis(FBClassReader.class, classDescriptor); } catch (CheckedAnalysisException e) { AnalysisContext.logError("Error finding self method calls for " + classDescriptor, e); return map; } reader.accept(new ClassVisitor(FindBugsASM.ASM_VERSION) { @Override public MethodVisitor visitMethod(final int access, final String name, final String desc, String signature, String[] exceptions) { return new MethodVisitor(FindBugsASM.ASM_VERSION) { @Override public void visitMethodInsn(int opcode, String owner, String name2, String desc2, boolean itf) { if (owner.equals(classDescriptor.getClassName()) && interestingSignature(desc2)) { T from = methods.get(name + desc + ((access & Opcodes.ACC_STATIC) != 0)); T to = methods.get(name2 + desc2 + (opcode == Opcodes.INVOKESTATIC)); map.add(from, to); } } }; } }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); return map; }
From source file:jaspex.speculation.Cache.java
License:Open Source License
public static byte[] lookupClass(Type className) { try {//from w w w. jav a2 s . c o m byte[] classBytes = IOUtils.readFile(new File(CACHE_DIR + className.commonName() + ".class")); ClassReader cr = new ClassReader(classBytes); final String[] hash = new String[1]; cr.accept(new ClassVisitor(Opcodes.ASM4) { @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { if (name.equals(CLASS_HASH_FIELD)) hash[0] = (String) value; return null; } }, 0); if (hash[0] == null) throw new Error("Unexpected class file found in cache"); if (!hash[0].equals(hashClass(className))) { clearCache(); // Ver nota no inicio do ficheiro sobre porque que isto tem de dar erro throw new Error("Invalid class in cache, clear cache and re-run"); } return classBytes; } catch (FileNotFoundException e) { return null; } catch (IOException e) { throw new Error(e); } }
From source file:jaspex.transactifier.Transactifier.java
License:Open Source License
private byte[] transactify() throws IOException { final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); // Copiar mtodos originais inalterados cr.accept(new ClassVisitor(Opcodes.ASM4) { @Override/*from ww w.j a v a 2s .co m*/ public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { cw.visit(version, access, name, signature, superName, interfaces); } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals("<clinit>")) return new EmptyMethodVisitor(); return cw.visitMethod(access, name, desc, signature, exceptions); } @Override public void visitEnd() { cw.visitEnd(); } }, 0); // Varivel que contm o ltimo ClassVisitor da "chain" de classvisitors que servem de filtros ao // ficheiro original ClassVisitor cv = cw; // Mtodos alterados so marcados com $transactional no nome // Este marcador temporrio, e ir ser substituido por $speculative mais frente // Nota: Apenas os mtodos so renomeados, os seus INVOKE* ainda no apontam para os // $transactional; essa alterao feita no SpeculativeTransformer cv = new ClassVisitor(Opcodes.ASM4, cv) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals("<init>")) { desc = desc.replace(")", "Ljaspex/MARKER/Transactional;)"); } else if (!name.equals("<clinit>")) { name += "$transactional"; } return cv.visitMethod(access, name, desc, signature, exceptions); } }; // Remover ACC_SYNCHRONIZED dos mtodos if (Options.REMOVESYNC || _JDKClass) cv = new RemoveSyncClassVisitor(cv); // Remover MONITORENTER/MONITOREXIT dos mtodos if (Options.REMOVEMONITORS) cv = new GenericMethodVisitorAdapter(cv, RemoveMonitorsClassVisitor.class); // Verificar se existem mtodos com ACC_SYNCHRONIZED ou opcodes MONITORENTER/MONITOREXIT if (!_JDKClass) cv = new CheckMonitorUsage(cv); // Corrigir chamadas a alguns mtodos de java.lang.Object cv = new GenericMethodVisitorAdapter(cv, ChangeObjectMethodsMethodVisitor.class, currentClass); // Adicionar overrides a alguns mtodos de java.lang.Object cv = new AddObjectMethodsClassVisitor(cv, currentClass); // Suporte para Arrays cv = new GenericMethodVisitorAdapter(cv, ChangeArrayAccessMethodVisitor.class, currentClass, _JDKClass); // Adicionar inicializao de offsets usados pela unsafetrans ao clinit da classe // Nota: Visitor tem que estar *depois* do FieldTransactifierClassVisitor if (!_JDKClass) cv = new GenericMethodVisitorAdapter(cv, ChangeClinitMethodVisitor.class, currentClass); // Visitor que cria os fields offset e o staticfieldbase if (!_JDKClass) cv = new FieldTransactifierClassVisitor(cv); // Alterar acessos a fields para passarem pela STM cv = new GenericMethodVisitorAdapter(cv, ChangeFieldAccessMethodVisitor.class, currentClass, _JDKClass); // Modificar string com filename da classe que aparece em excepes if (!_JDKClass) cv = new MarkAsTransactifiedClassVisitor(cv); // Verificar e fazer upgrade da verso da classe, se necessrio if (!_JDKClass) cv = new ClassVisitor(Opcodes.ASM4, cv) { @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { // Transactificao precisa de version >= 49, porque usa o MethodVisitor.visitLdcInsn(Type) // MethodVisitor.visitLdcInsn(Type), que s funciona a partir dessa verso dos classfiles. // http://asm.ow2.org/asm40/javadoc/user/org/objectweb/asm/MethodVisitor.html#visitLdcInsn(java.lang.Object) // http://stackoverflow.com/questions/2784791/ // Caso especial: V1_1 196653, por alguma razo... if (version < Opcodes.V1_5 || version == Opcodes.V1_1) { //Log.debug("Class " + name + " has version " + version + ", upgrading it to Java 5"); version = Opcodes.V1_5; } if (version > Opcodes.V1_6 && !name.startsWith("java/")) { Log.warn("Class " + name + " is compiled for Java 7 or newer"); } super.visit(version, access, name, signature, superName, interfaces); } }; cr.accept(cv, ClassReader.EXPAND_FRAMES); return cw.toByteArray(); }