diff --git src/main/java/org/apache/hadoop/hbase/client/coprocessor/Exec.java src/main/java/org/apache/hadoop/hbase/client/coprocessor/Exec.java index 504bd77..54c9db8 100644 --- src/main/java/org/apache/hadoop/hbase/client/coprocessor/Exec.java +++ src/main/java/org/apache/hadoop/hbase/client/coprocessor/Exec.java @@ -56,6 +56,7 @@ public class Exec extends Invocation implements Row { /** Row key used as a reference for any region lookups */ private byte[] referenceRow; private Class protocol; + private String protocolName; public Exec() { } @@ -68,6 +69,11 @@ public class Exec extends Invocation implements Row { this.conf = configuration; this.referenceRow = row; this.protocol = protocol; + this.protocolName = protocol.getName(); + } + + public String getProtocolName() { + return protocolName; } public Class getProtocol() { @@ -117,12 +123,13 @@ public class Exec extends Invocation implements Row { } // fields for Exec referenceRow = Bytes.readByteArray(in); - String protocolName = in.readUTF(); + protocolName = in.readUTF(); try { protocol = (Class)conf.getClassByName(protocolName); } catch (ClassNotFoundException cnfe) { - throw new IOException("Protocol class "+protocolName+" not found", cnfe); + // can't do eager instantiation. pass it as a string and try to deserialize later. + //throw new IOException("Protocol class "+protocolName+" not found", cnfe); } } } diff --git src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java index 3bd75b8..c56e283 100644 --- src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java +++ src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java @@ -49,6 +49,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantReadWriteLock; +import com.google.common.collect.Maps; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; @@ -178,6 +179,9 @@ public class HRegion implements HeapSize { // , Writable{ // Registered region protocol handlers private ClassToInstanceMap protocolHandlers = MutableClassToInstanceMap.create(); + + private Map> + protocolHandlerNames = Maps.newHashMap(); //These variable are just used for getting data out of the region, to test on //client side @@ -3903,6 +3907,7 @@ public class HRegion implements HeapSize { // , Writable{ } protocolHandlers.putInstance(protocol, handler); + protocolHandlerNames.put(protocol.getName(), protocol); if (LOG.isDebugEnabled()) { LOG.debug("Registered protocol handler: region="+ Bytes.toStringBinary(getRegionName())+" protocol="+protocol.getName()); @@ -3928,6 +3933,19 @@ public class HRegion implements HeapSize { // , Writable{ public ExecResult exec(Exec call) throws IOException { Class protocol = call.getProtocol(); + if (protocol == null) { + String protocolName = call.getProtocolName(); + if (LOG.isDebugEnabled()) { + LOG.debug("Received dynamic protocol exec call with protocolName " + protocolName); + } + // detect the actual protocol class + protocol = protocolHandlerNames.get(protocolName); + if (protocol == null) { + throw new HBaseRPC.UnknownProtocolException(protocol, + "No matching handler for protocol "+protocolName+ + " in region "+Bytes.toStringBinary(getRegionName())); + } + } if (!protocolHandlers.containsKey(protocol)) { throw new HBaseRPC.UnknownProtocolException(protocol, "No matching handler for protocol "+protocol.getName()+ diff --git src/main/java/org/apache/hadoop/hbase/util/BloomFilterFactory.java src/main/java/org/apache/hadoop/hbase/util/BloomFilterFactory.java index 33ecfb3..8d22a46 100644 --- src/main/java/org/apache/hadoop/hbase/util/BloomFilterFactory.java +++ src/main/java/org/apache/hadoop/hbase/util/BloomFilterFactory.java @@ -196,4 +196,4 @@ public final class BloomFilterFactory { public static int getBloomBlockSize(Configuration conf) { return conf.getInt(IO_STOREFILE_BLOOM_BLOCK_SIZE, 128 * 1024); } -}; +}