![]() |
|
|
|||||||
![]() |
Java - dynamically change the classpath |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
I've got a question regarding how to "dynamically change
the classpath" ? I've already written some (simple) custom ClassLoaders, to help... loading classes. This time, I need to do something and I think I need to use a custom ClassLoader but I'm really not sure. And if I need to use/write one, I don't know of to go about it. Here's my problem: - I've got several .jars that my application needs and I have to keep these files as separated jars. - I cannot be sure of the exact location of these jars, so I cannot add them to the main jar's MANIFEST.MF's Class-Path:. - At runtime, I will have a way to know where those jars are located. How can I tell the application "if you don't find a class, go look into those jars"? I've read several articles/webpages and read code sample, but I don't get it. I know how to load a certain class from a .jar, but not how to tell the application "if you don't find a class then look into xxx.jar and yyy.jar and zzz.jar before throwing a ClassDefNotFoundError". On Roedy's site, it is written: > Why would you ever want a custom ClassLoader? > > ... > They let you dynamically change the classpath. > ... So I think I need to use a custom ClassLoader (an URLClassLoader?), but how... Thanks in advance for any help, Jean jeanlutrin@yahoo.fr |
|
|
|
|
#2 |
|
Posts: n/a
|
There is a well-known hack for dynamically extending the class path.
It generally works, and we use it in production releases of our software. It uses reflection, plus the knowledge that the default ClassLoader *is* a URLClassLoader. It works like this: public static void main(String[] args) throws Exception { Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[] {URL.class}); addURL.setAccessible(true);//you're telling the JVM to override the default visibility File[] files = getExternalJars();//some method returning the jars to add ClassLoader cl = ClassLoader.getSystemClassLoader(); for (int i = 0; i < files.length; i++) { URL url = files[i].toURL(); addURL.invoke(cl, new Object[] { url }); } //at this point, the default class loader has all the jars you indicated } As I said, this is a hack, undocumented, and subject to change at any time. Indeed, there's no guarantee that extant JREs use a URLClassLoader as a default class loader. Moreover, it only works if your program doesn't have a security manager (it probably doesn't), or your code is trusted. That said, it works for us. We've never seen problems with it, although our software is used on a plethora of different boxes and OSs. There are more traditional ways, for instance using ThreadGroups at program startup to change the default ClassLoader. These are more complex, though, and have their own problems. Hope this helps, Walter Gildersleeve __________________________________________________ ____ http://linkfrog.net URL Shortening Free and easy, small and green. NullBock |
|
|
|
#3 |
|
Posts: n/a
|
<> wrote:
> I've got a question regarding how to "dynamically change > the classpath" ? The first thing you should realize is that you cannot (in a portable way that's guaranteed to work) change the system classpath. Instead, you need to define a new ClassLoader. Now, the second part. ClassLoaders work in a hierarchical manner... so any class that makes a static reference to class X needs to be loaded in the same ClassLoader as X, or in a child ClassLoader. You can NOT use any custom ClassLoader to make code loaded by the system ClassLoader link properly, if it wouldn't have done so before. So you need to arrange for your main application code to be run in the custom ClassLoader in addition to the extra code that you locate. Finally, don't ACTUALLY write your own ClassLoader. I see no good reason that you can't just use URLClassLoader instead. It's very easy to use. Just pass an array of URLs into the constructor. So, you have two pieces of your application: 1. A stub that discovers, at runtime, where to find all the necessary classes, and then creates a URLClassLoader which will load both your main application and the other classes it needs. 2. The rest of your application, which is not loaded by the system class loader or placed in the classpath, but is rather loaded by the stub through the URLClassLoader. -- www.designacourse.com The Easiest Way To Train Anyone... Anywhere. Chris Smith - Lead Software Developer/Technical Trainer MindIQ Corporation Chris Smith |
|
|
|
#4 |
|
Posts: n/a
|
Thanks a lot for your answers...
It's all much clearer now. I'm working on writing a small stub that does the discovery then loads the main application. jeanlutrin@yahoo.fr |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| master page does not change due to preinit event not firing | franchise63 | General Help Related Topics | 0 | 02-13-2008 09:18 AM |
| Why We Resist Change @ The TechZone | Silverstrand | Front Page News | 0 | 09-07-2006 12:01 PM |
| Dune Extended Edition - where is the layer change? | John | DVD Video | 0 | 02-16-2006 09:43 PM |
| If I could change the LotR movies... | Opticreep | DVD Video | 33 | 03-03-2004 12:36 PM |
| Can't Change IRQs in Windows 2000 | Alicia White | A+ Certification | 8 | 09-01-2003 08:54 AM |