[External] : Re: My experience using Java to do CLI Scripting
Ron Pressler
ron.pressler at oracle.com
Tue Apr 15 12:30:47 UTC 2025
> On 15 Apr 2025, at 10:51, forax at univ-mlv.fr wrote:
>
> ----- Original Message -----
>> From: "Stuart Marks" <stuart.marks at oracle.com>
>> To: "Remi Forax" <forax at univ-mlv.fr>, "Ron Pressler" <ron.pressler at oracle.com>, "David Alayachew"
>> <davidalayachew at gmail.com>
>> Cc: "cay horstmann" <cay.horstmann at gmail.com>, "core-libs-dev" <core-libs-dev at openjdk.org>
>> Sent: Tuesday, April 15, 2025 12:10:54 AM
>> Subject: Re: My experience using Java to do CLI Scripting
>>
>> A few points here...
>>
>> It might be possible to get away without any Process-related cleanup. For one,
>> there's no "close" method on Process or ProcessBuilder. The destroy() method
>> will
>> certainly clean up, but you don't want that; and waitFor() merely waits for
>> termination but doesn't actually clean anything up.
>>
>> At least in the Unix ProcessImpl class, there's a bunch of infrastructure to
>> handle
>> exit of the underlying process, drain input from its stdout/stderr, and close
>> the
>> pipes. (I didn't look on Windows.) So setting aside termination, IOException,
>> and
>> what to do with stderr, it seems possible to just get the inputReader() and do
>> something with the characters it emits.
>
> You mean by making the Process Closeable ?
It could make sense to make Process AutoCloseable similar to how ExecutorService now works, i.e. by having the close method call waitFor.
>
>>
>> Getting a stream of lines with lines() seems like a reasonable thing to do if
>> you
>> want to process the output line by line.
>
> with the caveat that you have to close() the returned stream (like Files.lines()), something people will often forget.
>
The three Process streams are created (by default) whether you ever use them or not, so if you did have to close them, you’d need to do it every time you use Process. The reason is that the IO scaffolding (including ensuring cleanup) needs to be set up as soon as the process is started, before we know if you’re interested in reading the output. I think that if you want the streams to *not* be opened, you need to ask ProcessBuilder explicitly with ProcessBuilder.Redirect.DISCARD.
It seems to me that on Unix, the pipes are all closed as soon as the process terminates. On Windows it’s more complicated and there may be Cleaners involved (and the buffering done by the OS rather than Java?), but on either platform it seems that it doesn’t matter whether you actually use the streams.
Perhaps Roger can clarify, or correct me if I’m wrong.
>
>>
>> There are other possibilities, taking a nod from Files, which has methods
>> readAllLines() and readString(). Putting similar methods on some class in the
>> Reader
>> family might help considerably here. Or you could call Reader.transferTo(Writer)
>> that will send the characters to any Writer that might have a useful
>> destination.
>
> +1 for readAllInputLines() and readInputString() on Process.
Wouldn’t it make more sense to add these to BufferedReader?
— Ron
More information about the core-libs-dev
mailing list