[Resolvido] ClassLoader a partir de binario

Galera, já pesquisei, mas não achei exemplo sobre isso:

public class ClassLoaderTest {
public static void main(String args[]) {
try {
URL url = new URL("file:///...//Segurança.jar");
while(true) {
Thread.sleep(1000);
ClassLoader cl = URLext.newInstance(new URL[] {url});//URLClassLoader.newInstance(new URL[] {url});
Object obj = cl.loadClass("OK").newInstance();
System.out.println(obj.toString());
}
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}

URLext é uma extends da URLClassLoader, tá tudo funcionando. A url que passo é de um jar. Mas preciso que, ao invés dele instanciar partir da url, ele instancie a partir de um byte[] desse jar, que vou baixar do banco de dados.

Não entendi direito a api do classloader, tem um defineClass(nome, byte[]…) e tals, mas pelo q percebi apenas “cria a classe” em tempo de execução… deve ter algum jeito dele já retornar a instancia pro "ClassLoader cl = ".

Em resumo: como faço ClassLoader cl = SeiLá.newInstance(byte[].doJAR)? heheheheeh
Valeu ae.

Acho que você vai ter de achar o erro neste programa aqui.

import java.util.*;
import java.io.*;
import java.lang.reflect.*;

public class ByteClassLoader extends ClassLoader {
    @Override
    public Class<?> findClass (String name) {
        Class<?> klass = nameToClass.get (name);
        if (klass != null) return klass;
        byte[] bytes = nameToBytes.get (name);
        assert (bytes != null);
        klass = defineClass (name, bytes, 0, bytes.length);
        nameToClass.put (name, klass);
        return klass;
    }
    public void addBytes (String name, byte[] bytes) {
        nameToBytes.put (name, bytes);
    }
    private Map<String, byte[]> nameToBytes = new HashMap<String, byte[]>();
    private Map<String, Class> nameToClass = new HashMap<String, Class>();
}

class TesteByteClassLoader {
    public static void main (String[] args) throws Exception {
        ByteClassLoader bcl = new ByteClassLoader();
        File f = new File ("Teste.class");
        InputStream is = new FileInputStream (f);
        byte[] bytes = new byte[(int) f.length()];
        is.read (bytes);
        is.close();
        bcl.addBytes ("Teste", bytes);
        Class<?> klass = bcl.findClass ("Teste");
        Method mainMethod = klass.getDeclaredMethod ("main", String[].class);
        mainMethod.invoke (null);
    }
}
class Teste {
    public static void main (String[] args) {
        System.out.println ("Hello, world!");
    }
}

O que você deve fazer é ver por que ocorre este erro aqui:

Exception in thread "main" java.lang.IllegalAccessException: Class TesteByteClassLoader can not access a member of class Teste with modifiers "public static"
        at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at TesteByteClassLoader.main(ByteClassLoader.java:34)

Estou sem tempo de ver por que é que está ocorrendo isso, mas a ideia geral é dada acima.

PUBLIC class Teste{

resolve esse problema, mas dae vem outro:
Exception in thread “main” java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at TesteByteClassLoader.main(TesteByteClassLoader.java:16)

Talvez seja isto aqui:

class TesteByteClassLoader {
    public static void main (String[] args) throws Exception {
        ByteClassLoader bcl = new ByteClassLoader();
        File f = new File ("Teste.class");
        InputStream is = new FileInputStream (f);
        byte[] bytes = new byte[(int) f.length()];
        is.read (bytes);
        is.close();
        bcl.addBytes ("Teste", bytes);
        Class<?> klass = bcl.findClass ("Teste");
        Method mainMethod = klass.getMethod ("main", String[].class);
        mainMethod.setAccessible (true);
        mainMethod.invoke (null, (Object) new String[]{});
    }
}

O resultado esperado:

Hello, world!

É iso ae! valeu memo, tá tudo funfando!