在运行时将文件添加到java classpath中

是否有可能在运行时将文件(不一定是jar文件)添加到java classpath中。 具体来说,文件已经存在于类path中,我想要的是我是否可以将此文件的修改副本添加到类path中。

谢谢,

您只能将文件夹或jar文件添加到类加载器。 所以如果你有一个类文件,你需要先把它放到合适的文件夹结构中。

这是在运行时添加到SystemClassLoader的一个相当丑陋的黑客攻击:

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 

reflection是必要的访问受保护的方法addURL 。 如果有SecurityManager,这可能会失败。

试试这个大小。

 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()}); } 

这编辑了系统类加载器以包含给定的库jar。 这是相当丑陋的,但它的作品。

我这样做的方式是使用我自己的类加载器

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

并创build以下类:

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

没有任何反思的作品

你尝试java.net.URLClassloader与更新的类所在的文件夹/ jar的URL,并创build一个新的线程时使用它,而不是默认的类加载器。

是的你可以。 如果要将其隔离,需要将其包装结构放在与其余编译代码不同的目录中。 那么你只需要把它的基本目录放在命令行的类path的前面。

是的,我相信这是可能的,但你可能需要实现你自己的类加载器。 我从来没有做过,但这是我可能会看的path。

我的解决scheme

 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());