use of sun.tools.java.Type in project jdk8u_jdk by JetBrains.
the class RMIGenerator method writeStubMethod.
/**
* Write the stub method for the remote method with the given "opnum".
*/
private void writeStubMethod(IndentingWriter p, int opnum) throws IOException {
RemoteClass.Method method = remoteMethods[opnum];
Identifier methodName = method.getName();
Type methodType = method.getType();
Type[] paramTypes = methodType.getArgumentTypes();
String[] paramNames = nameParameters(paramTypes);
Type returnType = methodType.getReturnType();
ClassDeclaration[] exceptions = method.getExceptions();
/*
* Declare stub method; throw exceptions declared in remote
* interface(s).
*/
p.pln("// implementation of " + methodType.typeString(methodName.toString(), true, false));
p.p("public " + returnType + " " + methodName + "(");
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0)
p.p(", ");
p.p(paramTypes[i] + " " + paramNames[i]);
}
p.plnI(")");
if (exceptions.length > 0) {
p.p("throws ");
for (int i = 0; i < exceptions.length; i++) {
if (i > 0)
p.p(", ");
p.p(exceptions[i].getName().toString());
}
p.pln();
}
p.pOlnI("{");
/*
* The RemoteRef.invoke methods throw Exception, but unless this
* stub method throws Exception as well, we must catch Exceptions
* thrown from the invocation. So we must catch Exception and
* rethrow something we can throw: UnexpectedException, which is a
* subclass of RemoteException. But for any subclasses of Exception
* that we can throw, like RemoteException, RuntimeException, and
* any of the exceptions declared by this stub method, we want them
* to pass through unharmed, so first we must catch any such
* exceptions and rethrow it directly.
*
* We have to be careful generating the rethrowing catch blocks
* here, because javac will flag an error if there are any
* unreachable catch blocks, i.e. if the catch of an exception class
* follows a previous catch of it or of one of its superclasses.
* The following method invocation takes care of these details.
*/
Vector<ClassDefinition> catchList = computeUniqueCatchList(exceptions);
/*
* If we need to catch any particular exceptions (i.e. this method
* does not declare java.lang.Exception), put the entire stub
* method in a try block.
*/
if (catchList.size() > 0) {
p.plnI("try {");
}
if (version == STUB_VERSION_FAT) {
p.plnI("if (useNewInvoke) {");
}
if (version == STUB_VERSION_FAT || version == STUB_VERSION_1_2) {
if (!returnType.isType(TC_VOID)) {
// REMIND: why $?
p.p("Object $result = ");
}
p.p("ref.invoke(this, " + methodFieldNames[opnum] + ", ");
if (paramTypes.length > 0) {
p.p("new java.lang.Object[] {");
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0)
p.p(", ");
p.p(wrapArgumentCode(paramTypes[i], paramNames[i]));
}
p.p("}");
} else {
p.p("null");
}
p.pln(", " + method.getMethodHash() + "L);");
if (!returnType.isType(TC_VOID)) {
p.pln("return " + unwrapArgumentCode(returnType, "$result") + ";");
}
}
if (version == STUB_VERSION_FAT) {
p.pOlnI("} else {");
}
if (version == STUB_VERSION_1_1 || version == STUB_VERSION_FAT) {
p.pln(idRemoteCall + " call = ref.newCall((" + idRemoteObject + ") this, operations, " + opnum + ", interfaceHash);");
if (paramTypes.length > 0) {
p.plnI("try {");
p.pln("java.io.ObjectOutput out = call.getOutputStream();");
writeMarshalArguments(p, "out", paramTypes, paramNames);
p.pOlnI("} catch (java.io.IOException e) {");
p.pln("throw new " + idMarshalException + "(\"error marshalling arguments\", e);");
p.pOln("}");
}
p.pln("ref.invoke(call);");
if (returnType.isType(TC_VOID)) {
p.pln("ref.done(call);");
} else {
// REMIND: why $?
p.pln(returnType + " $result;");
p.plnI("try {");
p.pln("java.io.ObjectInput in = call.getInputStream();");
boolean objectRead = writeUnmarshalArgument(p, "in", returnType, "$result");
p.pln(";");
p.pOlnI("} catch (java.io.IOException e) {");
p.pln("throw new " + idUnmarshalException + "(\"error unmarshalling return\", e);");
/*
* If any only if readObject has been invoked, we must catch
* ClassNotFoundException as well as IOException.
*/
if (objectRead) {
p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
p.pln("throw new " + idUnmarshalException + "(\"error unmarshalling return\", e);");
}
p.pOlnI("} finally {");
p.pln("ref.done(call);");
p.pOln("}");
p.pln("return $result;");
}
}
if (version == STUB_VERSION_FAT) {
// end if/else (useNewInvoke) block
p.pOln("}");
}
/*
* If we need to catch any particular exceptions, finally write
* the catch blocks for them, rethrow any other Exceptions with an
* UnexpectedException, and end the try block.
*/
if (catchList.size() > 0) {
for (Enumeration<ClassDefinition> enumeration = catchList.elements(); enumeration.hasMoreElements(); ) {
ClassDefinition def = enumeration.nextElement();
p.pOlnI("} catch (" + def.getName() + " e) {");
p.pln("throw e;");
}
p.pOlnI("} catch (java.lang.Exception e) {");
p.pln("throw new " + idUnexpectedException + "(\"undeclared checked exception\", e);");
// end try/catch block
p.pOln("}");
}
// end stub method
p.pOln("}");
}
use of sun.tools.java.Type in project jdk8u_jdk by JetBrains.
the class RemoteClass method computeInterfaceHash.
/**
* Compute the "interface hash" of the stub/skeleton pair for this
* remote implementation class. This is the 64-bit value used to
* enforce compatibility between a stub and a skeleton using the
* JDK 1.1 version of the stub/skeleton protocol.
*
* It is calculated using the first 64 bits of a SHA digest. The
* digest is from a stream consisting of the following data:
* (int) stub version number, always 1
* for each remote method, in order of operation number:
* (UTF) method name
* (UTF) method type signature
* for each declared exception, in alphabetical name order:
* (UTF) name of exception class
*
*/
private long computeInterfaceHash() {
long hash = 0;
ByteArrayOutputStream sink = new ByteArrayOutputStream(512);
try {
MessageDigest md = MessageDigest.getInstance("SHA");
DataOutputStream out = new DataOutputStream(new DigestOutputStream(sink, md));
out.writeInt(INTERFACE_HASH_STUB_VERSION);
for (int i = 0; i < remoteMethods.length; i++) {
MemberDefinition m = remoteMethods[i].getMemberDefinition();
Identifier name = m.getName();
Type type = m.getType();
out.writeUTF(name.toString());
// type signatures already use mangled class names
out.writeUTF(type.getTypeSignature());
ClassDeclaration[] exceptions = m.getExceptions(env);
sortClassDeclarations(exceptions);
for (int j = 0; j < exceptions.length; j++) {
out.writeUTF(Names.mangleClass(exceptions[j].getName()).toString());
}
}
out.flush();
// use only the first 64 bits of the digest for the hash
byte[] hashArray = md.digest();
for (int i = 0; i < Math.min(8, hashArray.length); i++) {
hash += ((long) (hashArray[i] & 0xFF)) << (i * 8);
}
} catch (IOException e) {
throw new Error("unexpected exception computing intetrface hash: " + e);
} catch (NoSuchAlgorithmException e) {
throw new Error("unexpected exception computing intetrface hash: " + e);
}
return hash;
}
use of sun.tools.java.Type in project jdk8u_jdk by JetBrains.
the class RMIGenerator method writeSkeletonDispatchCase.
/**
* Write the case block for the skeleton's dispatch method for
* the remote method with the given "opnum".
*/
private void writeSkeletonDispatchCase(IndentingWriter p, int opnum) throws IOException {
RemoteClass.Method method = remoteMethods[opnum];
Identifier methodName = method.getName();
Type methodType = method.getType();
Type[] paramTypes = methodType.getArgumentTypes();
String[] paramNames = nameParameters(paramTypes);
Type returnType = methodType.getReturnType();
p.pOlnI("case " + opnum + ": // " + methodType.typeString(methodName.toString(), true, false));
/*
* Use nested block statement inside case to provide an independent
* namespace for local variables used to unmarshal parameters for
* this remote method.
*/
p.pOlnI("{");
if (paramTypes.length > 0) {
/*
* Declare local variables to hold arguments.
*/
for (int i = 0; i < paramTypes.length; i++) {
p.pln(paramTypes[i] + " " + paramNames[i] + ";");
}
/*
* Unmarshal arguments from call stream.
*/
p.plnI("try {");
p.pln("java.io.ObjectInput in = call.getInputStream();");
boolean objectsRead = writeUnmarshalArguments(p, "in", paramTypes, paramNames);
p.pOlnI("} catch (java.io.IOException e) {");
p.pln("throw new " + idUnmarshalException + "(\"error unmarshalling arguments\", e);");
/*
* If any only if readObject has been invoked, we must catch
* ClassNotFoundException as well as IOException.
*/
if (objectsRead) {
p.pOlnI("} catch (java.lang.ClassNotFoundException e) {");
p.pln("throw new " + idUnmarshalException + "(\"error unmarshalling arguments\", e);");
}
p.pOlnI("} finally {");
p.pln("call.releaseInputStream();");
p.pOln("}");
} else {
p.pln("call.releaseInputStream();");
}
if (!returnType.isType(TC_VOID)) {
/*
* Declare variable to hold return type, if not void.
*/
// REMIND: why $?
p.p(returnType + " $result = ");
}
/*
* Invoke the method on the server object.
*/
p.p("server." + methodName + "(");
for (int i = 0; i < paramNames.length; i++) {
if (i > 0)
p.p(", ");
p.p(paramNames[i]);
}
p.pln(");");
/*
* Always invoke getResultStream(true) on the call object to send
* the indication of a successful invocation to the caller. If
* the return type is not void, keep the result stream and marshal
* the return value.
*/
p.plnI("try {");
if (!returnType.isType(TC_VOID)) {
p.p("java.io.ObjectOutput out = ");
}
p.pln("call.getResultStream(true);");
if (!returnType.isType(TC_VOID)) {
writeMarshalArgument(p, "out", returnType, "$result");
p.pln(";");
}
p.pOlnI("} catch (java.io.IOException e) {");
p.pln("throw new " + idMarshalException + "(\"error marshalling return\", e);");
p.pOln("}");
// break from switch statement
p.pln("break;");
// end nested block statement
p.pOlnI("}");
p.pln();
}
use of sun.tools.java.Type in project jdk8u_jdk by JetBrains.
the class RMIGenerator method writeMethodFieldInitializers.
/**
* Write code to initialize the static fields for each method
* using the Java Reflection API.
*/
private void writeMethodFieldInitializers(IndentingWriter p) throws IOException {
for (int i = 0; i < methodFieldNames.length; i++) {
p.p(methodFieldNames[i] + " = ");
/*
* Here we look up the Method object in the arbitrary interface
* that we find in the RemoteClass.Method object.
* REMIND: Is this arbitrary choice OK?
* REMIND: Should this access be part of RemoteClass.Method's
* abstraction?
*/
RemoteClass.Method method = remoteMethods[i];
MemberDefinition def = method.getMemberDefinition();
Identifier methodName = method.getName();
Type methodType = method.getType();
Type[] paramTypes = methodType.getArgumentTypes();
p.p(def.getClassDefinition().getName() + ".class.getMethod(\"" + methodName + "\", new java.lang.Class[] {");
for (int j = 0; j < paramTypes.length; j++) {
if (j > 0)
p.p(", ");
p.p(paramTypes[j] + ".class");
}
p.pln("});");
}
}
Aggregations