Go Back   Velocity Reviews > Newsgroups > Java
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

Java - dynamically change the classpath

 
Thread Tools Search this Thread
Old 11-25-2005, 08:55 AM   #1
Default dynamically change the classpath


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
  Reply With Quote
Old 11-25-2005, 09:08 AM   #2
NullBock
 
Posts: n/a
Default Re: dynamically change the classpath
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
  Reply With Quote
Old 11-26-2005, 04:57 PM   #3
Chris Smith
 
Posts: n/a
Default Re: dynamically change the classpath
<> 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
  Reply With Quote
Old 11-27-2005, 04:15 AM   #4
jeanlutrin@yahoo.fr
 
Posts: n/a
Default Re: dynamically change the classpath
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
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

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




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46