code: public synchronized void handleMessage(ChaincodeMessage message) throws Exception {
  
  		if (message.getType() == ChaincodeMessage.Type.KEEPALIVE){
  			logger.debug(String.format("[%s] Recieved KEEPALIVE message, do nothing",
  					shortID(message)));
  			// Received a keep alive message, we don't do anything with it for now
  			// and it does not touch the state machine
  				return;
  		}
  
  		logger.debug(String.format("[%s]Handling ChaincodeMessage of type: %s(state:%s)",
  				shortID(message), message.getType(), fsm.current()));
  
  		if (fsm.eventCannotOccur(message.getType().toString())) {
  			String errStr = String.format("[%s]Chaincode handler org.hyperledger.fabric.java.fsm cannot handle message (%s) with payload size (%d) while in state: %s",
  					message.getTxid(), message.getType(), message.getPayload().size(), fsm.current());
  			ByteString payload = ByteString.copyFromUtf8(errStr);
  			ChaincodeMessage errormessage = ChaincodeMessage.newBuilder()
  					.setType(ERROR)
  					.setPayload(payload)
  					.setTxid(message.getTxid())
  					.build();
  			serialSend(errormessage);
  			throw new RuntimeException(errStr);
  		}
  
  		// Filter errors to allow NoTransitionError and CanceledError
  		// to not propagate for cases where embedded Err == nil.
  		try {
  			fsm.raiseEvent(message.getType().toString(), message);
  		} catch (NoTransitionException e) {
  			if (e.error != null) throw e;
  			logger.debug("["+ shortID(message)+"]Ignoring NoTransitionError");
  		} catch (CancelledException e) {
  			if (e.error != null) throw e;
  			logger.debug("["+ shortID(message)+"]Ignoring CanceledError");
  		}
  	}
docs: handleMessage message handles loop for org.hyperledger.fabric.java.shim side of chaincode/validator stream.