Search in sources :

Example 1 with RemoteCall

use of java.rmi.server.RemoteCall in project jdk8u_jdk by JetBrains.

the class UnicastRef method invoke.

/**
     * Invoke a method. This form of delegating method invocation
     * to the reference allows the reference to take care of
     * setting up the connection to the remote host, marshalling
     * some representation for the method and parameters, then
     * communicating the method invocation to the remote host.
     * This method either returns the result of a method invocation
     * on the remote object which resides on the remote host or
     * throws a RemoteException if the call failed or an
     * application-level exception if the remote invocation throws
     * an exception.
     *
     * @param obj the proxy for the remote object
     * @param method the method to be invoked
     * @param params the parameter list
     * @param opnum  a hash that may be used to represent the method
     * @since 1.2
     */
public Object invoke(Remote obj, Method method, Object[] params, long opnum) throws Exception {
    if (clientRefLog.isLoggable(Log.VERBOSE)) {
        clientRefLog.log(Log.VERBOSE, "method: " + method);
    }
    if (clientCallLog.isLoggable(Log.VERBOSE)) {
        logClientCall(obj, method);
    }
    Connection conn = ref.getChannel().newConnection();
    RemoteCall call = null;
    boolean reuse = true;
    /* If the call connection is "reused" early, remember not to
         * reuse again.
         */
    boolean alreadyFreed = false;
    try {
        if (clientRefLog.isLoggable(Log.VERBOSE)) {
            clientRefLog.log(Log.VERBOSE, "opnum = " + opnum);
        }
        // create call context
        call = new StreamRemoteCall(conn, ref.getObjID(), -1, opnum);
        // marshal parameters
        try {
            ObjectOutput out = call.getOutputStream();
            marshalCustomCallData(out);
            Class<?>[] types = method.getParameterTypes();
            for (int i = 0; i < types.length; i++) {
                marshalValue(types[i], params[i], out);
            }
        } catch (IOException e) {
            clientRefLog.log(Log.BRIEF, "IOException marshalling arguments: ", e);
            throw new MarshalException("error marshalling arguments", e);
        }
        // unmarshal return
        call.executeCall();
        try {
            Class<?> rtype = method.getReturnType();
            if (rtype == void.class)
                return null;
            ObjectInput in = call.getInputStream();
            /* StreamRemoteCall.done() does not actually make use
                 * of conn, therefore it is safe to reuse this
                 * connection before the dirty call is sent for
                 * registered refs.
                 */
            Object returnValue = unmarshalValue(rtype, in);
            /* we are freeing the connection now, do not free
                 * again or reuse.
                 */
            alreadyFreed = true;
            /* if we got to this point, reuse must have been true. */
            clientRefLog.log(Log.BRIEF, "free connection (reuse = true)");
            /* Free the call's connection early. */
            ref.getChannel().free(conn, true);
            return returnValue;
        } catch (IOException e) {
            clientRefLog.log(Log.BRIEF, "IOException unmarshalling return: ", e);
            throw new UnmarshalException("error unmarshalling return", e);
        } catch (ClassNotFoundException e) {
            clientRefLog.log(Log.BRIEF, "ClassNotFoundException unmarshalling return: ", e);
            throw new UnmarshalException("error unmarshalling return", e);
        } finally {
            try {
                call.done();
            } catch (IOException e) {
                /* WARNING: If the conn has been reused early,
                     * then it is too late to recover from thrown
                     * IOExceptions caught here. This code is relying
                     * on StreamRemoteCall.done() not actually
                     * throwing IOExceptions.
                     */
                reuse = false;
            }
        }
    } catch (RuntimeException e) {
        /*
             * Need to distinguish between client (generated by the
             * invoke method itself) and server RuntimeExceptions.
             * Client side RuntimeExceptions are likely to have
             * corrupted the call connection and those from the server
             * are not likely to have done so.  If the exception came
             * from the server the call connection should be reused.
             */
        if ((call == null) || (((StreamRemoteCall) call).getServerException() != e)) {
            reuse = false;
        }
        throw e;
    } catch (RemoteException e) {
        /*
             * Some failure during call; assume connection cannot
             * be reused.  Must assume failure even if ServerException
             * or ServerError occurs since these failures can happen
             * during parameter deserialization which would leave
             * the connection in a corrupted state.
             */
        reuse = false;
        throw e;
    } catch (Error e) {
        /* If errors occurred, the connection is most likely not
             *  reusable.
             */
        reuse = false;
        throw e;
    } finally {
        /* alreadyFreed ensures that we do not log a reuse that
             * may have already happened.
             */
        if (!alreadyFreed) {
            if (clientRefLog.isLoggable(Log.BRIEF)) {
                clientRefLog.log(Log.BRIEF, "free connection (reuse = " + reuse + ")");
            }
            ref.getChannel().free(conn, reuse);
        }
    }
}
Also used : MarshalException(java.rmi.MarshalException) ObjectOutput(java.io.ObjectOutput) Connection(sun.rmi.transport.Connection) IOException(java.io.IOException) StreamRemoteCall(sun.rmi.transport.StreamRemoteCall) UnmarshalException(java.rmi.UnmarshalException) RemoteObject(java.rmi.server.RemoteObject) ObjectInput(java.io.ObjectInput) RemoteException(java.rmi.RemoteException) StreamRemoteCall(sun.rmi.transport.StreamRemoteCall) RemoteCall(java.rmi.server.RemoteCall)

Example 2 with RemoteCall

use of java.rmi.server.RemoteCall in project jdk8u_jdk by JetBrains.

the class UnicastRef method newCall.

/**
     * Create an appropriate call object for a new call on this object.
     * Passing operation array and index, allows the stubs generator to
     * assign the operation indexes and interpret them. The RemoteRef
     * may need the operation to encode in for the call.
     */
public RemoteCall newCall(RemoteObject obj, Operation[] ops, int opnum, long hash) throws RemoteException {
    clientRefLog.log(Log.BRIEF, "get connection");
    Connection conn = ref.getChannel().newConnection();
    try {
        clientRefLog.log(Log.VERBOSE, "create call context");
        /* log information about the outgoing call */
        if (clientCallLog.isLoggable(Log.VERBOSE)) {
            logClientCall(obj, ops[opnum]);
        }
        RemoteCall call = new StreamRemoteCall(conn, ref.getObjID(), opnum, hash);
        try {
            marshalCustomCallData(call.getOutputStream());
        } catch (IOException e) {
            throw new MarshalException("error marshaling " + "custom call data");
        }
        return call;
    } catch (RemoteException e) {
        ref.getChannel().free(conn, false);
        throw e;
    }
}
Also used : MarshalException(java.rmi.MarshalException) StreamRemoteCall(sun.rmi.transport.StreamRemoteCall) Connection(sun.rmi.transport.Connection) IOException(java.io.IOException) RemoteException(java.rmi.RemoteException) StreamRemoteCall(sun.rmi.transport.StreamRemoteCall) RemoteCall(java.rmi.server.RemoteCall)

Example 3 with RemoteCall

use of java.rmi.server.RemoteCall in project jdk8u_jdk by JetBrains.

the class InterfaceHash method main.

public static void main(String[] args) throws Exception {
    System.err.println("\nRegression test for bug 4472769");
    System.err.println("\n=== verifying that J2SE registry's skeleton uses" + "\ncorrect interface hash and operation numbers:");
    Registry testImpl = LocateRegistry.createRegistry(PORT);
    System.err.println("created test registry on port " + PORT);
    RemoteRef ref = new UnicastRef(new LiveRef(new ObjID(ObjID.REGISTRY_ID), new TCPEndpoint("", PORT), false));
    Registry referenceStub = new ReferenceRegistryStub(ref);
    System.err.println("created reference registry stub: " + referenceStub);
    referenceStub.bind(NAME, referenceStub);
    System.err.println("bound name \"" + NAME + "\" in registry");
    String[] list = referenceStub.list();
    System.err.println("list of registry contents: " + Arrays.asList(list));
    if (list.length != 1 || !list[0].equals(NAME)) {
        throw new RuntimeException("TEST FAILED: unexpected list contents");
    }
    Registry result = (Registry) referenceStub.lookup(NAME);
    System.err.println("lookup of name \"" + NAME + "\" returned: " + result);
    if (!result.equals(referenceStub)) {
        throw new RuntimeException("TEST FAILED: unexpected lookup result");
    }
    referenceStub.rebind(NAME, referenceStub);
    referenceStub.unbind(NAME);
    System.err.println("unbound name \"" + NAME + "\"");
    list = referenceStub.list();
    System.err.println("list of registry contents: " + Arrays.asList(list));
    if (list.length != 0) {
        throw new RuntimeException("TEST FAILED: list not empty");
    }
    System.err.println("\n=== verifying that J2SE registry's stub uses" + "correct interface hash:");
    class FakeRemoteRef implements RemoteRef {

        long hash;

        int opnum;

        public RemoteCall newCall(RemoteObject obj, Operation[] op, int opnum, long hash) {
            this.hash = hash;
            this.opnum = opnum;
            throw new UnsupportedOperationException();
        }

        public void invoke(RemoteCall call) {
        }

        public void done(RemoteCall call) {
        }

        public Object invoke(Remote obj, Method method, Object[] args, long hash) {
            throw new UnsupportedOperationException();
        }

        public String getRefClass(java.io.ObjectOutput out) {
            return "FakeRemoteRef";
        }

        public int remoteHashCode() {
            return 1013;
        }

        public boolean remoteEquals(RemoteRef obj) {
            return false;
        }

        public String remoteToString() {
            return "FakeRemoteRef";
        }

        public void writeExternal(java.io.ObjectOutput out) {
        }

        public void readExternal(java.io.ObjectInput in) {
        }
    }
    FakeRemoteRef f = new FakeRemoteRef();
    Registry testRegistry = LocateRegistry.getRegistry(PORT);
    System.err.println("created original test registry stub: " + testRegistry);
    Class stubClass = testRegistry.getClass();
    System.err.println("test registry stub class: " + stubClass);
    Constructor cons = stubClass.getConstructor(new Class[] { RemoteRef.class });
    Registry testStub = (Registry) cons.newInstance(new Object[] { f });
    System.err.println("created new instrumented test registry stub: " + testStub);
    System.err.println("invoking bind:");
    try {
        testStub.bind(NAME, referenceStub);
    } catch (UnsupportedOperationException e) {
    }
    System.err.println("hash == " + f.hash + ", opnum == " + f.opnum);
    if (f.hash != 4905912898345647071L) {
        throw new RuntimeException("TEST FAILED: wrong interface hash");
    } else if (f.opnum != 0) {
        throw new RuntimeException("TEST FAILED: wrong operation number");
    }
    System.err.println("invoking list:");
    try {
        testStub.list();
    } catch (UnsupportedOperationException e) {
    }
    System.err.println("hash == " + f.hash + ", opnum == " + f.opnum);
    if (f.hash != 4905912898345647071L) {
        throw new RuntimeException("TEST FAILED: wrong interface hash");
    } else if (f.opnum != 1) {
        throw new RuntimeException("TEST FAILED: wrong operation number");
    }
    System.err.println("invoking lookup:");
    try {
        testStub.lookup(NAME);
    } catch (UnsupportedOperationException e) {
    }
    System.err.println("hash == " + f.hash + ", opnum == " + f.opnum);
    if (f.hash != 4905912898345647071L) {
        throw new RuntimeException("TEST FAILED: wrong interface hash");
    } else if (f.opnum != 2) {
        throw new RuntimeException("TEST FAILED: wrong operation number");
    }
    System.err.println("invoking rebind:");
    try {
        testStub.rebind(NAME, referenceStub);
    } catch (UnsupportedOperationException e) {
    }
    System.err.println("hash == " + f.hash + ", opnum == " + f.opnum);
    if (f.hash != 4905912898345647071L) {
        throw new RuntimeException("TEST FAILED: wrong interface hash");
    } else if (f.opnum != 3) {
        throw new RuntimeException("TEST FAILED: wrong operation number");
    }
    System.err.println("invoking unbind:");
    try {
        testStub.unbind(NAME);
    } catch (UnsupportedOperationException e) {
    }
    System.err.println("hash == " + f.hash + ", opnum == " + f.opnum);
    if (f.hash != 4905912898345647071L) {
        throw new RuntimeException("TEST FAILED: wrong interface hash");
    } else if (f.opnum != 4) {
        throw new RuntimeException("TEST FAILED: wrong operation number");
    }
    System.err.println("TEST PASSED");
}
Also used : Constructor(java.lang.reflect.Constructor) RemoteRef(java.rmi.server.RemoteRef) Remote(java.rmi.Remote) Registry(java.rmi.registry.Registry) LocateRegistry(java.rmi.registry.LocateRegistry) Method(java.lang.reflect.Method) TCPEndpoint(sun.rmi.transport.tcp.TCPEndpoint) LiveRef(sun.rmi.transport.LiveRef) RemoteObject(java.rmi.server.RemoteObject) ObjID(java.rmi.server.ObjID) RemoteObject(java.rmi.server.RemoteObject) UnicastRef(sun.rmi.server.UnicastRef) RemoteCall(java.rmi.server.RemoteCall)

Example 4 with RemoteCall

use of java.rmi.server.RemoteCall in project jdk8u_jdk by JetBrains.

the class TCPTransport method handleMessages.

/**
     * handleMessages decodes transport operations and handles messages
     * appropriately.  If an exception occurs during message handling,
     * the socket is closed.
     */
void handleMessages(Connection conn, boolean persistent) {
    int port = getEndpoint().getPort();
    try {
        DataInputStream in = new DataInputStream(conn.getInputStream());
        do {
            // transport op
            int op = in.read();
            if (op == -1) {
                if (tcpLog.isLoggable(Log.BRIEF)) {
                    tcpLog.log(Log.BRIEF, "(port " + port + ") connection closed");
                }
                break;
            }
            if (tcpLog.isLoggable(Log.BRIEF)) {
                tcpLog.log(Log.BRIEF, "(port " + port + ") op = " + op);
            }
            switch(op) {
                case TransportConstants.Call:
                    // service incoming RMI call
                    RemoteCall call = new StreamRemoteCall(conn);
                    if (serviceCall(call) == false)
                        return;
                    break;
                case TransportConstants.Ping:
                    // send ack for ping
                    DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                    out.writeByte(TransportConstants.PingAck);
                    conn.releaseOutputStream();
                    break;
                case TransportConstants.DGCAck:
                    DGCAckHandler.received(UID.read(in));
                    break;
                default:
                    throw new IOException("unknown transport op " + op);
            }
        } while (persistent);
    } catch (IOException e) {
        // exception during processing causes connection to close (below)
        if (tcpLog.isLoggable(Log.BRIEF)) {
            tcpLog.log(Log.BRIEF, "(port " + port + ") exception: ", e);
        }
    } finally {
        try {
            conn.close();
        } catch (IOException ex) {
        // eat exception
        }
    }
}
Also used : StreamRemoteCall(sun.rmi.transport.StreamRemoteCall) DataOutputStream(java.io.DataOutputStream) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) Endpoint(sun.rmi.transport.Endpoint) StreamRemoteCall(sun.rmi.transport.StreamRemoteCall) RemoteCall(java.rmi.server.RemoteCall)

Aggregations

RemoteCall (java.rmi.server.RemoteCall)4 IOException (java.io.IOException)3 StreamRemoteCall (sun.rmi.transport.StreamRemoteCall)3 MarshalException (java.rmi.MarshalException)2 RemoteException (java.rmi.RemoteException)2 RemoteObject (java.rmi.server.RemoteObject)2 Connection (sun.rmi.transport.Connection)2 DataInputStream (java.io.DataInputStream)1 DataOutputStream (java.io.DataOutputStream)1 ObjectInput (java.io.ObjectInput)1 ObjectOutput (java.io.ObjectOutput)1 Constructor (java.lang.reflect.Constructor)1 Method (java.lang.reflect.Method)1 Remote (java.rmi.Remote)1 UnmarshalException (java.rmi.UnmarshalException)1 LocateRegistry (java.rmi.registry.LocateRegistry)1 Registry (java.rmi.registry.Registry)1 ObjID (java.rmi.server.ObjID)1 RemoteRef (java.rmi.server.RemoteRef)1 UnicastRef (sun.rmi.server.UnicastRef)1