crear - Agregar archivos a Java classpath en tiempo de ejecución
java classpath command line (7)
Esta pregunta ya tiene una respuesta aquí:
¿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,
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 reflejo
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());
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.
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í, 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.
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.
Here 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.
sí tu puedes. tendrá que estar en su estructura de paquete en un directorio separado del resto de su código compilado si desea aislarlo. entonces simplemente colocará su directorio base al frente de la ruta de clase en la línea de comando.