Index: security/src/main/java/org/apache/hadoop/hbase/ipc/SecureRpcEngine.java =================================================================== --- security/src/main/java/org/apache/hadoop/hbase/ipc/SecureRpcEngine.java (revision 1383749) +++ security/src/main/java/org/apache/hadoop/hbase/ipc/SecureRpcEngine.java (working copy) @@ -162,7 +162,7 @@ startTime = System.currentTimeMillis(); } HbaseObjectWritable value = (HbaseObjectWritable) - client.call(new Invocation(method, args), address, + client.call(new Invocation(method, protocol, args), address, protocol, ticket, rpcTimeout); if (logDebug) { long callTime = System.currentTimeMillis() - startTime; @@ -234,7 +234,7 @@ Invocation[] invocations = new Invocation[params.length]; for (int i = 0; i < params.length; i++) - invocations[i] = new Invocation(method, params[i]); + invocations[i] = new Invocation(method, protocol, params[i]); SecureClient client = CLIENTS.getClient(conf); try { Writable[] wrappedValues = Index: src/main/java/org/apache/hadoop/hbase/client/coprocessor/Exec.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/client/coprocessor/Exec.java (revision 1383749) +++ src/main/java/org/apache/hadoop/hbase/client/coprocessor/Exec.java (working copy) @@ -64,7 +64,7 @@ byte[] row, Class protocol, Method method, Object[] parameters) { - super(method, parameters); + super(method, protocol, parameters); this.conf = configuration; this.referenceRow = row; this.protocol = protocol; Index: src/main/java/org/apache/hadoop/hbase/ipc/WritableRpcEngine.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/ipc/WritableRpcEngine.java (revision 1383749) +++ src/main/java/org/apache/hadoop/hbase/ipc/WritableRpcEngine.java (working copy) @@ -148,7 +148,7 @@ } HbaseObjectWritable value = (HbaseObjectWritable) - client.call(new Invocation(method, args), address, + client.call(new Invocation(method, protocol, args), address, protocol, ticket, rpcTimeout); if (logDebug) { // FIGURE HOW TO TURN THIS OFF! @@ -210,7 +210,7 @@ Invocation[] invocations = new Invocation[params.length]; for (int i = 0; i < params.length; i++) - invocations[i] = new Invocation(method, params[i]); + invocations[i] = new Invocation(method, protocol, params[i]); HBaseClient client = CLIENTS.getClient(conf); try { Writable[] wrappedValues = Index: src/main/java/org/apache/hadoop/hbase/ipc/Invocation.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/ipc/Invocation.java (revision 1383749) +++ src/main/java/org/apache/hadoop/hbase/ipc/Invocation.java (working copy) @@ -45,26 +45,27 @@ public Invocation() {} - public Invocation(Method method, Object[] parameters) { + public Invocation(Method method, + Class declaringClass, Object[] parameters) { this.methodName = method.getName(); this.parameterClasses = method.getParameterTypes(); this.parameters = parameters; - if (method.getDeclaringClass().equals(VersionedProtocol.class)) { + if (declaringClass.equals(VersionedProtocol.class)) { //VersionedProtocol is exempted from version check. clientVersion = 0; clientMethodsHash = 0; } else { try { - Field versionField = method.getDeclaringClass().getField("VERSION"); + Field versionField = declaringClass.getField("VERSION"); versionField.setAccessible(true); - this.clientVersion = versionField.getLong(method.getDeclaringClass()); + this.clientVersion = versionField.getLong(declaringClass); } catch (NoSuchFieldException ex) { - throw new RuntimeException("The " + method.getDeclaringClass(), ex); + throw new RuntimeException("The " + declaringClass, ex); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } - this.clientMethodsHash = ProtocolSignature.getFingerprint(method - .getDeclaringClass().getMethods()); + this.clientMethodsHash = ProtocolSignature.getFingerprint( + declaringClass.getMethods()); } } @@ -169,4 +170,4 @@ public byte getVersion() { return RPC_VERSION; } -} \ No newline at end of file +} Index: src/test/java/org/apache/hadoop/hbase/ipc/TestProtocolExtension.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/ipc/TestProtocolExtension.java (revision 0) +++ src/test/java/org/apache/hadoop/hbase/ipc/TestProtocolExtension.java (working copy) @@ -0,0 +1,103 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hbase.ipc; + +import java.io.IOException; +import java.net.InetSocketAddress; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.hbase.SmallTests; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** Unit test for Protocol extending common interface. */ +@Category(SmallTests.class) +public class TestProtocolExtension { + private static final String ADDRESS = "0.0.0.0"; + + public static final Log LOG = + LogFactory.getLog(TestProtocolExtension.class); + + private static Configuration conf = new Configuration(); + + public interface ProtocolExtention { + void logClassName(); + } + + public interface TestProtocol extends VersionedProtocol, ProtocolExtention { + public static final long VERSION = 7L; + + void ping() throws IOException; + + // @Override // Uncomment to make the test pass + // public void logClassName(); +} + + public static class TestImpl implements TestProtocol { + public long getProtocolVersion(String protocol, long clientVersion) { + return TestProtocol.VERSION; + } + + @Override + public void ping() {} + + @Override + public void logClassName() { + LOG.info(this.getClass().getName()); + } + + @Override + public ProtocolSignature getProtocolSignature(String protocol, + long clientVersion, int clientMethodsHash) throws IOException { + return new ProtocolSignature(VERSION, null); + } + } + + @Test + public void testCalls() throws Exception { + RpcServer server = HBaseRPC.getServer(TestProtocol.class, + new TestImpl(), + new Class[]{ProtocolExtention.class}, + ADDRESS, + 6016, + 10, 10, false, + conf, 10); + TestProtocol proxy = null; + try { + server.start(); + + InetSocketAddress addr = server.getListenerAddress(); + proxy = (TestProtocol)HBaseRPC.getProxy( + TestProtocol.class, TestProtocol.VERSION, addr, conf, 10000); + + proxy.ping(); + + proxy.logClassName(); + } finally { + server.stop(); + if(proxy!=null) HBaseRPC.stopProxy(proxy); + } + } + + @org.junit.Rule + public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = + new org.apache.hadoop.hbase.ResourceCheckerJUnitRule(); +}