Ejemplo: carga de una clase Java en tiempo de ejecuci贸n

    Java no es el lenguaje m谩s din谩mico que existe, pero con una planificaci贸n cuidadosa y flexibilidad puede hacer que sus programas sean un poco m谩s din谩micos cargando clases en tiempo de ejecuci贸n.

    Esto puede ser 煤til cuando desee hacer que su aplicaci贸n sea m谩s extensible y permitir que ciertos m贸dulos dentro de ella sean reemplazados simplemente colocando un jar que implementa una interfaz en un directorio.

    O puede cargar escrito por el usuario plugins en tiempo de ejecuci贸n. Por ejemplo, esto podr铆a ser 煤til para agregar funcionalidad a una aplicaci贸n web. Colocar un plugin podr铆a permitirle cambiar la forma en que se realiza la autenticaci贸n de usuario o podr铆a agregar un mejor registro.

    El c贸digo

    Aqu铆 hay un c贸digo que lo ayudar谩 a cargar din谩micamente una nueva clase dada la ruta a su archivo jar.

    import java.io.File;
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.net.URLClassLoader;
    
    public class ExtensionLoader<C> {
    
      public C LoadClass(String directory, String classpath, Class<C> parentClass) throws ClassNotFoundException {
        File pluginsDir = new File(System.getProperty("user.dir") + directory);
        for (File jar : pluginsDir.listFiles()) {
          try {
            ClassLoader loader = URLClassLoader.newInstance(
                new URL[] { jar.toURL() },
                getClass().getClassLoader()
            );
            Class<?> clazz = Class.forName(classpath, true, loader);
            Class<? extends C> newClass = clazz.asSubclass(parentClass);
            // Apparently its bad to use Class.newInstance, so we use 
            // newClass.getConstructor() instead
            Constructor<? extends C> constructor = newClass.getConstructor();
            return constructor.newInstance();
            
          } catch (ClassNotFoundException e) {
            // There might be multiple JARs in the directory,
            // so keep looking
            continue;
          } catch (MalformedURLException e) {
            e.printStackTrace();
          } catch (NoSuchMethodException e) {
            e.printStackTrace();
          } catch (InvocationTargetException e) {
            e.printStackTrace();
          } catch (IllegalAccessException e) {
            e.printStackTrace();
          } catch (InstantiationException e) {
            e.printStackTrace();
          }
        }
        throw new ClassNotFoundException("Class " + classpath
            + " wasn't found in directory " + System.getProperty("user.dir") + directory);
      }
    }
    

    Usando el c贸digo:

    ExtensionLoader<MyPlugin> loader = new ExtensionLoader<MyPlugin>();
    somePlugin = loader.LoadClass("path/to/jar/file", "com.example.pluginXYZ", MyPlugin.class);
    

    Algunas notas

    Sin duda, existen mejores formas de hacer que una aplicaci贸n sea extensible (OSGi, Portlets, JPF, etc.), pero a veces solo necesitas algo simple como esto.

    Tenga en cuenta que ExtensionLoader solo llama a constructores sin argumentos (clases tipo bean). Podr铆a ser m谩s beneficioso devolver un Constructor<? extends C> class y ll谩melo con los argumentos apropiados. Si este es el caso, aseg煤rese de cargar el constructor correcto desde el newClass.getConstructor() m茅todo.

    ADVERTENCIA: No se realizan controles de seguridad en este c贸digo, 隆as铆 que aseg煤rese de confiar en las clases que est谩 cargando!

    .

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *