Program Locking in While

Asked

Viewed 599 times

5

I’m working on a project and I’m having problems with the same, this program I’m posting is similar to what I’m working on.

The problem is this: it arrives in while, the program does its function, then hangs and does not come out.

I’ve tried everything. Could someone give some suggestion?

public class CommandZ {

private static String Command;
private static Scanner scan;


public static void main(String[] args) {        
    scan = new Scanner(System.in);


        System.out.println("Shell: ");
        Command = scan.nextLine();

        ProcessBuilder pb = new ProcessBuilder("powershell.exe", "-Command", Command);
        Process p;
        try {
            p = pb.start();
        } catch (IOException e) {
            System.out.println("Failed to start powershell");
            return;
        }


        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
        String line;
        System.out.println("Begin!");
        try {
            //PROBLEMA AQUI
            while((line = bufferedReader.readLine()) != null){
                System.out.println(line);
                //Imprimi as linhas, e não da sequência no programa..




            }
        } catch (IOException e) {
            System.out.println("Failed to read line");
            return;
        }

        System.out.println("Exit");


    }
  • Have you tried to isolate the problem? probably this InputStreamReader is that it’s hanging. I think you can’t read it the way you’re trying. Or maybe you need to finish this process to finish the stream. I’ve never done anything like this. Was this your idea? Have you read somewhere that you can do this? Any additional information can help.

  • I’m trying to make like a framework to interact with the windows prompt, but I have this problem, and I can’t follow the program.. tried a bufferedReader.close after while.. didn’t work..

  • I have doubts whether what you are trying to do is possible, at least in this way. It is obvious that one is hanging in the while any attempt to do something after it, will not be carried out. And I doubt that try to close the stream within the while is also the solution. Even if it seems to work it smells really bad.

  • close the stream inside while, it will read only the first line, and the rest is gone.. will be that there is no other way then to do this ?

  • I tried, give a close after the while, he didn’t even get there...

  • It’s bone.. Nothing helps... a gringo said I needed another thread to read the output and then add it at the end of the main method()

  • You may have another solution, but you need to have in-depth knowledge of all Apis that interact with processes and streams, maybe have a notification system when there is something new in the stream and respond to this signaling instead of staying in loop. I think your problem is lower, I hope someone can give some idea to do different but I don’t think the problem is just the while. And thread alone will not solve anything, has to see how to use in a correct way (if it will help).

  • I don’t use windows, I try Virtualmachine, but I did a test on another computer with windows 7 and the problem was the same...

  • He reads everything, all the way out of the prompt.. but at the end, he stops the program

  • tried the suggestions, the problem remains.. P

  • Well, let’s wait to see if someone with more experience in Java appears with a path (Sunday things slow down...).

  • Thanks for your help!

Show 7 more comments

4 answers

3

This code can solve your problem.

The source is this chatting, specifically at the end of the conversation.

Code:

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.io.PrintWriter;


public class Gobbler implements Runnable {

    private PrintStream out;
    private String message;

    private BufferedReader reader;

    public Gobbler(InputStream inputStream, PrintStream out) {
        this.reader = new BufferedReader(new InputStreamReader(inputStream));
               this.out = out;
        this.message = ( null != message ) ? message : "";
    }

    public void run() {
        String line;

        try {
            while (null != (line = this.reader.readLine())) {
                out.println(message + line);
            }
            this.reader.close();
        } catch (IOException e) {
            System.err.println("ERROR: " + e.getMessage());
        }
    }
}


class PowerConsole {

    private ProcessBuilder pb;
    Process p;
    boolean closed = false;
    PrintWriter writer;

    PowerConsole(String[] commandList) {
        pb = new ProcessBuilder(commandList);
        try {
            p = pb.start();
        } catch (IOException ex) {
            throw new RuntimeException("Cannot execute PowerShell.exe", ex);
        }
        writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(p.getOutputStream())), true);
        Gobbler outGobbler = new Gobbler(p.getInputStream(), System.out);
        Gobbler errGobbler = new Gobbler(p.getErrorStream(), System.out);
        Thread outThread = new Thread(outGobbler);
        Thread errThread = new Thread(errGobbler);
        outThread.start();
        errThread.start();
    }

    public void execute(String command) {
        if (!closed) {
            writer.println(command);
            writer.flush();
        } else {
            throw new IllegalStateException("Power console has ben closed.");
        }
    }

    public void close() {
        try {
            execute("exit");
            p.waitFor();
        } catch (InterruptedException ex) {
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        PowerConsole pc = new PowerConsole(new String[]{"powershell.exe", "-NoExit", "-Command", "-"});
        System.out.println("========== Executing dir");
        pc.execute("dir"); 
//        System.out.println("========== Executing cd\\");
//        pc.execute("cd \\"); Thread.sleep(2000);
//        System.out.println("========== Executing dir");
//        pc.execute("dir"); Thread.sleep(2000);
//        System.out.println("========== Executing cd \\temp");
//        pc.execute("cd \\temp"); Thread.sleep(2000);
//        System.out.println("========== Executing dir");
//        pc.execute("dir"); Thread.sleep(2000);
//        System.out.println("========== Executing cd \\bubba");
//        pc.execute("cd \\bubba"); Thread.sleep(2000);
        System.out.println("========== Exiting .... bye.");
        pc.close();
    }
}

1

I found a solution in stackoverflow.with:

ProcessBuilder proc = new ProcessBuilder().inheritIO().command(
                "powershell.exe", "-Command", Command);
        proc.redirectErrorStream(true);
        Process p = proc.start();
        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(p.getInputStream()));
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
  • 2

    You can post your solution smoothly, but the part you ask a new question is not appropriate. The ideal would be you create a new question and if it is necessary to link this one for greater understanding.

  • I’m removing the new question from here, OK? If you want to post a new one separately. The content I removed is available on editing history.

  • All right! I already asked a new question.

1

Guess your problem is because the "powershell.exe" is waiting for command in Runtime. And because of that the while "hangs" on execution. Because Process is waiting for new data to be read.

I found this link who talks about it.

I also ran some tests running on Windows. Calling cmd.exe and passing the commands, the same hangs on while. Because I imagine he’s waiting for new commands to keep returning in the Inputstreamreader. But when I run only one command like ipconfig. It usually finishes the program.

Well I hope I helped ^^

-2

Your mistake has to do with logic. You did not guarantee that the variable line reach the value null therefore the while repeats indefinitely. You should do this at the end of the while, I added before the comment:

...
while((line = bufferedReader.readLine()) != null){
    System.out.println(line);
    line = null;
 //Imprimi as linhas, e não da sequência no programa..
...
  • 1

    That’s roughly equivalent to putting one break without condition there. I don’t think that’s what the OP wants. Otherwise, I didn’t even need to while.

  • This way only one interaction will be executed. It would be good to put the block closure of the cycle while to understand better @Heidymiguel.

  • @Heydy Miguel You’re just forgetting that if you put a line = null inside the while, the code does not run anymore, pq it prints line by line of the prompt command, on the user’s screen then each line is a new output, putting this null it will print only one line pulled?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.