First solution that comes to mind would be to use OSGI. Sometime you don't want to setup a whole OSGi environment to replace just one jar, or even just one file.
An alternative is to use a custom classloader.
8 import java.net.URL; 9 import java.net.URLClassLoader; 10 import java.util.List; 11 12 /** 13 * own classloader, delegating not found classes to parent classloader. 14 ... 15 */ 16 public class DelegatingClassLoader extends URLClassLoader { 17 18 private ClassLoader mainLoader; 19 private List < URL > defaultUrls; 20 21 /** 22 * default contrsuctor. 23 * @see URLClassLoader#URLClassLoader(java.net.URL[]) 24 */ 25 public DelegatingClassLoader() { 26 super(new URL[0]); 27 } 28 29 /** 30 * getter for default url list. 31 * @return list of urls 32 */ 33 public List < URL > getDefaultUrls() { 34 return this.defaultUrls; 35 } 36 37 /** 38 * setter for default url list. 39 * @param defaultUrlsToBeSet list of url 40 */ 41 public void setDefaultUrls(List < URL > defaultUrlsToBeSet) { 42 this.defaultUrls = defaultUrlsToBeSet; 43 } 44 45 /** 46 * adding url to classpath. 47 * @see URLClassLoader#addURL(java.net.URL) 48 * @param url to be added 49 */ 50 public void addUrl(URL url) { 51 addURL(url); 52 } 53 54 /** 55 * activate this classloader, remember parent loader. 56 */ 57 public void activate() { 58 // backup parent class loader 59 this.mainLoader = Thread.currentThread().getContextClassLoader(); 60 61 // add default urls 62 for (URL url : this.defaultUrls) { 63 addURL(url); 64 } 65 66 // set this class loader as default for thread 67 Thread.currentThread().setContextClassLoader(this); 68 } 69 70 /** 71 * restore parent classloader. 72 */ 73 public void restore() { 74 Thread.currentThread().setContextClassLoader(this.mainLoader); 75 } 76 77 /** 78 * {@inheritDoc} 79 */ 80 @Override 81 public Class loadClass(String name) throws ClassNotFoundException { 82 try { 83 return super.loadClass(name); 84 } catch (NoClassDefFoundError ncde) { 85 return this.mainLoader.loadClass(name); 86 } catch (ClassNotFoundException cnfe) { 87 return this.mainLoader.loadClass(name); 88 } catch (UnsupportedClassVersionError ucve) { 89 throw new RuntimeException("Bad class " + name, ucve); 90 } 91 92 } 93 94 /** 95 * {@inheritDoc} 96 */ 97 @Override 98 public URL getResource(String name) { 99 try {100 return super.getResource(name); 101 } catch (NoClassDefFoundError ncde) { 102 return this.mainLoader.getResource(name); 103 } catch (UnsupportedClassVersionError ucve) { 104 throw new RuntimeException("Bad class " + name, ucve); 105 } 106 } 107 }
The above code extends URLClassloader, trying to load a class from specified url, if not found delegate to its parent <code>mainLoader</code>.
Furthermore the current classloader is replaced (<code>activate()</code>) and afterwards restored (<code>restore()</code>).
Example usage would be:
129 DelegatingClassLoader delegateLoader = new DelegatingClassLoader(); 130 delegateLoader.addUrl(SOMEFILE.toURI().toURL()); 131 132 delegateLoader.activate(); we create a new loader, add an url (for example from an existing file, and activate the new class loader
144 try { 145 Class tf = delegateLoader.loadClass( 146 "com.myapp.SomeFactory"); 147 148 Method getInstance = tf.getDeclaredMethod("getInstance", null); 149 Object factory = getInstance.invoke(null, null); afterwards we use reflection to invoke methods ...
173 } finally { 174 delegateLoader.restore(); 175 } ;.. don't forget to restore the old classloader ...

Hello from Russia!
Can I quote a post in your blog with the link to you?