public Registry getObject ( final String command ) throws Exception { String host; int port; int sep = command.indexOf(':'); if ( sep < 0 ) { port = new Random().nextInt(65535); host = command; } else { host = command.substring(0, sep); port = Integer.valueOf(command.substring(sep + 1)); } ObjID id = new ObjID(new Random().nextInt()); // RMI registry TCPEndpoint te = new TCPEndpoint(host, port); UnicastRef ref = new UnicastRef(new LiveRef(id, te, false)); RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref); Registry proxy = (Registry) Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[] { Registry.class }, obj); return proxy; }
public StreamRemoteCall(Connection c, ObjID id, int op, long hash) throws RemoteException { try { conn = c; Transport.transportLog.log(Log.VERBOSE, "write remote call header..."); // write out remote call header info... // call header, part 1 (read by Transport) conn.getOutputStream().write(TransportConstants.Call); getOutputStream(); // creates a MarshalOutputStream id.write(out); // object id (target of call) // call header, part 2 (read by Dispatcher) out.writeInt(op); // method number (operation index) out.writeLong(hash); // stub/skeleton hash } catch (IOException e) { throw new MarshalException("Error marshaling call header", e); } }
public Registry getObject ( String connection ) throws Exception { String host; int port; int sep = connection.indexOf(':'); if ( sep < 0 ) { port = new Random().nextInt(65535); host = connection; } else { host = connection.substring(0, sep); port = Integer.valueOf(connection.substring(sep + 1)); } ObjID id = new ObjID(new Random().nextInt()); // RMI registry TCPEndpoint te = new TCPEndpoint(host, port); UnicastRef ref = new UnicastRef(new LiveRef(id, te, false)); RemoteObjectInvocationHandler obj = new RemoteObjectInvocationHandler(ref); Registry proxy = (Registry) Proxy.newProxyInstance(JRMPClient.class.getClassLoader(), new Class[] { Registry.class }, obj); return proxy; }
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { manager = UnicastConnectionManager.read(in); objid = ObjID.read(in); byte ack = in.readByte(); // This byte is somewhat confusing when interoperating with JDK if (ack != RETURN_ACK && ack != 0/* jdk ack value */) { throw new IOException("no ack found"); } // Notify the DGC of the remote side that we hold the reference to the // received object. Do not notify if the client and server are on the // same virtual machine. if (manager.serverobj == null) LeaseRenewingTask.scheduleLeases(this); }
/** * Creates a NinjaRemoteRef which points to the object on the given hostname * and port with the given object ID. Used to manually bootstrap a * client-side reference to a remote object (that is, without going through * the registry). * // * @param host * The hostname to contact to call on this remote object. // * @param port * The port to contact to call on this remote object. * @param oid * The ObjID corresponding to the remote object. // * @param comm_type * One of NinjaExportData.RMI_COMM_TYPE_* values, specifying the * communication semantics for the call. */ public NinjaRemoteRef( // String host, // int port, ObjID oid, String server){ // int comm_type) { // DEBUG(System.out.println("NinjaRemoteRef constructor called with: // "+host+":"+port+" objid "+oid)); debug = new Debug(); debug.print("NinjaRemoteRef constructor called with: " // + host + ":" // + port + " objid " + oid); // remotehost = host; // remoteport = port; objid = oid; this.server=server; // commtype = comm_type; }
/** * Reads everything left except Endpoint info from the given stream and * detects if DGC ack is needed. * * @param in the stream to read data from * * @throws IOException if any I/O error occurred * @throws ClassNotFoundException if class could not be loaded by current * class loader */ protected void readCommon(ObjectInput in) throws IOException, ClassNotFoundException { objId = ObjID.read(in); boolean needAck = in.readBoolean(); if (in instanceof RMIObjectInputStream) { RMIObjectInputStream oin = (RMIObjectInputStream) in; if (oin.isRemoteCallStream()) { oin.needDGCAck(needAck); } } RMIObjectInfo info = ExportManager.getInfo(objId); if ((info == null) || !info.sref.remoteEquals(this)) { /* * This remote object created in another VM so * register it in ClientDGC. */ ClientDGC.registerForRenew(this); } }
RMIObjectInfo(RMIReference ref, ObjID id, UnicastServerRef sref, Remote stub) { this.ref = ref; this.id = id; this.sref = sref; this.stub = stub; acc = AccessController.getContext(); ClassLoader objCl = ref.get().getClass().getClassLoader(); ClassLoader threadCl = Thread.currentThread().getContextClassLoader(); if (threadCl == null) { loader = objCl; } else if (objCl == null || RMIUtil.isParentLoader(threadCl, objCl)) { loader = threadCl; } else { loader = objCl; } }
/** * Construct a Target for a remote object "impl" with * a specific object id. * * If "permanent" is true, then the impl is pinned permanently * (the impl will not be collected via distributed and/or local * GC). If "on" is false, than the impl is subject to * collection. Permanent objects do not keep a server from * exiting. */ public Target(Remote impl, Dispatcher disp, Remote stub, ObjID id, boolean permanent) { this.weakImpl = new WeakRef(impl, ObjectTable.reapQueue); this.disp = disp; this.stub = stub; this.id = id; this.acc = AccessController.getContext(); /* * Fix for 4149366: so that downloaded parameter types unmarshalled * for this impl will be compatible with types known only to the * impl class's class loader (when it's not identical to the * exporting thread's context class loader), mark the impl's class * loader as the loader to use as the context class loader in the * server's dispatch thread while a call to this impl is being * processed (unless this exporting thread's context class loader is * a child of the impl's class loader, such as when a registry is * exported by an application, in which case this thread's context * class loader is preferred). */ ClassLoader threadContextLoader = Thread.currentThread().getContextClassLoader(); ClassLoader serverLoader = impl.getClass().getClassLoader(); if (checkLoaderAncestry(threadContextLoader, serverLoader)) { this.ccl = threadContextLoader; } else { this.ccl = serverLoader; } this.permanent = permanent; if (permanent) { pinImpl(); } }
/** * Process client VM signalling reference for given ObjID: forward to * corresponding Target entry. If ObjID is not found in table, * no action is taken. */ static void referenced(ObjID id, long sequenceNum, VMID vmid) { synchronized (tableLock) { ObjectEndpoint oe = new ObjectEndpoint(id, Transport.currentTransport()); Target target = objTable.get(oe); if (target != null) { target.referenced(sequenceNum, vmid); } } }
/** * Process client VM dropping reference for given ObjID: forward to * corresponding Target entry. If ObjID is not found in table, * no action is taken. */ static void unreferenced(ObjID id, long sequenceNum, VMID vmid, boolean strong) { synchronized (tableLock) { ObjectEndpoint oe = new ObjectEndpoint(id, Transport.currentTransport()); Target target = objTable.get(oe); if (target != null) target.unreferenced(sequenceNum, vmid, strong); } }
/** * The clean call removes the VMID from the set of clients * that hold references to the object associated with the LiveRef * ref. The sequence number is used to detect late clean calls. If the * argument "strong" is true, then the clean call is a result of a * failed "dirty" call, thus the sequence number for the VMID needs * to be remembered until the client goes away. */ public void clean(ObjID[] ids, long sequenceNum, VMID vmid, boolean strong) { for (ObjID id : ids) { if (dgcLog.isLoggable(Log.VERBOSE)) { dgcLog.log(Log.VERBOSE, "id = " + id + ", vmid = " + vmid + ", strong = " + strong); } ObjectTable.unreferenced(id, sequenceNum, vmid, strong); } }
public Void run() { ClassLoader savedCcl = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader( ClassLoader.getSystemClassLoader()); /* * Put remote collector object in table by hand to prevent * listen on port. (UnicastServerRef.exportObject would * cause transport to listen.) */ try { dgc = new DGCImpl(); ObjID dgcID = new ObjID(ObjID.DGC_ID); LiveRef ref = new LiveRef(dgcID, 0); UnicastServerRef disp = new UnicastServerRef(ref); Remote stub = Util.createProxy(DGCImpl.class, new UnicastRef(ref), true); disp.setSkeleton(dgc); Target target = new Target(dgc, disp, stub, dgcID, true); ObjectTable.putTarget(target); } catch (RemoteException e) { throw new Error( "exception initializing server-side DGC", e); } } finally { Thread.currentThread().setContextClassLoader(savedCcl); } return null; }
/** * Create an array of ObjIDs (needed for the DGC remote calls) * from the ids in the given set of refs. */ private static ObjID[] createObjIDArray(Set<RefEntry> refEntries) { ObjID[] ids = new ObjID[refEntries.size()]; Iterator<RefEntry> iter = refEntries.iterator(); for (int i = 0; i < ids.length; i++) { ids[i] = iter.next().getRef().getObjID(); } return ids; }
/** * Construct a new live reference for a server object in the local * address space, to use sockets of the specified type. */ public LiveRef(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) { this((new ObjID()), port, csf, ssf); }
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; }
/** * Construct a new Activator on a specified port. */ ActivatorImpl(int port, RMIServerSocketFactory ssf) throws RemoteException { /* Server ref must be created and assigned before remote object * 'this' can be exported. */ LiveRef lref = new LiveRef(new ObjID(ObjID.ACTIVATOR_ID), port, null, ssf); UnicastServerRef uref = new UnicastServerRef(lref); ref = uref; uref.exportObject(this, null, false); }
ActivationSystemImpl(int port, RMIServerSocketFactory ssf) throws RemoteException { /* Server ref must be created and assigned before remote object * 'this' can be exported. */ LiveRef lref = new LiveRef(new ObjID(4), port, null, ssf); UnicastServerRef uref = new UnicastServerRef(lref); ref = uref; uref.exportObject(this, null); }