tags:

views:

67

answers:

4

I have this piece of code that compiles a class called tspClassName, when I compile using this code:

           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());

it outputs this: "Compile exit status: 2 Compile error:java.io.FileInputStream@17182c1" The class tspClassName.java compiles without errors otherwise, so I am guessing it has to do with the path,and in my eclipse project, the tspClassName.java resides in package homework4.generated inside src, is there something wrong with the path that I use in the code?

thanks

+1  A: 

You can use the javax.tools.JavaCompiler or JCI that wrap this functionality.

Bozho
Thanks, but I am getting a NULL pointer exception here: JavaCompiler compiler = ToolProvider.getSystemJavaCompiler (); DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager (diagnostics, null, null);because compiler is null, how can I resolve this?
Noona
perhaps you don't have a JDK installed?
Bozho
No I have it it installed here:C:\Sun\SDK\jdk
Noona
A: 

I think the proper way to do this kind of work is programatically using the javax.tools API, not an external process:

http://java.sun.com/javase/6/docs/api/javax/tools/ToolProvider.html#getSystemJavaCompiler%28%29

seanizer
+1  A: 

Your Java code runs a command that looks something like this:

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

I don't think that's what you want. I think you need to change your Java code so it maybe generates something like:

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

Note the space after the classpath (".").

Michael Angstadt
thanks, I did that, but using debug now I found out that the program stops here:compileProc.waitFor();what can cause this?
Noona
@Noona: more than likely there's compilation error (try to manually compile the `.java` file to confirm this). You need to drain the `Process`'s stdin and stderr, or else they block.
polygenelubricants
the .java file is in my eclipse project, and it's compiled without errors there.
Noona
the command should be like this (i forgot homework4 earlier, but still, there had to be src twice): "javac -classpath ./src src/homework4/generated/ClassName.java -d ./bin" .replace("/", File.separator) .replace("ClassName", tspClassName);
Noona
Try draining the input and output streams like polygenelubricants suggested in his answer.
Michael Angstadt
A: 

I recommend doing something like this:

    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

... where LOG is whatever your logging framework uses to log the command to be executed. This will help debugging immensely, since it was pointed out that the command you built is ill-constructed.

Alternately you can also build the string using replace

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

This is perhaps more readable.


On draining Process streams

OP's comment suggests that waitFor() never returns. This is likely caused by compilation errors/warnings in javac process.

From the API:

Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock.

You need to continuously drain the Process.getOutputStream() et.al.

See also

  • Java Puzzlers, Puzzle 82: Beer Blast

Related questions

polygenelubricants