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

This commit is contained in:
tedyu 2016-04-28 09:19:12 -07:00
parent 889d89a74c
commit 8a28c23431
3 changed files with 37 additions and 3 deletions

View File

@ -908,6 +908,8 @@ public final class HConstants {
public static final Pattern CP_HTD_ATTR_VALUE_PARAM_PATTERN = Pattern.compile( public static final Pattern CP_HTD_ATTR_VALUE_PARAM_PATTERN = Pattern.compile(
"(" + CP_HTD_ATTR_VALUE_PARAM_KEY_PATTERN + ")=(" + "(" + CP_HTD_ATTR_VALUE_PARAM_KEY_PATTERN + ")=(" +
CP_HTD_ATTR_VALUE_PARAM_VALUE_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) */ /** The delay when re-trying a socket operation in a loop (HBASE-4712) */
public static final int SOCKET_RETRY_WAIT_MS = 200; public static final int SOCKET_RETRY_WAIT_MS = 200;

View File

@ -264,8 +264,13 @@ public class CoprocessorClassLoader extends ClassLoaderBase {
@Override @Override
public Class<?> loadClass(String name) public Class<?> loadClass(String name)
throws ClassNotFoundException { 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 // Delegate to the parent immediately if this class is exempt
if (isClassExempt(name)) { if (isClassExempt(name, includedClassPrefixes)) {
if (LOG.isDebugEnabled()) { if (LOG.isDebugEnabled()) {
LOG.debug("Skipping exempt class " + name + LOG.debug("Skipping exempt class " + name +
" - delegating directly to parent"); " - 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; * @return true if the class should *not* be loaded by this ClassLoader;
* false otherwise. * 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) { for (String exemptPrefix : CLASS_PREFIX_EXEMPTIONS) {
if (name.startsWith(exemptPrefix)) { if (name.startsWith(exemptPrefix)) {
return true; 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.CoprocessorEnvironment;
import org.apache.hadoop.hbase.DoNotRetryIOException; import org.apache.hadoop.hbase.DoNotRetryIOException;
import org.apache.hadoop.hbase.HBaseInterfaceAudience; import org.apache.hadoop.hbase.HBaseInterfaceAudience;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTableWrapper; import org.apache.hadoop.hbase.client.HTableWrapper;
@ -177,6 +178,25 @@ public abstract class CoprocessorHost<E extends CoprocessorEnvironment> {
*/ */
public E load(Path path, String className, int priority, public E load(Path path, String className, int priority,
Configuration conf) throws IOException { 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; Class<?> implClass = null;
LOG.debug("Loading coprocessor class " + className + " with path " + LOG.debug("Loading coprocessor class " + className + " with path " +
path + " and priority " + priority); path + " and priority " + priority);
@ -192,7 +212,7 @@ public abstract class CoprocessorHost<E extends CoprocessorEnvironment> {
cl = CoprocessorClassLoader.getClassLoader( cl = CoprocessorClassLoader.getClassLoader(
path, getClass().getClassLoader(), pathPrefix, conf); path, getClass().getClassLoader(), pathPrefix, conf);
try { try {
implClass = cl.loadClass(className); implClass = ((CoprocessorClassLoader)cl).loadClass(className, includedClassPrefixes);
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new IOException("Cannot load external coprocessor class " + className, e); throw new IOException("Cannot load external coprocessor class " + className, e);
} }