sistema - Java: ¿Cómo cargar la clase almacenada como byte[] en la JVM?
que es jvm en programacion (5)
Bien, entonces esto es lo que hice:
public class AgentClassLoader extends ClassLoader
{
public void loadThisClass(ClassByte classByte_)
{
resolveClass(defineClass(classByte_.getName(),
classByte_.getBytes(),
0,
classByte_.getBytes().length));
}
}
Espero que cargue la clase en JVM? Si esto realmente funciona, ¿por qué el implementador de Java no hizo públicos los métodos defineClass y resolverClass? Realmente me pregunto qué estaban pensando. ¿Alguien me puede iluminar?
Sólo para completar, aquí está ClassByte
import java.io.Serializable;
public class ClassByte implements Serializable
{
private String name;
private byte[] bytes;
ClassByte(String name_, byte[] bytes_)
{
name = name_;
bytes = bytes_;
}
public String getName()
{
return name;
}
public byte[] getBytes()
{
return bytes;
}
}
Si uno ha serializado todo el archivo .class en el byte [], y suponiendo que se conoce el nombre de la clase (se pasa junto con el byte []), ¿cómo convertir el byte [] -> Class -> y luego cargarlo al ¿JVM para poder usarlo más tarde llamando a Class.forName ()?
NOTA: Estoy haciendo esto porque envié el .class a otro host, y la JVM del host no conoce este .class.
En realidad estoy usando algo como esto ahora mismo en una prueba para dar un conjunto de definiciones de clase como byte [] a un ClassLoader:
public static class ByteClassLoader extends URLClassLoader {
private final Map<String, byte[]> extraClassDefs;
public ByteClassLoader(URL[] urls, ClassLoader parent, Map<String, byte[]> extraClassDefs) {
super(urls, parent);
this.extraClassDefs = new HashMap<String, byte[]>(extraClassDefs);
}
@Override
protected Class<?> findClass(final String name) throws ClassNotFoundException {
byte[] classBytes = this.extraClassDefs.remove(name);
if (classBytes != null) {
return defineClass(name, classBytes, 0, classBytes.length);
}
return super.findClass(name);
}
}
Extienda ClassLoader
y luego implemente la llamada necesaria para obtener su byte[]
dentro del método defineClass()
. Por el contrario, puede hacer esto en findClass()
. Por lo tanto, cargará este ClassLoader al principio o lo empleará cuando necesite definiciones de clase a través de su matriz.
public class ByteArrayClassLoader extends ClassLoader {
public Class findClass(String name) {
byte[] ba = /* go obtain your byte array by the name */;
return defineClass(name,ba,0,ba.length);
}
}
La respuesta de Alex es correcta, pero si tiene una relación de herencia entre las clases, debe asegurarse de cargar primero la clase principal. De lo contrario, el cargador de clases no podrá definirlo.
Utilice el método defineClass (String, byte [], int, int) de ClassLoader