Author: oheger Date: Mon Nov 19 20:43:14 2012 New Revision: 1411400 URL: http://svn.apache.org/viewvc?rev=1411400&view=rev Log: Added a central method for loading classes dynamically.
Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java?rev=1411400&r1=1411399&r2=1411400&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java (original) +++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration/ConfigurationUtils.java Mon Nov 19 20:43:14 2012 @@ -774,6 +774,40 @@ public final class ConfigurationUtils } /** + * Loads the class with the given name. This method is used whenever a class + * has to be loaded dynamically. It first tries the current thread's context + * class loader. If this fails, the class loader of this class is tried. + * + * @param clsName the name of the class to be loaded + * @return the loaded class + * @throws ClassNotFoundException if the class cannot be resolved + */ + public static Class<?> loadClass(String clsName) + throws ClassNotFoundException + { + if (LOG.isDebugEnabled()) + { + LOG.debug("Loading class " + clsName); + } + + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + try + { + if (cl != null) + { + return cl.loadClass(clsName); + } + } + catch (ClassNotFoundException cnfex) + { + LOG.info("Could not load class " + clsName + + " using CCL. Falling back to default CL.", cnfex); + } + + return ConfigurationUtils.class.getClassLoader().loadClass(clsName); + } + + /** * Creates an {@code ImmutableConfiguration} from the given * {@code Configuration} object. This method creates a proxy object wrapping * the original configuration and making it available under the Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java?rev=1411400&r1=1411399&r2=1411400&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java (original) +++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration/TestConfigurationUtils.java Mon Nov 19 20:43:14 2012 @@ -35,6 +35,8 @@ import junitx.framework.ListAssert; import org.apache.commons.configuration.tree.DefaultExpressionEngine; import org.apache.commons.configuration.tree.ExpressionEngine; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import com.mockobjects.dynamic.Mock; @@ -46,11 +48,29 @@ import com.mockobjects.dynamic.Mock; */ public class TestConfigurationUtils { - protected Configuration config = new BaseConfiguration(); + /** Constant for the name of a class to be loaded. */ + private static final String CLS_NAME = + "org.apache.commons.configuration.PropertiesConfiguration"; + + /** Stores the CCL. */ + private ClassLoader ccl; + + @Before + public void setUp() throws Exception + { + ccl = Thread.currentThread().getContextClassLoader(); + } + + @After + public void tearDown() throws Exception + { + Thread.currentThread().setContextClassLoader(ccl); + } @Test public void testToString() { + Configuration config = new BaseConfiguration(); String lineSeparator = System.getProperty("line.separator"); assertEquals("String representation of an empty configuration", "", ConfigurationUtils.toString(config)); @@ -457,4 +477,55 @@ public class TestConfigurationUtils { ConfigurationUtils.enableRuntimeExceptions(null); } + + /** + * Tests whether a class can be loaded from CCL. + */ + @Test + public void testLoadClassFromCCL() throws ClassNotFoundException + { + Thread.currentThread().setContextClassLoader( + getClass().getClassLoader()); + assertEquals("Wrong class", CLS_NAME, + ConfigurationUtils.loadClass(CLS_NAME).getName()); + } + + /** + * Tests whether a class can be loaded if there is no CCL. + */ + @Test + public void testLoadClassCCLNull() throws ClassNotFoundException + { + Thread.currentThread().setContextClassLoader(null); + assertEquals("Wrong class", CLS_NAME, + ConfigurationUtils.loadClass(CLS_NAME).getName()); + } + + /** + * Tests whether a class can be loaded if it is not found by the CCL. + */ + @Test + public void testLoadClassCCLNotFound() throws ClassNotFoundException + { + Thread.currentThread().setContextClassLoader(new ClassLoader() + { + @Override + public Class<?> loadClass(String name) + throws ClassNotFoundException + { + throw new ClassNotFoundException(name); + } + }); + assertEquals("Wrong class", CLS_NAME, + ConfigurationUtils.loadClass(CLS_NAME).getName()); + } + + /** + * Tests the behavior of loadClass() for a non-existing class. + */ + @Test(expected = ClassNotFoundException.class) + public void testLoadClassNotFound() throws ClassNotFoundException + { + ConfigurationUtils.loadClass("a non existing class!"); + } }