Cita:
Iniciado por LuisChavezB Siempre debes de utilizar la ruta completa a la clase.
Un ejemplo:
Código Javascript
:
Ver originalScanner scanner = new Scanner(System.in);
Class<?> clazz = Class.forName("mx.com.leviathan.data.filter.FilterExample");
if (clazz.isAnnotationPresent(Filter.class)) {
Object newInstance = clazz.newInstance();
Filter filter = clazz.getAnnotation(Filter.class);
System.out.printf("%s, %s %s\n", filter.author(), filter.name(), filter.version());
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(FilterFunction.class)) {
FilterFunction filterFunction = method.getAnnotation(FilterFunction.class);
if (filterFunction.params().length != filterFunction.paramTypes().length) {
System.err.println("El numero de argumentos es invalido!!");
return;
}
ArrayList<Object> params = new ArrayList<>();
for (int i = 0; i < filterFunction.params().length; i++) {
System.out.printf("Ingresa el parametro: %s >> ", filterFunction.params()[i]);
Object param = scanner.nextLine();
params.add(param);
}
Object result = method.invoke(newInstance, params.toArray());
System.out.printf("%s: %s\n", filterFunction.returnType(), result);
}
}
}
Cual es la ruta de antes del package del proyecto, "com"?
Creo que lo he resuelto (de momento me funciona, no se si luego mientras desarrolle el codigo tendre algun problema).
Hay que cambiar el package por defecto en el que busca las clases el classloader:
http://www.javablogging.com/java-classloader-2-write-your-own-classloader/
Este seria el classloader que estoy utilizando:
Código:
package pruebas;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
/**
* Our custom implementation of the ClassLoader.
* For any of classes from "javablogging" package
* it will use its {@link CustomClassLoader#getClass()}
* method to load it from the specific .class file. For any
* other class it will use the super.loadClass() method
* from ClassLoader, which will eventually pass the
* request to the parent.
*
*/
public class CustomClassLoader2 extends ClassLoader {
/**
* Parent ClassLoader passed to this constructor
* will be used if this ClassLoader can not resolve a
* particular class.
*
* @param parent Parent ClassLoader
* (may be from getClass().getClassLoader())
*/
public CustomClassLoader2(ClassLoader parent) {
super(parent);
}
/**
* Loads a given class from .class file just like
* the default ClassLoader. This method could be
* changed to load the class over network from some
* other server or from the database.
*
* @param name Full class name
*/
private Class<?> getClass(String name)
throws ClassNotFoundException {
// We are getting a name that looks like
// javablogging.package.ClassToLoad
// and we have to convert it into the .class file name
// like javablogging/package/ClassToLoad.class
String file = name.replace('.', File.separatorChar)
+ ".class";
// System.out.println("NAME: "+file);
byte[] b = null;
try {
// This loads the byte code data from the file
b = loadClassData(file);
// defineClass is inherited from the ClassLoader class
// and converts the byte array into a Class
Class<?> c = defineClass(name, b, 0, b.length);
resolveClass(c);
return c;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
/**
* Every request for a class passes through this method.
* If the requested class is in "javablogging" package,
* it will load it using the
* {@link CustomClassLoader#getClass()} method.
* If not, it will use the super.loadClass() method
* which in turn will pass the request to the parent.
*
* @param name
* Full class name
*/
@Override
public Class<?> loadClass(String name)
throws ClassNotFoundException {
// System.out.println("loading class '" + name + "'");
if (name.startsWith("inventarionb.")) {
return getClass(name);
}
else if (name.startsWith("componentespkg")) {
return getClass(name);
}
return super.loadClass(name);
}
/**
* Loads a given file (presumably .class) into a byte array.
* The file should be accessible as a resource, for example
* it could be located on the classpath.
*
* @param name File name to load
* @return Byte array read from the file
* @throws IOException Is thrown when there
* was some problem reading the file
*/
private byte[] loadClassData(String name) throws IOException {
// Opening the file
InputStream stream = getClass().getClassLoader()
.getResourceAsStream(name);
int size = stream.available();
byte buff[] = new byte[size];
DataInputStream in = new DataInputStream(stream);
// Reading the binary data
in.readFully(buff);
in.close();
return buff;
}
}
y este el main:
Código:
package inventarionb;
import pruebas.*;
public class IntegerPrinterTest {
/**
* This main method shows a use of our CustomClassLoader for
* loading some class and running it. All the objects referenced
* from the IntegerPrinter class will be loaded with
* our CustomClassLoader.
*/
public static void main(String[] args) throws Exception
{
System.out.println(stringtoclassmethod("componentespkg.cat3.DiodoSchottky","toCB"));
String[] a=(String[])stringtoclassmethod("componentespkg.cat3.DiodoSchottky","toCol");
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+", ");
}
System.out.print("\n");
System.out.println(stringtoclassmethod("componentespkg.cat2.Diodo","toCB"));
a=(String[])stringtoclassmethod("componentespkg.cat2.Diodo","toCol");
for(int i=0;i<a.length;i++)
{
System.out.print(a[i]+", ");
}
}
public static Object stringtoclassmethod (String dir, String method) throws Exception
{
// dir="componentespkg.cat3.DiodoSchottky";
// method="toCB";
CustomClassLoader2 loader = new CustomClassLoader2(IntegerPrinterTest.class.getClassLoader()); //(StaticAccessorTest.class.getClassLoader());
Class<?> clazz =
loader.loadClass(dir); //inventarionb.IntegerPrinter //componentespkg.cat2.Diodo
Object instance = clazz.newInstance();
Object aas=clazz.getMethod(method).invoke(instance);//runMe // toCB2CB
//System.out.println(aas);
return aas;
}
}
Esta un poco desordenado, hay anotaciones por el codigo y codigo omitido... pero como referencia sirve. Ire adaptandolo a mi otro programa.