dynamically change the classpath

Discussion in 'Java' started by jeanlutrin@yahoo.fr, Nov 25, 2005.

  1. Guest

    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
    , Nov 25, 2005
    #1
    1. Advertising

  2. NullBock Guest

    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.
    NullBock, Nov 25, 2005
    #2
    1. Advertising

  3. Chris Smith Guest

    <> 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, Nov 26, 2005
    #3
  4. Guest

    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.
    , Nov 27, 2005
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Phil Hanna
    Replies:
    0
    Views:
    1,292
    Phil Hanna
    Jul 1, 2003
  2. Flip
    Replies:
    3
    Views:
    7,214
    Tony Morris
    Feb 9, 2004
  3. Gabe
    Replies:
    3
    Views:
    1,055
  4. Replies:
    2
    Views:
    732
  5. Replies:
    2
    Views:
    1,084
    Mike Schilling
    Mar 2, 2008
Loading...

Share This Page