Пример #1
0
  public static LiveRef read(ObjectInput in, boolean useNewFormat)
      throws IOException, ClassNotFoundException {
    Endpoint ep;
    ObjID id;

    // Now read in the endpoint, id, and result flag
    // (need to choose whether or not to read old JDK1.1 endpoint format)
    if (useNewFormat) {
      ep = TCPEndpoint.read(in);
    } else {
      ep = TCPEndpoint.readHostPortFormat(in);
    }
    id = ObjID.read(in);
    boolean isResultStream = in.readBoolean();

    LiveRef ref = new LiveRef(id, ep, false);

    if (in instanceof ConnectionInputStream) {
      ConnectionInputStream stream = (ConnectionInputStream) in;
      // save ref to send "dirty" call after all args/returns
      // have been unmarshaled.
      stream.saveRef(ref);
      if (isResultStream) {
        // set flag in stream indicating that remote objects were
        // unmarshaled.  A DGC ack should be sent by the transport.
        stream.setAckNeeded();
      }
    } else {
      DGCClient.registerRefs(ep, Arrays.asList(new LiveRef[] {ref}));
    }

    return ref;
  }
Пример #2
0
  public boolean remoteEquals(Object obj) {
    if (obj != null && obj instanceof LiveRef) {
      LiveRef ref = (LiveRef) obj;

      TCPEndpoint thisEp = ((TCPEndpoint) ep);
      TCPEndpoint refEp = ((TCPEndpoint) ref.ep);

      RMIClientSocketFactory thisClientFactory = thisEp.getClientSocketFactory();
      RMIClientSocketFactory refClientFactory = refEp.getClientSocketFactory();

      /**
       * Fix for 4254103: LiveRef.remoteEquals should not fail if one of the objects in the
       * comparison has a null server socket. Comparison should only consider the following
       * criteria:
       *
       * <p>hosts, ports, client socket factories and object IDs.
       */
      if (thisEp.getPort() != refEp.getPort() || !thisEp.getHost().equals(refEp.getHost())) {
        return false;
      }
      if ((thisClientFactory == null) ^ (refClientFactory == null)) {
        return false;
      }
      if ((thisClientFactory != null)
          && !((thisClientFactory.getClass() == refClientFactory.getClass())
              && (thisClientFactory.equals(refClientFactory)))) {
        return false;
      }
      return (id.equals(ref.id));
    } else {
      return false;
    }
  }
Пример #3
0
  public boolean equals(Object obj) {
    if (obj != null && obj instanceof LiveRef) {
      LiveRef ref = (LiveRef) obj;

      return (ep.equals(ref.ep) && id.equals(ref.id) && isLocal == ref.isLocal);
    } else {
      return false;
    }
  }
Пример #4
0
  private static void incomingMessageCall(UnicastConnection conn) throws IOException {
    ObjectInputStream in = conn.startObjectInputStream(); // (re)start ObjectInputStream

    ObjID objid = ObjID.read(in);
    int method = in.readInt();
    long hash = in.readLong();

    // System.out.println("ObjID: " + objid + ", method: " + method + ", hash: " + hash);

    // Use the objid to locate the relevant UnicastServerRef
    UnicastServerRef uref = (UnicastServerRef) objects.get(objid);
    Object returnval;
    int returncode = RETURN_ACK;
    // returnval is from Method.invoke(), so we must check the return class to see
    // if it's primitive type
    Class returncls = null;
    if (uref != null) {
      try {
        // Dispatch the call to it.
        returnval = uref.incomingMessageCall(conn, method, hash);
        returncls = uref.getMethodReturnType(method, hash);
      } catch (Exception e) {
        returnval = e;
        returncode = RETURN_NACK;
      } catch (Error e) {
        returnval =
            new ServerError("An Error is thrown while processing the invocation on the server", e);
        returncode = RETURN_NACK;
      }
    } else {
      returnval = new NoSuchObjectException("");
      returncode = RETURN_NACK;
    }

    conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK);

    ObjectOutputStream out = conn.startObjectOutputStream(); // (re)start ObjectOutputStream

    out.writeByte(returncode);
    (new UID()).write(out);

    // System.out.println("returnval=" + returnval + " returncls=" + returncls);

    if (returnval != null && returncls != null)
      ((RMIObjectOutputStream) out).writeValue(returnval, returncls);

    // 1.1/1.2 void return type detection:
    else if (!(returnval instanceof RMIVoidValue || returncls == Void.TYPE))
      out.writeObject(returnval);

    out.flush();
  }
Пример #5
0
  public void executeCall() throws Exception {
    byte returncode;
    ObjectInput oin;

    // signal the call when constructing
    try {
      DataOutputStream dout = conn.getDataOutputStream();
      dout.write(MESSAGE_CALL);

      oout = conn.startObjectOutputStream(); // (re)start ObjectOutputStream
      objid.write(oout);
      oout.writeInt(opnum);
      oout.writeLong(hash);
    } catch (IOException ex) {
      throw new MarshalException("Try to write header but failed.", ex);
    }

    try {
      releaseOutputStream();
      DataInputStream din = conn.getDataInputStream();
      if (din.readByte() != MESSAGE_CALL_ACK) throw new RemoteException("Call not acked");

      oin = startInputStream();
      returncode = oin.readByte();
      UID.read(oin);
    } catch (IOException ex) {
      throw new UnmarshalException("Try to read header but failed:", ex);
    }

    // check return code
    switch (returncode) {
      case RETURN_ACK: // it's ok
        return;
      case RETURN_NACK:
        Object returnobj;
        try {
          returnobj = oin.readObject();
        } catch (Exception ex2) {
          throw new UnmarshalException("Try to read exception object but failed", ex2);
        }

        if (!(returnobj instanceof Exception))
          throw new UnmarshalException("Should be Exception type here: " + returnobj);
        throw (Exception) returnobj;

      default:
        throw new UnmarshalException("Invalid return code");
    }
  }
Пример #6
0
  public void write(ObjectOutput out, boolean useNewFormat) throws IOException {
    boolean isResultStream = false;
    if (out instanceof ConnectionOutputStream) {
      ConnectionOutputStream stream = (ConnectionOutputStream) out;
      isResultStream = stream.isResultStream();
      /*
       * Ensure that referential integrity is not broken while
       * this LiveRef is in transit.  If it is being marshalled
       * as part of a result, it may not otherwise be strongly
       * reachable after the remote call has completed; even if
       * it is being marshalled as part of an argument, the VM
       * may determine that the reference on the stack is no
       * longer reachable after marshalling (see 6181943)--
       * therefore, tell the stream to save a reference until a
       * timeout expires or, for results, a DGCAck message has
       * been received from the caller, or for arguments, the
       * remote call has completed.  For a "local" LiveRef, save
       * a reference to the impl directly, because the impl is
       * not reachable from the LiveRef (see 4114579);
       * otherwise, save a reference to the LiveRef, for the
       * client-side DGC to watch over.  (Also see 4017232.)
       */
      if (isLocal) {
        ObjectEndpoint oe = new ObjectEndpoint(id, ep.getInboundTransport());
        Target target = ObjectTable.getTarget(oe);

        if (target != null) {
          Remote impl = target.getImpl();
          if (impl != null) {
            stream.saveObject(impl);
          }
        }
      } else {
        stream.saveObject(this);
      }
    }
    // All together now write out the endpoint, id, and flag

    // (need to choose whether or not to use old JDK1.1 endpoint format)
    if (useNewFormat) {
      ((TCPEndpoint) ep).write(out);
    } else {
      ((TCPEndpoint) ep).writeHostPortFormat(out);
    }
    id.write(out);
    out.writeBoolean(isResultStream);
  }
Пример #7
0
  public void write(ObjectOutput out, boolean useNewFormat) throws IOException {
    boolean isResultStream = false;
    if (out instanceof ConnectionOutputStream) {
      ConnectionOutputStream stream = (ConnectionOutputStream) out;
      isResultStream = stream.isResultStream();
      /*
       * If this LiveRef is being marshalled as part of a return value,
       * then we have to worry about referential integrity being broken
       * while the reference is in transit, in case there no longer
       * remains a strong reference in this VM after the call has
       * completed.  Therefore, we tell the stream to save a reference
       * until an acknowledgment has been received from the caller; for
       * "local" LiveRefs, save a reference to the impl directly,
       * because the impl is not reachable from this LiveRef (see
       * 4114579); otherwise, save a reference to the LiveRef, for the
       * client-side DGC to watch over (see 4017232 for more details).
       */
      if (isResultStream) {
        if (isLocal) {
          Target target = ObjectTable.getTarget(id);
          if (target != null) {
            Remote impl = target.getImpl();
            if (impl != null) {
              stream.saveObject(impl);
            }
          }
        } else {
          stream.saveObject(this);
        }
      }
    }
    // All together now write out the endpoint, id, and flag

    // (need to choose whether or not to use old JDK1.1 endpoint format)
    if (useNewFormat) {
      ((TCPEndpoint) ep).write(out);
    } else {
      ((TCPEndpoint) ep).writeHostPortFormat(out);
    }
    id.write(out);
    out.writeBoolean(isResultStream);
  }
Пример #8
0
 public int hashCode() {
   return id.hashCode();
 }