title: Duplicate fields in renamed classes (ASM + Jar)
body: <p>For a project I'm working on I'm trying to rename classes inside a jar file using ASM. I've got it working... but there's a catch. Each class that is renamed in the jar has it's fields duplicated.</p>
  
  <p>Here's my code:</p>
  
  <pre><code>import org.objectweb.asm.ClassReader;
  import org.objectweb.asm.ClassWriter;
  import org.objectweb.asm.commons.Remapper;
  import org.objectweb.asm.commons.RemappingClassAdapter;
  import org.objectweb.asm.commons.SimpleRemapper;
  import org.objectweb.asm.tree.ClassNode;
  //Imports showing which ASM (5.0.4) classes I'm using
  
  private static void doStuff() throws IOException {
      File jar = new File("Input.jar");
      //Get's the ClassNodes for each class in a jar
      ArrayList&lt;ClassNode&gt; nodes = BCU.loadClasses(jar);
      //Appends '_Test' to each class except for the main class.
      Remapper mapper = new SimpleRemapper(getRename(nodes));
      //Loop through the ClassNodes updating references to renamed classes
      for (ClassNode cn : nodes) {
           ClassReader cr = new ClassReader(BCU.getNodeBytes(cn));
           ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); 
           RemappingClassAdapter rca = new RemappingClassAdapter(cw, mapper); 
           cr.accept(rca, ClassReader.EXPAND_FRAMES); 
           cr = new ClassReader(cw.toByteArray()); 
           cr.accept(cn,ClassReader.EXPAND_FRAMES);
      }
      //Export the nodes as a new jar file and copy over the META-INF folder
      BCU.saveAsJar(nodes, "Output.jar");
  }
  </code></pre>
  
  <p>Example output:</p>
  
  <pre><code>public static String VERSION;
  public static final ConfigFile config;
  public static String VERSION;
  public static final ConfigFile_Test config;
  </code></pre>
  
  <hr>
  
  <p><strong>Edit (3/28/2016)</strong>: Coming back after learning more about ASM here's how it should be done:</p>
  
  <pre><code>for (ClassNode cn : nodes.values()) {
      ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
      //mapper is a Remapper instance
      ClassVisitor remapper = new RemappingClassAdapter(cw, mapper);
      cn.accept(remapper);
      //out = Map&lt;String, byte[]&gt;
      out.put(renamed.get(cn.name).getRenamed(), cw.toByteArray());
  }
  </code></pre>
  
  <p>Antimony was right. My original idea back when I posted this was to edit the ClassNode itself <em>(I had a ClassNode extension that handled everything. It was pretty nasty)</em>. Since moving to the Remapper implementation things have been working much better.</p>