diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java index 88cfa9a..327bedc 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java @@ -908,6 +908,7 @@ 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; diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/CoprocessorClassLoader.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/CoprocessorClassLoader.java index e586930..78ecc7e 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/CoprocessorClassLoader.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/CoprocessorClassLoader.java @@ -264,8 +264,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"); @@ -344,7 +349,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; diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java index dbeb122..da0e8b1 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/coprocessor/CoprocessorHost.java @@ -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.HTableWrapper; @@ -177,6 +178,25 @@ public abstract class CoprocessorHost { */ 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); @@ -192,7 +212,7 @@ public abstract class CoprocessorHost { 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); }