private void secondChance(RRObject obj) throws ClassNotFoundException, IOException {
   try {
     obj.runProtocol(_srv, _ois, _oos);
   } catch (PDBatchTaskExecutorException e2) {
     utils.Messenger.getInstance()
         .msg(
             "PDBTEC2ListenerThread.run(): sending NoWorkerAvailableResponse() to client...", 1);
     // e.printStackTrace();
     _oos.writeObject(new NoWorkerAvailableResponse(((TaskObjectsExecutionRequest) obj)._tasks));
     _oos.flush();
   } catch (IOException e2) {
     utils.Messenger.getInstance()
         .msg("PDBTEC2ListenerThread.run(): sending FailedReply to client...", 1);
     // e.printStackTrace();
     _oos.writeObject(new FailedReply());
     _oos.flush();
   }
 }
 /**
  * reads from the input stream the initialization command sent to it, sends back to the client
  * an <CODE>OKReply</CODE> "ACK" msg, and then enters an infinite loop waiting to read from the
  * input stream an <CODE>RRObject</CODE> obj that should really be of type <CODE>
  * TaskObjectsExecutionRequest</CODE>, on which it executes its method <CODE>
  * obj.runProtocol(_srv,_ois, _oos)</CODE>.
  */
 public void run() {
   // first, read from socket the worker-initialization object that will
   // be broadcast for execution to every worker connecting to this server.
   utils.Messenger mger = utils.Messenger.getInstance();
   try {
     mger.msg("PDBTEC2ListenerThread: waiting to read the init_cmd from client", 1);
     RRObject initCmd = (RRObject) _ois.readObject();
     mger.msg("PDBTEC2ListenerThread: done reading the init_cmd from client", 1);
     setInitCmd(initCmd);
     mger.msg("PDBTEC2ListenerThread: done setting the init_cmd", 2);
     // send back to the clt an "ACK" message
     _oos.writeObject(new OKReply());
     _oos.flush();
     mger.msg("PDBTEC2ListenerThread: done sending OKReply through the socket", MIN_PRIORITY);
   } catch (Exception e) { // client closed connection
     // e.printStackTrace();
     try {
       _ois.close();
       _oos.close();
       _s.close();
     } catch (Exception e2) {
       // e2.printStackTrace();
     }
     mger.msg("PDBTEC2ListenerThread: Client Network Connection Closed", 0);
     System.exit(-1);
   }
   while (true) {
     try {
       mger.msg("PDBTEC2ListenerThread.run(): waiting to read an RRObject...", 2);
       // 1. read from socket input
       RRObject obj = (RRObject) _ois.readObject(); // obj is an TaskObjectsExecutionRequest
       mger.msg("PDBTEC2ListenerThread.run(): RRObject read", 2);
       // 2. take appropriate action
       try {
         obj.runProtocol(_srv, _ois, _oos);
       } catch (PDBatchTaskExecutorException e) {
         mger.msg(
             "PDBTEC2ListenerThread.run(): calling obj.runProtocol() "
                 + "issued PDBatchTaskExecutorException, will try one more time.",
             1);
         secondChance(obj);
       } catch (
           IOException e) { // worker somehow failed, give srv one more shot, then notify client
         mger.msg(
             "PDBTEC2ListenerThread.run(): calling obj.runProtocol() "
                 + "issued IOException, will try one more time.",
             1);
         secondChance(obj);
       }
     } catch (Exception e) { // client closed connection
       // e.printStackTrace();
       try {
         _ois.close();
         _oos.close();
         _s.close();
       } catch (Exception e2) {
         // e2.printStackTrace();
       }
       mger.msg(
           "PDBTExecSingleCltWrkInitSrv: Client Network Connection Closed "
               + "(exception '"
               + e
               + "' caught)",
           0);
       System.exit(-1);
     }
   }
 }