0

I am executing CSharp Program with java Process by creating the .exe file but the process of that file is not responding with 0 exitCode.Errors are Empty.In Visual Studio it runs fine but with java, it creates problem.No output and no Errors, I am stuck in this Please help. I am using Java 7. I am using Csc (inbuild compiler in .Net framework for windows) It is giving me dll reference error.Command is following

csc /nologo /r:D:/simulatorConfig/ArrayConversion.dll /out:D:\\apache-tomcat-7.0.64\\temp\\tmp749792186557790590.exe D:\\apache-tomcat-7.0.64\\temp\\tmp749792186557790590.cs

stream = new BufferedReader(new InputStreamReader(proc.getErrorStream())); 

above is Error which is empty String.

code is here Please look at it.

public File compile(File sourceFile, LANGUAGE lang) throws InterruptedException, IOException, CompilerException, ConfigurationException {
    String absolutePath = sourceFile.getCanonicalPath();
    // System.out.println("absolutePath : " + absolutePath);
    String destFile;
    if (OsUtils.isWindows()) {
        destFile = absolutePath.replace(lang.getFileExtension(), EXECUTABLE_FILE_SUFFIX);
    } else {
        destFile = absolutePath.replace(lang.getFileExtension(), "");
    }

    String compileCommand = generateCommand(absolutePath, destFile, lang);
    logger.error("compileCommand : " + compileCommand);
    // Compiles and create exe file for execution
    Process proc = Runtime.getRuntime().exec(compileCommand);

    // Wait for process to complete
    int returnValue = proc.waitFor();

    if (returnValue != 0) {
        String errorMsg = getCompilerMessage(sourceFile, proc, lang);
        throw new CompilerException(errorMsg);
    }

    proc.destroy();

    return new File(destFile);
}

private String getCompilerMessage(File sourceFile, Process proc, LANGUAGE lang) throws IOException {

    StringBuilder message = new StringBuilder();
    BufferedReader stream = null;
    String line = null;

    switch (lang) {
    case C:
    case CPP:
        // GNU C/CPP compiler prints compiler errors in standard errors
        // tream
        stream = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
        break;

    case CSHARP:
        // CSharp compiler prints compiler errors in standard output stream
        stream = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
        break;

    }

    while ((line = stream.readLine()) != null) {
        logger.error(line);
        line = line.substring(line.indexOf(sourceFile.getName()) + (int) sourceFile.getName().length());
        if (message.toString().isEmpty()) {
            message.append(lang == LANGUAGE.CSHARP ? "Line" : "").append(line);
        } else {
            message.append("<br/>Line").append(line);
        }
        // message.append(line).append(SystemUtils.LINE_SEPARATOR);
    }

    stream.close();

    return message.toString();
}

private String generateCommand(String sourceFile, String destFile, LANGUAGE lang) throws ConfigurationException {
    // System.out.println("sourceFile : " + sourceFile + " -- destFile : " +
    // destFile);
    Configuration config = new PropertiesConfiguration("system.properties");
    String cmd = "";
    switch (lang) {
    case C:
    case CPP:
        sourceFile = sourceFile.replace("\\", "\\\\");
        destFile = destFile.replace("\\", "\\\\");
        cmd = "g++ " + sourceFile + " -o " + destFile + " " + config.getString("C_CPP_HEADERFILE").trim();
        break;

    case CSHARP:
        sourceFile = sourceFile.replace("\\", "\\\\");
        destFile = destFile.replace("\\", "\\\\");
        logger.error("Config Path : "+config.getString("MONO_PATH"));
        if (OsUtils.isWindows()) {
            cmd = "csc /nologo /r:" + config.getString("CS_HEADERFILE_WIN") + " /out:" + destFile + " " + sourceFile;
        } else {
            cmd = "/opt/mono/bin/mcs /reference:" + config.getString("CS_HEADERFILE") + " /out:" + destFile + " "
                    + sourceFile;
        }

        break;
    }
    logger.info("Command :" + cmd);
    return cmd;
}

2 Answers2

0

When launching a command using Runtime#exec, you MUST consume the error and std streams in every case (not only when the return code is != 0), or else the internal buffers could/will get full and the subprocess will wait indefinitely until somebody consumes them.

The common symptom of this problem is an process that never return, making the whole seems to be deadlocked.

There are several ways to correct this, one the easiest is described here: https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html#redirect-input.

Additionally, there seems to be an issue here:

// CSharp compiler prints compiler errors in standard output stream
    stream = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
    break;

In the comment, you tell the compiler does output errors on stdout, but you are consuming the error stream.

spi
  • 1,673
  • 13
  • 19
  • maybe, it depends on the executable. rule of thumb is: when launching a command with java (Runtime#exec and friends), don't think too much: starts with consumming everything (stdout AND stderr) then analyze the output and start to make assumptions about why you get a particular return code and whether you can ignore it or not. some badly written exe does returns things that does not describe the real state of the execution (I remember time when Maven was returning '0' but had failed to build my project. Very fun in CI environment) – spi Nov 24 '17 at 13:45
0

There was .dll linking error in when I tried to do the same in command prompt with Demo files.By keeping .dll file and .exe file in the same directory it solved my purpose program was running Flawlessly with proper exit code (0). So kept other .dll file in this path D:\apache-tomcat-7.0.64\temp\. and is fine.

The thumb rule says .dll and .exe should be in the same directoryeory