Agregar archivos a Java classpath en tiempo de ejecución

¿Es posible agregar un archivo (no necesariamente un archivo jar) a Java classpath en tiempo de ejecución? Específicamente, el archivo ya está presente en el classpath, lo que quiero es si puedo agregar una copia modificada de este archivo al classpath.

Gracias,

Solo puede agregar carpetas o archivos jar a un cargador de clases. Entonces, si tiene un solo archivo de clase, primero debe colocarlo en la estructura de carpetas adecuada.

Aquí hay un truco bastante feo que se agrega a SystemClassLoader en tiempo de ejecución:

import java.io.IOException; import java.io.File; import java.net.URLClassLoader; import java.net.URL; import java.lang.reflect.Method; public class ClassPathHacker { private static final Class[] parameters = new Class[]{URL.class}; public static void addFile(String s) throws IOException { File f = new File(s); addFile(f); }//end method public static void addFile(File f) throws IOException { addURL(f.toURL()); }//end method public static void addURL(URL u) throws IOException { URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Class sysclass = URLClassLoader.class; try { Method method = sysclass.getDeclaredMethod("addURL", parameters); method.setAccessible(true); method.invoke(sysloader, new Object[]{u}); } catch (Throwable t) { t.printStackTrace(); throw new IOException("Error, could not add URL to system classloader"); }//end try catch }//end method }//end class 

La reflexión es necesaria para acceder al método protegido addURL . Esto podría fallar si hay un SecurityManager.

Prueba esto por tamaño.

 private static void addSoftwareLibrary(File file) throws Exception { Method method = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class}); method.setAccessible(true); method.invoke(ClassLoader.getSystemClassLoader(), new Object[]{file.toURI().toURL()}); } 

Esto edita el cargador de clases del sistema para incluir el archivo jar de la biblioteca. Es bastante feo, pero funciona.

La forma en que he hecho esto es usando mi propio cargador de clases

 URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader(); DynamicURLClassLoader dynalLoader = new DynamicURLClassLoader(urlClassLoader); 

Y crea la siguiente clase:

 public class DynamicURLClassLoader extends URLClassLoader{ public DynamicURLClassLoader(URLClassLoader classLoader) { super(classLoader.getURLs()); } @Override public void addURL(URL url) { super.addURL(url); } } 

Funciona sin ningún reflection

Puede probar java.net.URLClassloader con la url de la carpeta / jar donde reside su clase actualizada y usarla en lugar del cargador de clases predeterminado al crear un nuevo hilo.

sí tu puedes. tendrá que estar en su estructura de paquete en un directorio separado del rest de su código comstackdo si desea aislarlo. entonces simplemente colocará su directorio base al frente de la ruta de clase en la línea de comando.

Sí, creo que es posible, pero es posible que deba implementar su propio cargador de clases. Nunca lo hice, pero ese es el camino que probablemente miraría.

Mi solución:

 File jarToAdd = new File("/path/to/file"); new URLClassLoader(((URLClassLoader) ClassLoader.getSystemClassLoader()).getURLs()) { @Override public void addURL(URL url) { super.addURL(url); } }.addURL(jarToAdd.toURI().toURL());