Click here to Skip to main content
15,038,237 members
Articles / Programming Languages / Java
Article
Posted 20 Jan 2011

Tagged as

Stats

26.8K views
129 downloads
3 bookmarked

Adding class paths to SystemClassLoader

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
23 Jan 2011CPOL
How to add class paths to SystemClassLoader.

Introduction

This article is a non-recommended hack for dynamically adding a class path to SystemClassLoader. You should re-think your design before using this hack; usually, you should be able to use URLClassLoader to load whatever you want.

About SystemClassLoader

SystemClassLoaders are usually URLClassLoaders, and in URLClassLoader, there is a method called addURL(), so we can make use of this to add paths/jars to SystemClassLoader dynamically at runtime. However, since "addURL()" is a protected method, we have to use Reflection to call it.

The sample code is as follows:

Java
public static void addURLs(URL[] urls) {
  ClassLoader cl = ClassLoader.getSystemClassLoader();
  if ( cl instanceof URLClassLoader ) {
    URLClassLoader ul = (URLClassLoader)cl;
    // addURL is a protected method, but we can use reflection to call it
    Class<?>[] paraTypes = new Class[1];
    paraTypes[0] = URL.class;
    Method method = URLClassLoader.class.getDeclaredMethod("addURL", paraTypes);
    // change access to true, otherwise, it will throw exception
    method.setAccessible(true);
    Object[] args = new Object[1];
    for(int i=0; i<urls.length; i++) {
      args[0] = urls[i];
      method.invoke(ul, args);
    }
  } else {
    // SystemClassLoader is not URLClassLoader....
  }
}

Test

I have written a test case, and it will automatically load all "lib/*.jar" and instantiate an object as specified in args[0]. The test output is as follows. Note: I only included "bin" as my class path, and I have commons-collections.jar under my "lib" directory, but the program is still able to dynamically load the required class.

Image 1

History

  • 2010.01.20: First draft.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sam NG
Hong Kong Hong Kong
No Biography provided

Comments and Discussions

 
GeneralInteresting, but well known and not recommended hack Pin
Alexandre Nikolov20-Jan-11 22:19
MemberAlexandre Nikolov20-Jan-11 22:19 
GeneralRe: Interesting, but well known and not recommended hack Pin
Sam NG23-Jan-11 16:50
MemberSam NG23-Jan-11 16:50 
Hi Nikolov,

I completely agree with your comment and I updated the introduction to remind people they should try to rethink their design instead of just hacking the SystemClassLoader.

For me, I am extending JUnit to do some special testing, and the system requires some jars from a commercial software, and of course I can't redistribute those jars. Because I want to make the unit test easier to use (so it is easier to force developers to use this), the program will do some auto-discovery by searching the PATH to detect the install path of the commercial software if the classpath is not setup properly. I have tried using URLClassLoader to load the jars I need, but since "this" is still loaded by the SystemClassLoader, lots of the classes still can't be resolved. Unless I change my code to remove all the "compile-time dependency", i.e. loading everything by Class.forName, and use reflection to call all methods, and I have used this method on another (simpler) project, I can't think of another solution that can solve this problem.

If you have some other ideas/recommendations on how to handle this properly, please share with me because I come across of this problem very often. Thanks.

Sam

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.