dynamically change the classpath

J

jeanlutrin

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".

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
 
N

NullBock

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.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.
 
C

Chris Smith

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
 
J

jeanlutrin

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top