如何在java程序中编译和运行

时间:2014-08-02 00:21:26

标签: java

我想用另一个Java程序打开一个Java GUI。它成功编译,但无法运行。它说“无法加载主类”。这是我的代码:

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;


public class Test {

  public static void main(String[] args) {
    try {
        JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
        jc.run(System.in, System.out, System.err, "src/HelloWorld.java");

        // I think this line has the error
        Runtime.getRuntime().exec("cmd.exe /c start java src/HelloWorld");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

HelloWorld类:

import javax.swing.JFrame;
public class HelloWorld {
public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setSize(100, 500);
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

1 个答案:

答案 0 :(得分:3)

您的代码可能会失败的位置有很多,例如,由于某种原因,它可能无法编译; java可能不在操作系统的搜索路径中; java命令可能会失败,因为src/HelloWorld参数看起来不对。

我相信你的命令应该更像java -cp ./src HelloWorld,或者它应该在src目录的上下文中执行...

您确实需要尽一切努力来诊断潜在问题,例如DiagnosticCollector的{​​{1}}和阅读流程JavaCompilerInputStream

根据您的ErrorStreamthis previous answer,我能够生成此示例,该示例可以成功编译并运行您的课程......

HelloWorld.java

作为使用import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.tools.Diagnostic; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class TestCompile { public static void main(String[] args) { StringBuilder sb = new StringBuilder(64); try { DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null)) { // >>>> Compiler Stage // This sets up the class path that the compiler will use. // I've added the .jar file that contains the DoStuff interface within in it... List<String> optionList = new ArrayList<>(); optionList.add("-classpath"); optionList.add(System.getProperty("java.class.path")); Iterable<? extends JavaFileObject> compilationUnit = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(new File("src/HelloWorld.java"))); JavaCompiler.CompilationTask task = compiler.getTask( null, fileManager, diagnostics, optionList, null, compilationUnit); if (task.call()) { // <<<< Compiler Stage // >>>> Run stage... ProcessBuilder pb = new ProcessBuilder("java", "-cp", "./src", "HelloWorld"); pb.redirectError(); Process p = pb.start(); InputStreamConsumer.consume(p.getInputStream()); p.waitFor(); // <<<< Run Stage } else { for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { System.out.format("Error on line %d in %s%n", diagnostic.getLineNumber(), diagnostic.getSource().toUri()); } } } catch (InterruptedException ex) { Logger.getLogger(TestCompile.class.getName()).log(Level.SEVERE, null, ex); } } catch (IOException exp) { exp.printStackTrace(); } } public static class InputStreamConsumer implements Runnable { private InputStream is; public InputStreamConsumer(InputStream is) { this.is = is; } public InputStream getInputStream() { return is; } public static void consume(InputStream is) { InputStreamConsumer consumer = new InputStreamConsumer(is); Thread t = new Thread(consumer); t.start(); } @Override public void run() { InputStream is = getInputStream(); int in = -1; try { while ((in = is.read()) != -1) { System.out.print((char)in); } } catch (IOException exp) { exp.printStackTrace(); } } } } 的替代方案,您实际上可以使用...

ProcessBuilder pb = new ProcessBuilder("java", "-cp", "./src", "HelloWorld");

将在ProcessBuilder pb = new ProcessBuilder("java", "HelloWorld"); pb.directory(new File("src")); pb.redirectError(); Process p = pb.start(); 目录

的上下文中启动java进程