HBASE-15686 Add override mechanism for the exempt classes when dynamically loading table coprocessor

This commit is contained in:
tedyu 2016-04-28 09:21:22 -07:00
parent 2b0913eea4
commit c512750914
3 changed files with 37 additions and 3 deletions

View File

@ -892,6 +892,8 @@ public final class HConstants {
public static final Pattern CP_HTD_ATTR_VALUE_PARAM_PATTERN = Pattern.compile(
"(" + CP_HTD_ATTR_VALUE_PARAM_KEY_PATTERN + ")=(" +
CP_HTD_ATTR_VALUE_PARAM_VALUE_PATTERN + "),?");
public static final String CP_HTD_ATTR_INCLUSION_KEY =
"hbase.coprocessor.classloader.included.classes";
/** The delay when re-trying a socket operation in a loop (HBASE-4712) */
public static final int SOCKET_RETRY_WAIT_MS = 200;

View File

@ -277,8 +277,13 @@ public class CoprocessorClassLoader extends ClassLoaderBase {
@Override
public Class<?> loadClass(String name)
throws ClassNotFoundException {
return loadClass(name, null);
}
public Class<?> loadClass(String name, String[] includedClassPrefixes)
throws ClassNotFoundException {
// Delegate to the parent immediately if this class is exempt
if (isClassExempt(name)) {
if (isClassExempt(name, includedClassPrefixes)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Skipping exempt class " + name +
" - delegating directly to parent");
@ -357,7 +362,14 @@ public class CoprocessorClassLoader extends ClassLoaderBase {
* @return true if the class should *not* be loaded by this ClassLoader;
* false otherwise.
*/
protected boolean isClassExempt(String name) {
protected boolean isClassExempt(String name, String[] includedClassPrefixes) {
if (includedClassPrefixes != null) {
for (String clsName : includedClassPrefixes) {
if (name.startsWith(clsName)) {
return false;
}
}
}
for (String exemptPrefix : CLASS_PREFIX_EXEMPTIONS) {
if (name.startsWith(exemptPrefix)) {
return true;

View File

@ -43,6 +43,7 @@ import org.apache.hadoop.hbase.Coprocessor;
import org.apache.hadoop.hbase.CoprocessorEnvironment;
import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTableInterface;
@ -178,6 +179,25 @@ public abstract class CoprocessorHost<E extends CoprocessorEnvironment> {
*/
public E load(Path path, String className, int priority,
Configuration conf) throws IOException {
String[] includedClassPrefixes = null;
if (conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY) != null){
String prefixes = conf.get(HConstants.CP_HTD_ATTR_INCLUSION_KEY);
includedClassPrefixes = prefixes.split(";");
}
return load(path, className, priority, conf, includedClassPrefixes);
}
/**
* Load a coprocessor implementation into the host
* @param path path to implementation jar
* @param className the main class name
* @param priority chaining priority
* @param conf configuration for coprocessor
* @param includedClassPrefixes class name prefixes to include
* @throws java.io.IOException Exception
*/
public E load(Path path, String className, int priority,
Configuration conf, String[] includedClassPrefixes) throws IOException {
Class<?> implClass = null;
LOG.debug("Loading coprocessor class " + className + " with path " +
path + " and priority " + priority);
@ -193,7 +213,7 @@ public abstract class CoprocessorHost<E extends CoprocessorEnvironment> {
cl = CoprocessorClassLoader.getClassLoader(
path, getClass().getClassLoader(), pathPrefix, conf);
try {
implClass = cl.loadClass(className);
implClass = ((CoprocessorClassLoader)cl).loadClass(className, includedClassPrefixes);
} catch (ClassNotFoundException e) {
throw new IOException("Cannot load external coprocessor class " + className, e);
}