2020-01-18 09:31:30 +03:00
|
|
|
package pro.gravit.launchserver;
|
|
|
|
|
|
|
|
import org.junit.jupiter.api.Assertions;
|
|
|
|
import org.junit.jupiter.api.BeforeAll;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import org.objectweb.asm.ClassReader;
|
|
|
|
import org.objectweb.asm.ClassWriter;
|
|
|
|
import org.objectweb.asm.tree.ClassNode;
|
|
|
|
import pro.gravit.launcher.LauncherInject;
|
|
|
|
import pro.gravit.launchserver.asm.InjectClassAcceptor;
|
2020-01-18 14:04:46 +03:00
|
|
|
import pro.gravit.utils.helper.JarHelper;
|
2020-01-18 09:31:30 +03:00
|
|
|
|
|
|
|
import java.lang.reflect.Field;
|
2020-01-30 13:43:07 +03:00
|
|
|
import java.util.ArrayList;
|
2020-01-18 09:31:30 +03:00
|
|
|
import java.util.HashMap;
|
2020-01-30 13:43:07 +03:00
|
|
|
import java.util.List;
|
2020-01-18 09:31:30 +03:00
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
public class ASMTransformersTest {
|
|
|
|
public static class ASMClassLoader extends ClassLoader
|
|
|
|
{
|
|
|
|
public ASMClassLoader(ClassLoader parent) {
|
|
|
|
super(parent);
|
|
|
|
}
|
|
|
|
public void rawDefineClass(String name, byte[] bytes, int offset, int length)
|
|
|
|
{
|
|
|
|
defineClass(name, bytes, offset, length);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public static ASMClassLoader classLoader;
|
|
|
|
public static class TestClass
|
|
|
|
{
|
|
|
|
@LauncherInject(value = "testprop")
|
2020-01-30 13:43:07 +03:00
|
|
|
public int test;
|
|
|
|
@LauncherInject(value = "testprop2")
|
|
|
|
public List<String> s;
|
|
|
|
@LauncherInject(value = "testprop3")
|
|
|
|
public Map<String, String> map;
|
2020-01-18 09:31:30 +03:00
|
|
|
}
|
|
|
|
@BeforeAll
|
|
|
|
public static void prepare() throws Exception {
|
|
|
|
classLoader = new ASMClassLoader(ASMTransformersTest.class.getClassLoader());
|
|
|
|
}
|
|
|
|
@Test
|
|
|
|
void testASM() throws Exception
|
|
|
|
{
|
2020-01-18 14:04:46 +03:00
|
|
|
ClassReader reader = new ClassReader(JarHelper.getClassBytes(TestClass.class));
|
2020-01-18 09:31:30 +03:00
|
|
|
ClassNode node = new ClassNode();
|
|
|
|
reader.accept(node, ClassReader.SKIP_DEBUG);
|
|
|
|
node.name = "ASMTestClass";
|
|
|
|
Map<String, Object> map = new HashMap<>();
|
|
|
|
map.put("testprop", 1234);
|
2020-01-30 13:43:07 +03:00
|
|
|
List<String> strings = new ArrayList<>();
|
|
|
|
strings.add("a");
|
|
|
|
strings.add("b");
|
|
|
|
map.put("testprop2", strings);
|
|
|
|
Map<String, String> byteMap = new HashMap<>();
|
|
|
|
byteMap.put("a", "TEST A");
|
|
|
|
byteMap.put("b", "TEST B");
|
|
|
|
map.put("testprop3", byteMap);
|
2020-01-24 05:57:04 +03:00
|
|
|
InjectClassAcceptor injectClassAcceptor = new InjectClassAcceptor(map);
|
|
|
|
injectClassAcceptor.transform(node, "ASMTestClass", null);
|
2020-01-18 09:31:30 +03:00
|
|
|
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
|
|
|
node.accept(writer);
|
|
|
|
byte[] bytes = writer.toByteArray();
|
|
|
|
classLoader.rawDefineClass("ASMTestClass", bytes, 0, bytes.length);
|
|
|
|
Class<?> clazz = classLoader.loadClass("ASMTestClass");
|
2020-01-30 13:43:07 +03:00
|
|
|
Object instance = clazz.newInstance();
|
2020-01-18 09:31:30 +03:00
|
|
|
Field field = clazz.getField("test");
|
2020-01-30 13:43:07 +03:00
|
|
|
Object result = field.get(instance);
|
2020-01-18 09:31:30 +03:00
|
|
|
Assertions.assertEquals(1234, (int) (Integer) result);
|
2020-01-30 13:43:07 +03:00
|
|
|
field = clazz.getField("s");
|
|
|
|
result = field.get(instance);
|
|
|
|
Assertions.assertEquals(strings, result);
|
|
|
|
field = clazz.getField("map");
|
|
|
|
result = field.get(instance);
|
|
|
|
Assertions.assertEquals(byteMap, result);
|
2020-01-18 09:31:30 +03:00
|
|
|
}
|
|
|
|
}
|