Adding files to java classpath at runtime [duplicate]
You can only add folders or jar files to a class loader. So if you have a single class file, you need to put it into the appropriate folder structure first.
Here is a rather ugly hack that adds to the SystemClassLoader at runtime:
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
The reflection is necessary to access the protected method addURL
. This could fail if there is a SecurityManager.
Try this one on for size.
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()});}
This edits the system class loader to include the given library jar. It is pretty ugly, but it works.
The way I have done this is by using my own class loader
URLClassLoader urlClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();DynamicURLClassLoader dynalLoader = new DynamicURLClassLoader(urlClassLoader);
And create the following class:
public class DynamicURLClassLoader extends URLClassLoader { public DynamicURLClassLoader(URLClassLoader classLoader) { super(classLoader.getURLs()); } @Override public void addURL(URL url) { super.addURL(url); }}
Works without any reflection