Question

I'm fairly new to ProcessBuilder and working with threads. In it's current state I have a J-Button which starts a scheduled executor service. The scheduled executor service is used to delegate a process to one of two process builders. The application is meant to record a user conversation. During the conversation, after x minutes it creates a wav and delegates it to an available process for transcription. The problem begins when the transcription class is called. The process is started and the application runs as expected. However, the transcription process doesn't actually do anything until I exit the parent application. Only then it will begin. Checking the task manager it shows as a process but uses 0.0% of the CPU and around 238MB of memory until I exit then the two processes jump to 30%-40% and 500-1000 MB of memory. Also, I am using the .waitFor() but am using a thread to run the .waitFor() process as from what I gather it causes the application to hang. How would I go about fixing this. Sorry I am unable to provide more details but I'm new to this. Thanks in advance!

public class TranDelegator {
    Future<?> futureTranOne = null;
    Future<?> futureTranTwo = null;
    ExecutorService transcriberOne = Executors.newFixedThreadPool(1);
    ExecutorService transcriberTwo = Executors.newFixedThreadPool(1);

    final Runnable transcribeChecker = new Runnable() {
        public void run() {
            String currentWav = null;
            File inputFile = new File("C:\\convoLists/unTranscribed.txt");

            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new FileReader(inputFile));
            } catch (FileNotFoundException e1) {
                System.out.println("reader didn't initialize");
                e1.printStackTrace();
            }
            try {
                currentWav = reader.readLine();
            } catch (IOException e) {
                System.out.println("currentWav string issue");
                e.printStackTrace();
            }
            try {
                reader.close();
            } catch (IOException e) {
                System.out.println("reader couldn't close");
                e.printStackTrace();
            }

            if(currentWav != null){
                if (futureTranOne == null || futureTranOne.isDone()) {
                    futureTranOne = transcriberOne.submit((transcriptorOne));
                }

                else if (futureTranTwo == null || futureTranTwo.isDone()) {                     
                    futureTranTwo = transcriberTwo.submit((transcriptorTwo));               
                }
            }
        }
    };

    final Runnable transcriptorOne = new Runnable() {
        public void run() {
            System.out.println("ONE");
            try {
                String classpath = System.getProperty("java.class.path");
                String path = "C:/Program Files/Java/jre7/bin/java.exe";
                ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp",
                        classpath, Transcriber.class.getName());
                Process process = processBuilder.start();
                try {
                    process.waitFor();
                } catch (InterruptedException e) {
                    System.out.println("process.waitFor call failed");
                    e.printStackTrace();
                }
            } catch (IOException e) {
                System.out.println("Unable to call transcribeConvo");
                e.printStackTrace();
            }

        }
    };
    final Runnable transcriptorTwo = new Runnable() {
        public void run() {
            System.out.println("TWO");
            try {
                String classpath = System.getProperty("java.class.path");
                String path = "C:/Program Files/Java/jre7/bin/java.exe";
                ProcessBuilder processBuilder = new ProcessBuilder(path, "-cp",
                        classpath, Transcriber.class.getName());
                Process process = processBuilder.start();
                try {
                    process.waitFor();
                } catch (InterruptedException e) {
                    System.out.println("process.waitFor call failed");
                    e.printStackTrace();
                }
            } catch (IOException e) {
                System.out.println("Unable to call transcribeConvo");
                e.printStackTrace();
            }
        }
    };

}


public class Transcriber {
    public static void main(String[] args) throws IOException,
            UnsupportedAudioFileException {
        retreiveEmpInfo();
        TextoArray saveConvo = new TextoArray();
        ArrayList<String> entireConvo = new ArrayList();
        URL audioURL;
        String currentWav = wavFinder();
        ConfigReader configuration = new ConfigReader();
        ArrayList<String> serverInfo = configuration
                .readFromDoc("serverconfig");

        while (currentWav != null) {
            audioURL = new URL("file:///" + currentWav);
            URL configURL = Transcriber.class.getResource("config.xml");
            ConfigurationManager cm = new ConfigurationManager(configURL);
            Recognizer recognizer = (Recognizer) cm.lookup("recognizer");
            recognizer.allocate(); // allocate the resource necessary for the
                                    // recognizer
            System.out.println(configURL);

            // configure the audio input for the recognizer
            AudioFileDataSource dataSource = (AudioFileDataSource) cm
                    .lookup("audioFileDataSource");
            dataSource.setAudioFile(audioURL, null);

            // Loop until last utterance in the audio file has been decoded, in
            // which case the recognizer will return null.
            Result result;
            while ((result = recognizer.recognize()) != null) {

                String resultText = result.getBestResultNoFiller();
                // System.out.println(result.toString());
                Collections.addAll(entireConvo, resultText.split(" "));
            }
            new File(currentWav).delete();
            saveConvo.Indexbuilder(serverInfo, entireConvo);
            entireConvo.clear();
            currentWav = wavFinder();
        }
        System.exit(0);
    }

    private static String wavFinder() throws IOException {
        String currentWav = null;
        int x = 1;
        File inputFile = new File("C:\\convoLists/unTranscribed.txt");
        File tempFile = new File("C:\\convoLists/unTranscribedtemp.txt");

        BufferedReader reader = new BufferedReader(new FileReader(inputFile));
        BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile));
        String currentLine = null;
        String newLine = System.getProperty("line.separator");

        while ((currentLine = reader.readLine()) != null) {
            if (x == 1) {
                currentWav = currentLine;
            } else {
                writer.write(currentLine);
                writer.write(newLine);
            }
            x = 2;
        }
        reader.close();
        writer.flush();
        writer.close();
        inputFile.delete();
        // boolean successful =
        tempFile.renameTo(inputFile);
        // System.out.println("Success: " + successful);
        // System.out.println("currentWav = " + currentWav);
        return currentWav;
    }

    private static void retreiveEmpInfo() throws IOException {
        File tempFile = new File("C:\\convoLists/tmp.txt");

        BufferedReader reader = new BufferedReader(new FileReader(tempFile));
        CurrentEmployeeInfo.setName(reader.readLine());
        CurrentEmployeeInfo.setUserEmail(reader.readLine());
        CurrentEmployeeInfo.setManagerEmail(reader.readLine());
        reader.close();
    }
}
Was it helpful?

Solution 2

(from comments)

Looks like process hang is due to out/error streams becoming full. You need to consume these streams; possibly via a thread.

Java7 provides another way to redirect output.

Related : http://alvinalexander.com/java/java-exec-processbuilder-process-3

OTHER TIPS

This problem may be related to sub-process's input stream buffers.

You should clear the sub-process's input stream buffers.

These stream buffers got increased within the parent process's memory with time and at some moment your sub-process will stop responding.

There are few options to make sub-process work normally

  1. Read continuously from sub-process's input streams
  2. Redirect sub-process's input streams
  3. Close sub-process's input streams

Closing sub-process's input streams

ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
InputStream inStream = process.getInputStream();
InputStream errStream = process.getErrorStream();
try {
    inStream.close();
    errStream.close();
} catch (IOException e1) {
}
process.waitFor();

Reading sub-process's input streams

    ProcessBuilder processBuilder = new ProcessBuilder(command);
    Process process = processBuilder.start();
    InputStreamReader tempReader = new InputStreamReader(new BufferedInputStream(p.getInputStream()));
    final BufferedReader reader = new BufferedReader(tempReader);
    InputStreamReader tempErrReader = new InputStreamReader(new BufferedInputStream(p.getErrorStream()));
    final BufferedReader errReader = new BufferedReader(tempErrReader);

    try {
        while ((line = reader.readLine()) != null) {
        }
    } catch (IOException e) {
    }

    try {
        while ((line = errReader.readLine()) != null) {
        }
    } catch (IOException e) {
    }
    process.waitFor();

Redirecting sub-process's input streams

ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.redirectInput();
processBuilder.redirectError();
Process process = processBuilder.start();
process.waitFor();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top