code: @Override
      public void recover() throws JMSException {
          checkClosed();
          
          //let's get all unacknowledged message identifiers
          List<SQSMessageIdentifier> unAckedMessages = acknowledger.getUnAckMessages();
          acknowledger.forgetUnAckMessages();
          
          //let's summarize which queues and which message groups we're nacked
          //we have to purge all prefetched messages and queued up callback entries for affected queues and groups
          //if not, we would end up consuming messages out of order
          Map<String, Set<String>> queueToGroupsMapping = getAffectedGroupsPerQueueUrl(unAckedMessages);
  
          for (SQSMessageConsumer consumer : this.messageConsumers) {
              SQSQueueDestination sqsQueue = (SQSQueueDestination)consumer.getQueue();
              Set<String> affectedGroups = queueToGroupsMapping.get(sqsQueue.getQueueUrl());
              if (affectedGroups != null) {
                  unAckedMessages.addAll(consumer.purgePrefetchedMessagesWithGroups(affectedGroups));
              }
          }
          
          unAckedMessages.addAll(sqsSessionRunnable.purgeScheduledCallbacksForQueuesAndGroups(queueToGroupsMapping));
          
          if (!unAckedMessages.isEmpty()) {
              negativeAcknowledger.bulkAction(unAckedMessages, unAckedMessages.size());
          }
      }
docs: Negative acknowledges all the messages on the session that is delivered
  but not acknowledged.
  
  @throws JMSException
  If session is closed or on internal error.