HBASE-14347 Add a switch to DynamicClassLoader to disable it (huaxiang sun)

This commit is contained in:
Matteo Bertozzi 2015-10-05 16:17:07 -07:00
parent ef8cc7a575
commit 12e8076fba
2 changed files with 54 additions and 4 deletions

View File

@ -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_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; private File localDir;
// FileSystem of the remote path, set only if remoteDir != null // 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) { final Configuration conf, final ClassLoader parent) {
super(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, Long>(); jarModifiedTime = new HashMap<String, Long>();
String localDirPath = conf.get( String localDirPath = conf.get(
LOCAL_DIR_KEY, DEFAULT_LOCAL_DIR) + DYNAMIC_JARS_DIR; 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"); 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: // Check whether the class has already been loaded:
Class<?> clasz = findLoadedClass(name); Class<?> clasz = findLoadedClass(name);
if (clasz != null) { if (clasz != null) {
@ -149,7 +173,6 @@ public class DynamicClassLoader extends ClassLoaderBase {
} }
return clasz; return clasz;
} }
}
} }
private synchronized void loadNewJars() { private synchronized void loadNewJars() {

View File

@ -29,6 +29,7 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseCommonTestingUtility; import org.apache.hadoop.hbase.HBaseCommonTestingUtility;
import org.apache.hadoop.hbase.testclassification.SmallTests; import org.apache.hadoop.hbase.testclassification.SmallTests;
import org.junit.Test; import org.junit.Test;
import org.junit.Before;
import org.junit.experimental.categories.Category; 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 Log LOG = LogFactory.getLog(TestDynamicClassLoader.class);
private static final HBaseCommonTestingUtility TEST_UTIL = new HBaseCommonTestingUtility(); private static final HBaseCommonTestingUtility TEST_UTIL = new HBaseCommonTestingUtility();
private static final Configuration conf = TEST_UTIL.getConfiguration(); private Configuration conf;
static { 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 @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 { private void deleteClass(String className) throws Exception {
String jarFileName = className + ".jar"; String jarFileName = className + ".jar";
File file = new File(TEST_UTIL.getDataTestDir().toString(), jarFileName); File file = new File(TEST_UTIL.getDataTestDir().toString(), jarFileName);