We’ve all done it before I guess. Called Class.forName( “com.foo.MyClass” ) to load some class at runtime based on some configurable class name. At first it seems very groovy.
However this does not work very well in application servers, containers or various environments like Maven, Ant, JUnit etc. The days of everything being in the system class loader are over, now we need to live in a multiple-classloader world.
Solution? Try use the current thread’s context class loader or the class loader used to load your code. So try replace this…
Class theClass = Class.forName( className );with this more verbose version (which could easily be wrapped in a helper method)
Class theClass = null;try {theClass = Thread.currentThread().getContextClassLoader().loadClass( className );}catch (ClassNotFoundException e) {theClass = getClass().getClassLoader().loadClass( className );}Henri, this could be a possible addition to commons lang?
While we’re talking about living in multi-classloader worlds, bob’s new project ClassWorlds looks very groovy.
This certainly goes a long way towards solving classloader issues – I always seem to get bitten by XML parsers in this regard. What it doesn’t always solve is the situation of colliding packages. I’ve hit a situation where the app. server is using a version of Xerces thats older than the version my app. wants to use. This gets messy, and the exact behaviour depends on your app. server’s classloading policy (it doesn’t help that the servlet spec. appears to be in conflict with the java language spec. on the issue of classloader delegation order).