HBASE-15686 Add override mechanism for the exempt classes when dynamically loading table coprocessor
This commit is contained in:
parent
2b0913eea4
commit
c512750914
|
@ -892,6 +892,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;
|
||||||
|
|
|
@ -277,8 +277,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");
|
||||||
|
@ -357,7 +362,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;
|
||||||
|
|
|
@ -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.HTableInterface;
|
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,
|
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);
|
||||||
|
@ -193,7 +213,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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue