elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  Java
| | | |-+  Evaluar si .java de un directorio sn parte d el proyecto y acceder a metodos
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Evaluar si .java de un directorio sn parte d el proyecto y acceder a metodos  (Leído 2,680 veces)
danirebollo

Desconectado Desconectado

Mensajes: 8


Ver Perfil
Evaluar si .java de un directorio sn parte d el proyecto y acceder a metodos
« en: 17 Noviembre 2012, 18:37 pm »

Hola! estoy haciendo una aplicacion que sea cliente de una base de datos la filtre y mas cosas...

Cada categoria o subcatecoria pone en una posicion de un combobox una palabra (el combobox es para seleccionar que lo que voy a crear forma parte de esa clase), por esto, y alguna cosa mas, querria evitar tener que modificar el codigo cada vez que añado una clase, en este caso tendria que modificar el metodo que rellene el combobox para decirle que tambien incluya la clase nueva.

La solucion que he encontrado y estoy desarrollando poco a poco para poder hacer esto de forma facil (facil para mantener la base de datos, no para crear el codigo de esta aplicacion, que me parece que con esto la estoy complicando mucho e incluso va a ser lenta, por lo menos al cargar al principio...) es la siguiente:
-obtengo los nombres de los ficheros de un directorio (parto del package principal donde estan los componentes (todas las clases que almacenan componentes de la base de datos) y si hay mas packages subo a ellos para leerlos tambien) y filtro los '.java' quitandoles la extension.
Código:
File fichero; //=new File("Readfile.java");
        fichero=new File(directory);
        
        String[] listaArchivos=fichero.list(); //crea un array cn los nombres de los ficheros en el directorio.      

        listaArchivos=fichero.list(new Filtro(".java")); //filtra los archivos dejando solo los que tienen extension '.java'

for(int i=0; i<listaArchivos.length; i++) //elimina la extension de el nombre del archivo
        {
            //System.out.println(listaArchivos[i]);
            listaArchivos[i]=listaArchivos[i].substring(listaArchivos[i].lastIndexOf('/') + 1, listaArchivos[i].lastIndexOf('.'));
            //System.out.println(listaArchivos[i].substring(listaArchivos[i].lastIndexOf('/') + 1, listaArchivos[i].lastIndexOf('.')));
        }
        
-
-creo una clase equivalente a la clase que tiene el mismo nombre del archivo
 
Código:
ClassLoader classLoader = Componente.class.getClassLoader();
        Class aClass = null;
        try {
        aClass= classLoader.loadClass("componentespkg.cat2."+classnamber);
}
  
-Instancio esa clase cast-andola (xd) con la clase que quiero comparar y ejecuto el metodo que me interesa, que es, por ejemplo el String que esa clase mandara al combobox.

El programa de momento lee los archivos en un directorio, los filtra y compara con instanceof con la clase padre o con las subclases, pero todavia tengo que darle yo demasiados datos...
Funciona, pero yo no quiero tener que saber la clase de antemano para hacer cast.
Probando si en cada metodo pongo
Código:
 static{} 
solo, sin modificador ni nada (que no se para que sirve), podria obtener variables escribiendo que llame a una funcion de la clase principal y le de como parametro algo, pero el problema de eso es que solo es una funcion/metodo(?), entonces si quisiera obtener informacion ordenada de esa clase tendria que enviarla toda de golpe a la clase principal y alli ordenarla... vamos, que no ganaria mucho teniendo que crear un indice de quien me envia cada cosa y que cosa es...

Otro modo de hacer algo parecido seria con reflexion (bueno, lo tro tambien se vale de ella xd), seria leer las clases de un directorio y cargarlas en tiempo de ejecucion, el problema es que no se como podria acceder a sus metodos (si es que se puede).
Es decir: yo leo un directorio y cargo una de las clases, la clase 'abc' (el archivo se llama 'abc.java' y tiene los metodos a, b y c), que ahora esta e una clase generica Class x, por ejemplo. Como puedo acceder a los metodos 'a', 'b', 'c'? Yo se que la clase, en cuanto que se cargue (en tiempo de ejecucion) sera 'abc' y tendra el metodo 'a' al que podre llamar, pero el compilador no lo sabe.

En resumen, yo tengo una carpeta con las clases que sé, porque heredan de una clase principal que lo tiene, que tienen un metodo determinado 'metodo1', lo demas no lo se, pero ese si.
¿Como voy llamando a todos los metodos 'metodo1' de las clases que desconozco cuales son?

¿Como podria hacerlo?

Perdonar por la extension, pero no sabia como explicarlo brevemente xd.
Un saludo.


« Última modificación: 17 Noviembre 2012, 21:33 pm por danirebollo » En línea

danirebollo

Desconectado Desconectado

Mensajes: 8


Ver Perfil
Re: Evaluar si .java de un directorio forman parte d el proyecto y acceder a metodos
« Respuesta #1 en: 17 Noviembre 2012, 21:32 pm »

En main:
Código:
String str = "HELLO";
        Diodo dod;
        dod=new Diodo("","",0,"","");

    try {
     
      Method method = str.getClass().getMethod("toString"); //getMethod("toString", null);
      Object retVal = method.invoke(str); //invoke(str, null);
      System.out.println(retVal);
     
    } catch ...............(a lot of catchs xd)
Este codigo, sea con  'str.getClass()...' y 'method.invoke(str)'  tratando de obtener el toString de un String, o con  'dod.getClass()...' y 'method.invoke(dod)' tratando de obtener uno de los metodos de la clase Diodo, funcionan bien, pero cuando trato de obtener un metodo de 'aClass', declarado como
Código:
Class aClass = null;
, e instanciado con:
Código:
aClass= classLoader.loadClass("componentespkg.cat2.Diodo");
, que deberia ser en este caso la clase Diodo, no funciona y me devuelve la excepcion
Código:
java.lang.NoSuchMethodException: java.lang.Class.toCB2CB()
at java.lang.Class.getMethod(Class.java:1622)
at inventarionb.InventarionbTEST.main(InventarionbTEST.java:83)
Hay una cosa, no se si tiene algo que ver con el error, cuando pone java.lang.Class.toCB2CB() en la excepcion. ¿Esa ruta es correcta? No creo que el metodo de mi clase derive del metodo Class, pero no sabria que poner... en el caso de que la clase se encuentre dentro de la clase principal, donde esta el main, no hay que poner mas cosas, pero lo mismo al estar fuera hay que poner algo en la ruta... no he conseguido que me funcione poniendo la sucesion de packages (separada por '.')


En línea

danirebollo

Desconectado Desconectado

Mensajes: 8


Ver Perfil
Re: Evaluar si .java de un directorio sn parte d el proyecto y acceder a metodos
« Respuesta #2 en: 17 Noviembre 2012, 21:35 pm »

(acabo de ver que no dejaba responder porque el nombre de el titulo era muy largo y no podia poner 'Re: ' an el mensaje de respuesta, he acortado el titulo)
En línea

danirebollo

Desconectado Desconectado

Mensajes: 8


Ver Perfil
Re: Evaluar si .java de un directorio sn parte d el proyecto y acceder a metodos
« Respuesta #3 en: 18 Noviembre 2012, 15:33 pm »

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.
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Descripcion de Metodos JAVA
Java
Lopardo 9 7,530 Último mensaje 19 Febrero 2006, 18:13 pm
por Lopardo
Metodo quicksort en java
Java
ship 3 15,675 Último mensaje 12 Noviembre 2011, 18:02 pm
por ship
Problema al acceder a métodos en java.
Java
bewa 4 3,492 Último mensaje 27 Diciembre 2011, 01:49 am
por Proteus1989
ejercicios con metodos java
Java
mq1024 9 11,371 Último mensaje 20 Marzo 2012, 15:38 pm
por Lerinor
MOVIDO: Métodos para saber como funciona un proyecto en c#MVC?
Programación General
Eleкtro 0 1,694 Último mensaje 10 Febrero 2016, 12:19 pm
por Eleкtro
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines