finally { try { if (service!=null && !service.isClosed()) service.close(); } catch (IOException ioex) {  } }
  void serveStep(Socket service, boolean no_resources)  {    try      {        Serving: while (true)          {            InputStream in = service.getInputStream();            service.setSoTimeout(TOUT_START_READING_MESSAGE);            MessageHeader msh_request = new MessageHeader();            try              {                msh_request.read(in);              }            catch (MARSHAL ex)              {                // This exception may be thrown due closing the connection.                return;              }            if (max_version != null)              {                if (!msh_request.version.until_inclusive(max_version.major,                  max_version.minor))                  {                    OutputStream out = service.getOutputStream();                    new ErrorMessage(max_version).write(out);                    return;                  }              }            byte[] r = msh_request.readMessage(in, service, TOUT_WHILE_READING,              TOUT_AFTER_RECEIVING);            if (msh_request.message_type == MessageHeader.REQUEST)              {                RequestHeader rh_request;                BufferredCdrInput cin = new BufferredCdrInput(r);                cin.setOrb(this);                cin.setVersion(msh_request.version);                cin.setOffset(msh_request.getHeaderSize());                cin.setBigEndian(msh_request.isBigEndian());                rh_request = msh_request.create_request_header();                // Read header and auto set the charset.                rh_request.read(cin);                // in 1.2 and higher, align the current position at                // 8 octet boundary.                if (msh_request.version.since_inclusive(1, 2))                  {                    cin.align(8);                    // find the target object.                  }                InvokeHandler target = (InvokeHandler) find_connected_object(                  rh_request.object_key, -1);                // Prepare the reply header. This must be done in advance,                // as the size must be known for handler to set alignments                // correctly.                ReplyHeader rh_reply = msh_request.create_reply_header();                // TODO log errors about not existing objects and methods.                ResponseHandlerImpl handler = new ResponseHandlerImpl(                  this, msh_request, rh_reply, rh_request);                SystemException sysEx = null;                try                  {                    if (no_resources)                      {                        NO_RESOURCES no = new NO_RESOURCES("Too many parallel calls");                        no.minor = Minor.Threads;                        throw no;                      }                    if (target == null)                      throw new OBJECT_NOT_EXIST();                    target._invoke(rh_request.operation, cin, handler);                  }                catch (gnuForwardRequest forwarded)                  {                    OutputStream sou = service.getOutputStream();                    forward_request(sou, msh_request, rh_request, forwarded);                    if (service != null && !service.isClosed())                      {                        // Wait for the subsequent invocations on the                        // same socket for the TANDEM_REQUEST duration.                        service.setSoTimeout(TANDEM_REQUESTS);                        continue Serving;                      }                  }                catch (UnknownException uex)                  {                    sysEx = new UNKNOWN("Unknown", 2,                      CompletionStatus.COMPLETED_MAYBE);                    sysEx.initCause(uex.originalEx);                    org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply();                    rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext(                      rh_reply.service_context, uex.originalEx, ech);                    ObjectCreator.writeSystemException(ech, sysEx);                  }                catch (SystemException ex)                  {                    sysEx = ex;                                        org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply();                                        rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext(                      rh_reply.service_context, ex, ech);                                        ObjectCreator.writeSystemException(ech, ex);                  }                catch (Exception except)                  {                    // This should never happen under normal operation and                    // can only indicate errors in user object implementation.                    // We inform the user.                    except.printStackTrace();                    sysEx = new UNKNOWN("Unknown", 2,                      CompletionStatus.COMPLETED_MAYBE);                    sysEx.initCause(except);                    org.omg.CORBA.portable.OutputStream ech = handler.createExceptionReply();                    rh_reply.service_context = UnknownExceptionCtxHandler.addExceptionContext(                      rh_reply.service_context, except, ech);                    ObjectCreator.writeSystemException(ech, sysEx);                  }                // Write the response.                if (rh_request.isResponseExpected())                  {                    OutputStream sou = service.getOutputStream();                    respond_to_client(sou, msh_request, rh_request, handler,                      sysEx);                  }              }            else if (msh_request.message_type == MessageHeader.CLOSE_CONNECTION              || msh_request.message_type == MessageHeader.MESSAGE_ERROR)              {                CloseMessage.close(service.getOutputStream());                service.close();                return;              }            if (service != null && !service.isClosed())              // Wait for the subsequent invocations on the              // same socket for the TANDEM_REQUEST duration.              service.setSoTimeout(TANDEM_REQUESTS);            else              return;          }      }    catch (SocketException ex)      {        // OK.        return;      }    catch (IOException ioex)      {        // Network error, probably transient.        // TODO log it.        return;      }  }