Question

The main problem is that I cannot run my c++ logic by running it through Java; am I creating a subprocess properly?

Thank you all; --- UPDATE! ---

So I have written these to test the ability to open .exe in the purest way; Eclipse can see the file/does not complain that it isn't there; ran using the run button in Eclipse:

The java file:

import java.io.*;

public class Runs_A_Exe {
   public static void main( String[] args ){
      try {
         ProcessBuilder pb = new ProcessBuilder( "M:\\aaa\\bbb\\ccc\\ddd\\eee\\workspace\\Runs Simple Exe\\src\\executables\\a.exe" );
         Process p = pb.start();

         InputStream is = p.getInputStream();
         InputStreamReader isr = new InputStreamReader( is );
         BufferedReader br = new BufferedReader( isr );
         System.out.println( br.readLine() );
      }

      catch ( Exception e ) {
         System.out.println( e );
      }
   }
}

The c++ file:

#include <iostream>

int main( void ) {
   std::cout << "Hey!" << std::endl;
}

The output:

null

Was it helpful?

Solution 2

The process created by ProcessBuilder has standard input, output, and error streams, and if you do not write to its input stream or read from its output streams, it will hang. See the following questions for more information:

Why does process hang if the parent does not consume stdout/stderr in Java?

Java ProcessBuilder: Resultant Process Hangs

It is also possible that the process is never started because either the user it is running as doesn't have the necessary permissions to start it, or because some DLLs cannot be loaded, or possibly for some other reason.

Unable to use taskkill.exe from a Java process

I've created a modified version of your program. When I run it from the command line it is able to execute the exe file, but when I do the same from an Eclipse project, the process returns an exit code of -1073741515, which, according to the question above, means "The application failed to initialize properly." I think you need to investigate the environment in which Eclipse is invoking java to run your exe (what user it runs under, how the PATH is set up, etc.), and whether all dependencies of the exe are available (what DLLs does it depend on) to determine why it isn't running successfully.

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;

public class Runs_An_Exe {
    public static void main(String[] args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("c:/cygwin/tmp/a.exe");
        pb.redirectErrorStream(true); // redirect stderr to stdin
        Process p = pb.start();

        final StringWriter writer = new StringWriter();
        final InputStreamReader isr = new InputStreamReader(p.getInputStream());
        // capture all output from the process
        new Thread(new Runnable() {
            @Override public void run() {
                readAll(isr, writer);
            }
        }).start();
        // wait for it to finish, and display the exit code
        int result = p.waitFor();
        System.out.println("result: " + result);
        // display any output from the process
        System.out.println(writer.toString());
    }

    private static void readAll(Reader reader, Writer writer) {
        try {
            char[] buffer = new char[8192];
            int n = 0;
            while (-1 != (n = reader.read(buffer))) {
                writer.write(buffer, 0, n);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

(The a.exe I used was compiled from your C++ source in the question using g++ 4.8.2 under 32-bit Cygwin.)

OTHER TIPS

Are you calling it with the right arguments? Does the C++ has the right working directory? Is Java parsing the stdout correctly? If you only do an hello world in the C++, can you see it in Java?

I suggest starting back from the beginning, make it work with the simplest possible C++ program and slowly complexify the C++ (putting back in your logic)

  • First call an hello world from java, and ensure the output is read correctly in Java
  • Then add a few arguments and ensure that the output is read correctly in java,
  • Then add a bit of logic, and ensure that the output is read correctly from Java.

And make sure the C++ is alway working correctly with Java. Write automated tests if you can :)


What happened is that you committed the capital sin of not having an end-to-end integrated build of your application from the beginning. The pain you feel is you expiating your crime :P .

I'm kidding of course, but seriously, next time, I would suggest integrating the C++ as soon as you can! Its those integration points that are always a source of problem in any software (I would know). Solving them early is a great way to ensure that you can focus on the logic later on. If I could suggest a reading, check out Growing object oriented software guided by test, it's a great demonstration of this kind of approach.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top