This may surprise you, but the same thing will happen if you created the same code using javac using the same classloader load. What you are observing is implied in how packet confidentiality is set in JLS. Your non-interface class
public abstract class Algorithm { abstract int execute(); }
defines a private-package method. Since you do not define a custom name for the generated class, Byte Buddy creates a subclass with a random name that lives in the same package. Byte Buddy also detects the executable method as being overridden from the generated subclass and implements it exactly as you expected.
However, you use the ClassLoadingStrategy.Default.WRAPPER strategy to load a class that creates a new loader for the child class of a single Algorithm load. In Java, at run time, two packages are only equal if the package name is equal, and both packages are loaded with the same ClassLoader . A later condition is not true for your case, so the JVM no longer applies polymorphism to the execute class. By calling
((Algorithm) type.newInstance()).execute();
therefore, you are not calling the generated method, but the original, abstract method. Therefore, according to JLS, an AbstractMethodError is thrown.
To fix this problem, you either need to load the generated class in the same package using the default INJECTION strategy, or you must define execute as public (this is defined when defining the interface) or protected , so the rules for polymorphism that you expect apply. As a third option, you can call the correct execution method
type.getDeclaredMethod("execute").invoke(type.newInstance());
Rafael winterhalter
source share