2015-11-30 1 views
0

Для проекта, над которым я работаю, я пытаюсь переименовать классы внутри файла jar с помощью ASM. У меня это работает ... но есть улов. Каждый класс, который переименован в банку, имеет свои дубликаты.Повторяющиеся поля в переименованных классах (ASM + Jar)

Вот мой код:

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<ClassNode> 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"); 
} 

Пример вывода:

public static String VERSION; 
public static final ConfigFile config; 
public static String VERSION; 
public static final ConfigFile_Test config; 

Edit (3/28/2016): Возвращаясь после получения дополнительной информации о ASM вот как это должно сделано:

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<String, byte[]> 
    out.put(renamed.get(cn.name).getRenamed(), cw.toByteArray()); 
} 

Сурьма была права. Моя первоначальная идея назад, когда я разместил это, должен был отредактировать сам ClassNode (у меня было расширение ClassNode, которое обрабатывало все. Это было довольно неприятно). С момента перехода к реализации Remapper все работает намного лучше.

+0

Ну и что вам нужно? – Andremoniy

+0

Где код сборки? Я вижу только Java. Вы имели в виду вместо этого использовать тег java-bytecode-asm? –

+0

@PeterSmith Исправлен тег. Я забыл, что ASM будет расширяться в Assembly. @ Andremoniy Я пытаюсь переименовать файлы классов в файле jar. Функция переименования работает, но все поля дублируются в процессе. Это делает файл jar непригодным для использования. –

ответ

1
cr.accept(cn,ClassReader.EXPAND_FRAMES); 

Проблема в том, что вы вызываете прием на существующий ClassNode. ClassNode.visitField добавляет поле к узлу класса. Таким образом, все в ClassNode удваивается - одна копия из существующих данных и одна добавленная вами копия.

+0

Спасибо, я сделал дешевое обходное решение, создав класс, который расширяет ClassNode, чтобы предотвратить дублирование записей. –

Смежные вопросы