ctongfei / progressbar

Terminal-based progress bar for Java / JVM
http://tongfei.me/progressbar/
MIT License
1.07k stars 102 forks source link

Seems to be a bug with early closing the terminal #137

Open bepopov opened 2 years ago

bepopov commented 2 years ago

Hello.

Thank you for your efforts in creating this great lib! It saved a lot of time for me.

Unfortunately, I think I found a bug. I tried to create several progress bars in my Spring Shell application sequentially but I faced with issue in cmd and PowerShell on Windows: after closing the first progress bar the width of each newly created one reduced, moreover, I wasn't able to print messages in terminal. While investigation I dived into progress bar's source code and found that library is closing the terminal when progress is finished.

class ProgressUpdateAction implements Runnable {
    //...
    public void run() {
        if (first) {
            forceRefresh();
            first = false;
        }
        else {
            if (!progress.paused) refresh();
            if (!progress.alive) {
                forceRefresh();
                consumer.close();
                TerminalUtils.closeTerminal();
            }
        }
    }
    //...
}

When it is closed each new creation of progress bar will also create dumb terminal using TerminalUtils.getTerminal(). Therefore the width is changing. And as initial terminal is closed output stream is also becoming to be closed (I assume it closes the System.out too so that is why I couldn't print anything even to there).

I downloaded the source code and removed TerminalUtils.closeTerminal(); line, built library locally and everything worked fine. Not closing the terminal also allows user to use terminal's output stream so user can change color of he's text and print messages to one output stream instead of printing via System.err. I would suggest to remove this line in the library too. Also maybe it would be good to mention in docs that user has to close Terminal by his own

ctongfei commented 2 years ago

Hi @bepopov, thanks for the issue and investigation!

However, I'm not sure why it behaves like you described. TerminalUtils.closeTerminal() does not close the System.out stream: see the source code at https://github.com/ctongfei/progressbar/blob/87600ecdc589b08319d47a9ef013f26205595113/src/main/java/me/tongfei/progressbar/TerminalUtils.java#L41

Creating progress bars sequentially might be a problem if the prior one is not yet closed and another Terminal is created. Can you try adding synchronized to TerminalUtils.getTerminal() method to see if it resolves your problem? https://github.com/ctongfei/progressbar/blob/87600ecdc589b08319d47a9ef013f26205595113/src/main/java/me/tongfei/progressbar/TerminalUtils.java#L77