Search in sources :

Example 1 with Type

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("}");
}
Also used : ClassDefinition(sun.tools.java.ClassDefinition) Type(sun.tools.java.Type) Identifier(sun.tools.java.Identifier) ClassDeclaration(sun.tools.java.ClassDeclaration)

Example 2 with Type

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;
}
Also used : DataOutputStream(java.io.DataOutputStream) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) Type(sun.tools.java.Type) Identifier(sun.tools.java.Identifier) ClassDeclaration(sun.tools.java.ClassDeclaration) DigestOutputStream(java.security.DigestOutputStream) MessageDigest(java.security.MessageDigest) MemberDefinition(sun.tools.java.MemberDefinition)

Example 3 with Type

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();
}
Also used : Type(sun.tools.java.Type) Identifier(sun.tools.java.Identifier)

Example 4 with Type

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("});");
    }
}
Also used : Type(sun.tools.java.Type) Identifier(sun.tools.java.Identifier) MemberDefinition(sun.tools.java.MemberDefinition)

Aggregations

Identifier (sun.tools.java.Identifier)4 Type (sun.tools.java.Type)4 ClassDeclaration (sun.tools.java.ClassDeclaration)2 MemberDefinition (sun.tools.java.MemberDefinition)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 DataOutputStream (java.io.DataOutputStream)1 IOException (java.io.IOException)1 DigestOutputStream (java.security.DigestOutputStream)1 MessageDigest (java.security.MessageDigest)1 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)1 ClassDefinition (sun.tools.java.ClassDefinition)1