diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java index e4345588e72..c1194ca805f 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java @@ -66,6 +66,11 @@ public class DynamicClassLoader extends ClassLoaderBase { private static final String DYNAMIC_JARS_DIR_KEY = "hbase.dynamic.jars.dir"; + private static final String DYNAMIC_JARS_OPTIONAL_CONF_KEY = "hbase.use.dynamic.jars"; + private static final boolean DYNAMIC_JARS_OPTIONAL_DEFAULT = true; + + private boolean useDynamicJars; + private File localDir; // FileSystem of the remote path, set only if remoteDir != null @@ -86,6 +91,15 @@ public class DynamicClassLoader extends ClassLoaderBase { final Configuration conf, final ClassLoader parent) { super(parent); + useDynamicJars = conf.getBoolean( + DYNAMIC_JARS_OPTIONAL_CONF_KEY, DYNAMIC_JARS_OPTIONAL_DEFAULT); + + if (useDynamicJars) { + initTempDir(conf); + } + } + + private void initTempDir(final Configuration conf) { jarModifiedTime = new HashMap(); String localDirPath = conf.get( LOCAL_DIR_KEY, DEFAULT_LOCAL_DIR) + DYNAMIC_JARS_DIR; @@ -120,7 +134,17 @@ public class DynamicClassLoader extends ClassLoaderBase { LOG.debug("Class " + name + " not found - using dynamical class loader"); } - synchronized (getClassLoadingLock(name)) { + if (useDynamicJars) { + return tryRefreshClass(name); + } + throw e; + } + } + + + private Class tryRefreshClass(String name) + throws ClassNotFoundException { + synchronized (getClassLoadingLock(name)) { // Check whether the class has already been loaded: Class clasz = findLoadedClass(name); if (clasz != null) { @@ -149,7 +173,6 @@ public class DynamicClassLoader extends ClassLoaderBase { } return clasz; } - } } private synchronized void loadNewJars() { diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestDynamicClassLoader.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestDynamicClassLoader.java index 2f26f4b5e94..612f3f8b8d8 100644 --- a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestDynamicClassLoader.java +++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestDynamicClassLoader.java @@ -29,6 +29,7 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseCommonTestingUtility; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.junit.Test; +import org.junit.Before; import org.junit.experimental.categories.Category; /** @@ -39,10 +40,16 @@ public class TestDynamicClassLoader { private static final Log LOG = LogFactory.getLog(TestDynamicClassLoader.class); private static final HBaseCommonTestingUtility TEST_UTIL = new HBaseCommonTestingUtility(); - private static final Configuration conf = TEST_UTIL.getConfiguration(); + private Configuration conf; static { - conf.set("hbase.dynamic.jars.dir", TEST_UTIL.getDataTestDir().toString()); + TEST_UTIL.getConfiguration().set( + "hbase.dynamic.jars.dir", TEST_UTIL.getDataTestDir().toString()); + } + + @Before + public void initializeConfiguration() { + conf = new Configuration(TEST_UTIL.getConfiguration()); } @Test @@ -94,6 +101,26 @@ public class TestDynamicClassLoader { } } + @Test + public void testLoadClassFromLocalPathWithDynamicDirOff() throws Exception { + conf.setBoolean("hbase.use.dynamic.jars", false); + ClassLoader parent = TestDynamicClassLoader.class.getClassLoader(); + DynamicClassLoader classLoader = new DynamicClassLoader(conf, parent); + + String className = "TestLoadClassFromLocalPath"; + deleteClass(className); + + try { + String folder = TEST_UTIL.getDataTestDir().toString(); + ClassLoaderTestHelper.buildJar( + folder, className, null, ClassLoaderTestHelper.localDirPath(conf)); + classLoader.loadClass(className); + fail("Should not be able to load class " + className); + } catch (ClassNotFoundException cnfe) { + // expected, move on + } + } + private void deleteClass(String className) throws Exception { String jarFileName = className + ".jar"; File file = new File(TEST_UTIL.getDataTestDir().toString(), jarFileName);