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!