Я пытаюсь динамически загружать классы с помощью Java sun.misc.Unsafe.defineClass (имя строки, байт [] код, int off, int len, классLoader classLoader, ProtectionDomain protectionDomain), но по какой-то причине объекты, которые я создаю, вызывая Class.newInstance() (или Class.getConstructor()). newInstance()) не являются экземплярами интерфейса, который я реализовал в этом классе (и который возвращает Class.getInterfaces()), ,Внедрение интерфейсов в динамических классах с использованием небезопасных Java
Метод, который я определил загрузить класс данный байт-код это:
public static Class<?> loadClass(String name, URL url, byte[] code) {
Unsafe u = UnsafeKey.getUnsafe();
java.lang.ClassLoader loader = java.lang.ClassLoader.getSystemClassLoader();
Permissions perms=new Permissions();
perms.add(new RuntimePermission("accessDeclaredMembers"));
ProtectionDomain protection = new ProtectionDomain(new CodeSource(url,(Certificate[])null),perms);
return u.defineClass(name, code, 0, code.length, loader, protection);
}
Байткода в моем случае загружается непосредственно из файла .class (составитель моего JDK), используя этот метод:
public static Class<?> loadClass(String name, File f) throws IOException {
byte[] data = new byte[(int) f.length()];
InputStream i = new FileInputStream(f);
i.read(data);
return loadClass(name, f.toURI().toURL(), data);
}
Который отправляет загруженные данные в первый метод.
Класс Я использую для тестирования реализует интерфейс под названием PixelArtist:
import com.ralitski.art.api.PixelArtist;
public class PixelArtistTest implements PixelArtist {
public PixelArtistTest() {}
@Override
public int getWidth() {
return 100;
}
@Override
public int getHeight() {
return 100;
}
@Override
public int getColor(int x, int y) {
int z = x * y;
return x + (y * 255) + z;
}
}
После загрузки этого класса из файла, определяя его, и создание нового экземпляра, я пытаюсь использовать его с помощью этого метода (этот объект передается создается с помощью вызова Class.newInstance()):
private static Artist getArtist(Object o) {
System.out.println(o);
Class c = o.getClass();
System.out.println(c);
System.out.println(c.getSuperclass());
for(Class c2 : c.getInterfaces()) {
System.out.println(" " + c2);
}
System.out.println(PixelArtist.class.isInstance(o));
if(o instanceof Artist) {
System.out.println(1);
return (Artist)o;
} else if(o instanceof PixelArtist) {
System.out.println(2);
return new PixelArtistFeed((PixelArtist)o);
} else {
System.out.println(3);
return null;
}
}
выходной сигнал этого кода заключается в следующем:
[email protected]
class PixelArtistTest
class java.lang.Object
interface com.ralitski.art.api.PixelArtist
false
3
Как вы можете видеть, класс перечисляет PixelArtist как интерфейс, но объект, созданный из этого класса, не является экземпляром типа PixelArtist.
Я попытался добавить разные разрешения для класса, когда я его определяю (даже для AllPermission), и я попытался создать экземпляр объекта Object с помощью Class.getConstructor(). NewInstance(), но эта ошибка сохраняется.