使用进程使用Java代码编译类

时间:2010-05-18 15:35:10

标签: java compiler-construction

当我使用这段代码编译时,我有这段代码编译一个名为tspClassName的类:

           Process compileProc = null;
        try {
            compileProc = Runtime.getRuntime().exec("javac -classpath ."
                       + File.separator + "src" + File.separator
                       + File.separator + "generated." + tspClassName + ".java -d ." + File.separator + "bin");
        // catch exception
           if (compileProc.exitValue() != 0) 
           {
               System.out.println("Compile exit status: "
                          + compileProc.exitValue());
                      System.err.println("Compile error:" +
                              compileProc.getErrorStream());

它输出: “编译退出状态:2 编译错误:java.io.FileInputStream@17182c1“ tspClassName.java类没有错误编译,所以我猜测它与路径有关,而在我的eclipse项目中,tspClassName.java驻留在src里面的homework4.generated包中,我的路径有问题吗在代码中使用?

感谢

6 个答案:

答案 0 :(得分:1)

您可以使用包含此功能的javax.tools.JavaCompilerJCI

答案 1 :(得分:1)

您的Java代码运行的命令如下所示:

javac -classpath ./src//generated.ClassName.java -d ./bin

我认为这不是你想要的。我认为您需要更改Java代码,以便生成类似的内容:

javac -classpath . src/generated/ClassName.java -d ./bin
                  ^

注意类路径后面的空格(“。”)。

答案 2 :(得分:0)

我认为执行此类工作的正确方法是以编程方式使用javax.tools API,而非外部流程:

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler()

<强>参考:

答案 3 :(得分:0)

我建议做这样的事情:

    String command = String.format(
        "javac -classpath . src%1$sgenerated%1$s%2$s.java -d .%1$sbin",
        File.separator,
        tspClassName
    );
    LOG("Executing " + command);
    //... exec(command) etc

...其中LOG是您的日志记录框架用于记录要执行的命令的任何内容。这将有助于调试,因为有人指出你构建的命令构造不良。

或者,您也可以使用replace

构建字符串
    String command =
        "javac -classpath . src/generated/ClassName.java -d ./bin"
        .replace("/", File.separator)
        .replace("ClassName", tspClassName);

这可能更具可读性。


关于耗尽Process

OP的评论表明waitFor()永远不会回来。这可能是由javac进程中的编译错误/警告引起的。

来自the API

  

由于某些本机平台仅为标准输入和输出流提供有限的缓冲区大小,因此无法及时写入输入流或读取子进程的输出流可能导致子进程阻塞,甚至死锁。

您需要不断消耗Process.getOutputStream() et.al。

另见

  • Java Puzzlers,Puzzle 82:Beer Blast

相关问题

答案 4 :(得分:0)

问题可能出在文件位置,而不是使用exec()的单值参数 尝试3参数方法,其中包含命令,环境和位置作为参数,帮助我们移动到指定位置并执行命令

检查6和8方法以供参考 http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

 Process compile = Runtime.getRuntime().exec("javac "+fname,null,new File(dir));

答案 5 :(得分:0)

首先,如果要使用这样的进程,应该使用apache exec库。 Apache exec库使事情变得非常简单。

其次,您应该打印正在执行的进程的std输出和std错误流。如果没有他们,就无法知道什么是被执行以及它在做什么。

第三,尝试打印进程正在执行的完整cmd行。复制该cmd行并尝试手动运行它。大多数情况下,您会以这种方式找到问题。

最后,如果你的目标只是在运行时编译一个类/生成或修改一个类文件,请给this一个好的读取和尝试。它也有例子。您还可以尝试代码生成/类操作库,如BCEL,JavaAssist等。

祝你好运。