}
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
ServerSerializationStreamReader streamReader =
new ServerSerializationStreamReader(classLoader, serializationPolicyProvider);
streamReader.prepareToRead(encodedRequest);
RpcToken rpcToken = null;
if (streamReader.hasFlags(AbstractSerializationStream.FLAG_RPC_TOKEN_INCLUDED)) {
// Read the RPC token
rpcToken = (RpcToken) streamReader.deserializeValue(RpcToken.class);
}
// Read the name of the RemoteService interface
String serviceIntfName = maybeDeobfuscate(streamReader, streamReader.readString());
if (type != null) {
if (!implementsInterface(type, serviceIntfName)) {
// The service does not implement the requested interface
throw new IncompatibleRemoteServiceException("Blocked attempt to access interface '"
+ serviceIntfName + "', which is not implemented by '" + printTypeName(type)
+ "'; this is either misconfiguration or a hack attempt");
}
}
SerializationPolicy serializationPolicy = streamReader.getSerializationPolicy();
Class<?> serviceIntf;
try {
serviceIntf = getClassFromSerializedName(serviceIntfName, classLoader);
if (!RemoteService.class.isAssignableFrom(serviceIntf)) {
// The requested interface is not a RemoteService interface
throw new IncompatibleRemoteServiceException(
"Blocked attempt to access interface '"
+ printTypeName(serviceIntf)
+ "', which doesn't extend RemoteService; this is either "
+ "misconfiguration or a hack attempt");
}
} catch (ClassNotFoundException e) {
throw new IncompatibleRemoteServiceException("Could not locate requested interface '"
+ serviceIntfName + "' in default classloader", e);
}
String serviceMethodName = streamReader.readString();
int paramCount = streamReader.readInt();
if (paramCount > streamReader.getNumberOfTokens()) {
throw new IncompatibleRemoteServiceException("Invalid number of parameters");
}
Class<?>[] parameterTypes = new Class[paramCount];
for (int i = 0; i < parameterTypes.length; i++) {
String paramClassName = maybeDeobfuscate(streamReader, streamReader.readString());
try {
parameterTypes[i] = getClassFromSerializedName(paramClassName, classLoader);
} catch (ClassNotFoundException e) {
throw new IncompatibleRemoteServiceException("Parameter " + i
+ " of is of an unknown type '" + paramClassName + "'", e);
}
}
try {
Method method = serviceIntf.getMethod(serviceMethodName, parameterTypes);
// The parameter types we have are the non-parameterized versions in the
// RPC stream. For stronger message verification, get the parameterized
// types from the method declaration.
Type[] methodParameterTypes = method.getGenericParameterTypes();
DequeMap<TypeVariable<?>, Type> resolvedTypes = new DequeMap<TypeVariable<?>, Type>();
TypeVariable<Method>[] methodTypes = method.getTypeParameters();
for (TypeVariable<Method> methodType : methodTypes) {
SerializabilityUtil.resolveTypes(methodType, resolvedTypes);
}
Object[] parameterValues = new Object[parameterTypes.length];
for (int i = 0; i < parameterValues.length; i++) {
parameterValues[i] = streamReader.deserializeValue(parameterTypes[i],
methodParameterTypes[i], resolvedTypes);
}
return new RPCRequest(method, parameterValues, rpcToken, serializationPolicy, streamReader
.getFlags());
} catch (NoSuchMethodException e) {
throw new IncompatibleRemoteServiceException(formatMethodNotFoundErrorMessage(serviceIntf,
serviceMethodName, parameterTypes));
}