Hi,
This tutorial is actually amazing. Thank you so much, it really helped me fill in the blank spaces in-between that I didn't know while I've been trying to figure this all out.
I've completed the tutorial basically, but the part that I can't get working is related to the interfaces.
I basically have identical to the tutorial, but I get errors when trying to add my custom interface to the ClassNode.
Java:
package com.alexander.runeo.transform.transformers;
import com.alexander.runeo.transform.ClassTransformer;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;
public class ClientClassTransformer extends ClassTransformer {
@Override
public void transform(ClassNode node) {
try {
System.out.println(Class.forName("com.alexander.runeo.transform.api.APIClientInterface").getSimpleName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
for (String internal : node.interfaces) {
System.out.println(internal);
}
node.interfaces.add("com/alexander/runeo/transform/api/APIClientInterface");
MethodNode methodNode = new MethodNode(Opcodes.ACC_PUBLIC, "helloWorld", "(Ljava/lang/String;)V", null, null);
methodNode.instructions.add(new FieldInsnNode(Opcodes.GETSTATIC,
"java/lang/System",
"out",
"Ljava/io/PrintStream;"));
methodNode.instructions.add(new VarInsnNode(Opcodes.ALOAD, 1));
methodNode.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL,
"java/io/PrintStream",
"println", "(Ljava/lang/String;)V"));
methodNode.instructions.add(new InsnNode(Opcodes.RETURN));
int size = methodNode.instructions.size();
methodNode.visitMaxs(size, size);
methodNode.visitEnd();
node.methods.add(methodNode);
}
}
I just wanted to make a method which is called "helloWorld", takes in a string as the first argument and then outputs that string. I managed to do that and then I could invoke that method through reflection really easily, but for some reason I get this error when adding the interface:
Code:
Exception in thread "main" java.lang.NoClassDefFoundError: com/alexander/runeo/transform/api/APIClientInterface
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at com.alexander.runeo.loader.ClientLoader.loadClass(ClientLoader.java:53)
at com.alexander.runeo.loader.ClientLoader.loadClassFromFile(ClientLoader.java:37)
at com.alexander.runeo.loader.ClientLoader.<init>(ClientLoader.java:22)
at com.alexander.runeo.Runeo.start(Runeo.java:39)
at com.alexander.runeo.Main.main(Main.java:6)
Caused by: java.lang.ClassNotFoundException: com.alexander.runeo.transform.api.APIClientInterface
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 16 more
As you can see, I specified the correct package path to the class itself, but I still get this error. It works when I use the built-in List interface, and it even works when I use an obfuscated interface from the Runescape package, but when I use it for my own class, it's like it can't see it.
I've tried with and without the package, and from my try/catch statement above you can see I try get the class and print its name out. This executes perfectly and prints "APIClientInterface".
Is there something I might've misconfigured in project?