private void runImpl()

in nailgun-server/src/main/java/com/facebook/nailgun/NGSession.java [227:335]


  private void runImpl(NGCommunicator comm, Socket socket) {
    try (InputStream in = new NGInputStream(comm);
        PrintStream out = new PrintStream(new NGOutputStream(comm, NGConstants.CHUNKTYPE_STDOUT));
        PrintStream err =
            new PrintStream(new NGOutputStream(comm, NGConstants.CHUNKTYPE_STDERR)); ) {
      // ThreadLocal streams for System.in/out/err redirection
      if (System.in instanceof ThreadLocalInputStream) {
        ((ThreadLocalInputStream) System.in).init(in);
        ((ThreadLocalPrintStream) System.out).init(out);
        ((ThreadLocalPrintStream) System.err).init(err);
      }

      CommandContext cmdContext = comm.readCommandContext();

      String threadName =
          (socket.getInetAddress() == null ? "" : socket.getInetAddress().getHostAddress() + ": ")
              + cmdContext.getCommand();
      updateThreadName(threadName);

      Class cmdclass;
      try {
        Alias alias = server.getAliasManager().getAlias(cmdContext.getCommand());
        if (alias != null) {
          cmdclass = alias.getAliasedClass();
        } else if (server.allowsNailsByClassName()) {
          cmdclass = Class.forName(cmdContext.getCommand(), true, classLoader);
        } else {
          cmdclass = server.getDefaultNailClass();
        }
      } catch (ClassNotFoundException ex) {
        throw new NGNailNotFoundException("Nail class not found: " + cmdContext.getCommand(), ex);
      }

      Object[] methodArgs = new Object[1];
      Method mainMethod; // will be either main(String[]) or nailMain(NGContext)
      String[] cmdlineArgs =
          cmdContext
              .getCommandArguments()
              .toArray(new String[cmdContext.getCommandArguments().size()]);

      boolean isStaticNail = true; // See: NonStaticNail.java

      Class[] interfaces = cmdclass.getInterfaces();

      for (int i = 0; i < interfaces.length; i++) {
        if (interfaces[i].equals(NonStaticNail.class)) {
          isStaticNail = false;
          break;
        }
      }

      if (!isStaticNail) {
        mainMethod = cmdclass.getMethod("nailMain", new Class[] {String[].class});
        methodArgs[0] = cmdlineArgs;
      } else {
        try {
          mainMethod = cmdclass.getMethod("nailMain", nailMainSignature);
          NGContext context = new NGContext();
          context.setArgs(cmdlineArgs);
          context.in = in;
          context.out = out;
          context.err = err;
          context.setCommand(cmdContext.getCommand());
          context.setNGServer(server);
          context.setCommunicator(comm);
          context.setEnv(cmdContext.getEnvironmentVariables());
          context.setInetAddress(socket.getInetAddress());
          context.setPort(socket.getPort());
          context.setWorkingDirectory(cmdContext.getWorkingDirectory());
          methodArgs[0] = context;
        } catch (NoSuchMethodException toDiscard) {
          // nailMain is not found, let's try main(String[])
          try {
            mainMethod = cmdclass.getMethod("main", mainSignature);
            methodArgs[0] = cmdlineArgs;
          } catch (NoSuchMethodException ex) {
            // failed to find 'main' too, so give up and throw
            throw new NGNailNotFoundException(
                "Can't find nailMain or main functions in " + cmdclass.getName(), ex);
          }
        }
      }

      server.nailStarted(cmdclass);

      try {
        mainMethod.invoke(isStaticNail ? null : cmdclass.newInstance(), methodArgs);
      } catch (InvocationTargetException ite) {
        throw ite.getCause();
      } finally {
        server.nailFinished(cmdclass);
      }

      // send exit code 0 to the client; if nail previously called NGSession.exit() or
      // System.exit() explicitly then this will do nothing
      comm.exit(NGConstants.EXIT_SUCCESS);

    } catch (NGExitException exitEx) {
      // We got here if nail called System.exit(). Just quit with provided exit code.
      LOG.log(Level.INFO, "Nail cleanly exited with status {0}", exitEx.getStatus());
      comm.exit(exitEx.getStatus());
    } catch (NGNailNotFoundException notFoundEx) {
      LOG.log(Level.WARNING, "Nail not found", notFoundEx);
      comm.exit(NGConstants.EXIT_NOSUCHCOMMAND);
    } catch (Throwable t) {
      LOG.log(Level.WARNING, "Nail raised unhandled exception", t);
      comm.exit(NGConstants.EXIT_EXCEPTION); // remote exception constant
    }
  }