diff --git hbase-common/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java hbase-common/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java index 81e4483..2d5eb5d 100644 --- hbase-common/src/main/java/org/apache/hadoop/hbase/util/DynamicClassLoader.java +++ 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 hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestDynamicClassLoader.java hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestDynamicClassLoader.java index 9269f2f..57514e3 100644 --- hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestDynamicClassLoader.java +++ hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestDynamicClassLoader.java @@ -30,6 +30,7 @@ import org.apache.hadoop.hbase.HBaseCommonTestingUtility; import org.apache.hadoop.hbase.testclassification.MiscTests; import org.apache.hadoop.hbase.testclassification.SmallTests; import org.junit.Test; +import org.junit.Before; import org.junit.experimental.categories.Category; /** @@ -40,10 +41,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 @@ -95,6 +102,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);