code: public void run() {
  
  	BufferedWriter out = null;
  
  	try {
  	    out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
  	    try {
  
  		CallbackResponse hd =
  		    new CallbackResponse( socket.getInputStream() );
  
  		if (hd.protocolVersion != GRAMProtocol.GRAM_PROTOCOL_VERSION) {
  		    throw new Exception("Gram callback protocol version mismatch");
  		}
  
  		GramJob job = handler.getJob( hd.jobManagerUrl );
  		if (job == null) {
  		    throw new Exception("Not registered with this handler: " +
  					hd.jobManagerUrl);
  		}
  
  		job.setError( hd.failureCode );
  		// the exit code needs to be set before the
  		// status, since setStatus triggers a listener
  		// notification
  		job.setExitCode ( hd.exitCode );
  		job.setStatus( hd.status );
  
  		if (job.getStatus() == GramJob.STATUS_DONE ||
  		    job.getStatus() == GramJob.STATUS_FAILED) {
  		    handler.unregisterJob(job);
  		}
  
  		try {
  		    out.write(GRAMProtocol.OKReply());
  		    out.flush();
  		} catch(IOException ignoreE) {
  		    logger.debug("Ignoring IOException");
  		}
  
  	    } catch(AuthorizationException ex) {
  		logger.debug("Authorization failed", ex);
  		out.write(GRAMProtocol.ErrorReply(401, "Authorization Failed"));
  		out.flush();
  	    } catch (Exception ex) {
  		logger.debug("General error", ex);
  		out.write(GRAMProtocol.ErrorReply(400, ex.getMessage()));
  		out.flush();
  	    }
  	} catch (IOException e) {
  	    logger.debug("IO Error", e);
  	} finally {
  	    try {
  		socket.close();
  	    } catch (IOException e) { }
  	}
      }
docs: Listen on the server socket for a client, start another thread to
  keep listening on the server socket, then deal with the client.