title: Compile and run a Java program from another Java program
body: <p>I am writing a program that takes the path to the input ".java" file with a main method. The program should then compile that file, and run it.</p>
  
  <p>Let's say that the program I am trying to compile and run looks like this:</p>
  
  <p><strong>Main.java</strong></p>
  
  <pre><code>public class Main {
  
      public static void main(String[] args) {
          System.out.println("Hello, world!");
      }
  }
  </code></pre>
  
  <p>The program that performs compilation and tries to run it:</p>
  
  <p><strong>Evaluator.java</strong></p>
  
  <pre><code>    /**
       * Matches any .java file.
       */
      private static final PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.java");
  
      private static String path;
  
      /**
       * Program entry point. Obtains the path to the .java file as a command line argument.
       * 
       * @param args One argument from the command line: path to the .java file.
       * @throws Exception 
       */
      public static void main(String[] args) throws Exception {
          if (args.length != 1) {
              throw new IllegalArgumentException(
                      "Expected exactly one argument from the command line.");
          }
  
          if (!matcher.matches(Paths.get(args[0]))) {
              throw new IllegalArgumentException(
                      String.format("File %s is not a valid java file.", args[0]));
          }
  
          // path is in a valid format
          path = args[0];
  
          // compile a program
          compile();
  
          // run a program
          run();
      }
  
      /**
       * Compiles a program.
       * 
       * @throws Exception
       */
      private static void compile() throws Exception {
          System.out.println("Compiling the program ...");
  
          Process p = Runtime.getRuntime().exec("javac " + path);
          output("Std.In", p.getInputStream());
          output("Std.Out", p.getErrorStream());
          p.waitFor();
  
          System.out.println("Program successfully compiled!\n");
      }
  
      /**
       * Runs a program.
       * 
       * @throws Exception
       */
      private static void run() throws Exception {
          System.out.println("Executing the program ...");
  
          Process p = Runtime.getRuntime().exec("java " + getProgramName(path));
          output("Std.In", p.getInputStream());
          output("Std.Out", p.getErrorStream());
          p.waitFor();
  
          System.out.println("Program finished!");
      }
  
      private static void output(String stream, InputStream in) throws IOException {      
          BufferedReader reader = new BufferedReader(new InputStreamReader(in, CS));
  
          for (String line = reader.readLine(); line != null; line = reader.readLine()) {
              System.out.println(String.format("%s: %s", stream, line));
          }
      }
  
      private static String getProgramName(String path) {
          return path.replace(".java", "");
      }
  }
  </code></pre>
  
  <p>My "Main.java" file is located in the project root. I am running the program with a command line argument "./Main.java". Doing so, compiles the program correctly and yields a new file "Main.class". However, the <code>run</code> method outputs as follows:</p>
  
  <p><strong>Std.Out: Error: Could not find or load main class ..Main</strong></p>
  
  <p>What should be the problem here?</p>