You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@commons.apache.org by Edgar H <ka...@gmail.com> on 2017/12/02 23:33:32 UTC

[exec] Misunderstanding DaemonExecutor and DefaultExecutor for asynchronous execution

Hey guys,

Recently I've been working with exec in order to execute several scripts
via Java.

The thing is that I don't clearly understand how they work as I'm trying to
perform asycnhronous tasks and the process seems to keep on blocking
without continuing the execution, so what I did in the meantime is to
create manual Java Thread classes to perform all of them, which isn't
elegant at all.

For example, I'm trying to run Icecast as a background process, and keep on
executing and instantiating more background ones, but it seems that with my
approach it keeps blocking.

    private void runIcecast() {
        File file = new File("Icecast");
        for (File s : file.listFiles()) {
            if (s.getName().equals("icecast.bat")) {
                DaemonExecutor executor = new DaemonExecutor();
                executor.setWorkingDirectory(file);
                executor.setExitValue(1);
                CommandLine commandLine = new
CommandLine(s.getAbsolutePath());

                try {
                    executor.execute(commandLine);
                    String line = "icecast -c icecast.xml";
                    commandLine = CommandLine.parse(line);
                    executor.execute(commandLine, new
DefaultExecuteResultHandler());
                } catch (ExecuteException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

What should I do so a new Thread is created whenever the command is
executed? Or should I just create normal Thread classes as I've been doing
until now?

Re: [exec] Misunderstanding DaemonExecutor and DefaultExecutor for asynchronous execution

Posted by Edgar H <ka...@gmail.com>.
Thanks for the reply Siegfried, I've checked it out but couldn't solve
anything. Anyhow, I've changed to synchronous and started working with Java
Threads as a temporal workaround. Even thought I'm having another kind of
problem I didn't know it could happen...

The situation is that I have 2 programs, a .jar that spits audio bytes to
the stdout that are then received by FFMPEG. Both commands are executed by
EXEC but it seems that the stream isn't maintained as long as the main
application lives, I've seen that the stream lasts around 30 seconds before
it just blocks. My first theory is that the FFMPEG output stream isn't
being consumed and then blocked because it's full. I've changed the
PumpStreamHandler output by a NullOutputStream and nothing seems to be
changing from the previous implementation that sent a null to the
OutputStream constructor parameter.

            PipedOutputStream output = new PipedOutputStream(); // output
from the .jar that send audio bytes to the stdout
            PipedInputStream input = new PipedInputStream(); // audio bytes
from the .jar are received via here to FFMPEG.
            output.connect(input);

And the PumpStreamHandler used by the FFMPEG process is the following one...

            executor.setStreamHandler(
                    new PumpStreamHandler(
                            new NullOutputStream(),
                            null,
                            input));

The full code for that executor is the following one...

    @Override
    public void run() {
        try {
            DefaultExecutor executor = new DefaultExecutor();

            String feedMe = ffmpegCommand();
            System.out.println(feedMe);
            CommandLine commandLine = CommandLine.parse(feedMe);

            executor.setStreamHandler(
                    new PumpStreamHandler(
                            System.out,
                            null,
                            input));

            executor.execute(commandLine); //, new
DefaultExecuteResultHandler());
        } catch (ExecuteException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Am I missing something to keep it alive?

2017-12-07 22:17 GMT+01:00 Siegfried Goeschl <si...@it20one.com>
:

> Hi Edgar,
>
> had a quick look and I can spot no obvious issue (apart from starting
> batch files which is error prone). Having said that could you check out
>
> * https://issues.apache.org/jira/browse/EXEC-57 <
> https://issues.apache.org/jira/browse/EXEC-57>
> * http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/
> test/java/org/apache/commons/exec/issues/Exec57Test.java?view=markup <
> http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/
> test/java/org/apache/commons/exec/issues/Exec57Test.java?view=markup>
>
> Thanks in advance,
>
> Siegfried Goeschl
>
>
> > On 03.12.2017, at 00:33, Edgar H <ka...@gmail.com> wrote:
> >
> > Hey guys,
> >
> > Recently I've been working with exec in order to execute several scripts
> > via Java.
> >
> > The thing is that I don't clearly understand how they work as I'm trying
> to
> > perform asycnhronous tasks and the process seems to keep on blocking
> > without continuing the execution, so what I did in the meantime is to
> > create manual Java Thread classes to perform all of them, which isn't
> > elegant at all.
> >
> > For example, I'm trying to run Icecast as a background process, and keep
> on
> > executing and instantiating more background ones, but it seems that with
> my
> > approach it keeps blocking.
> >
> >    private void runIcecast() {
> >        File file = new File("Icecast");
> >        for (File s : file.listFiles()) {
> >            if (s.getName().equals("icecast.bat")) {
> >                DaemonExecutor executor = new DaemonExecutor();
> >                executor.setWorkingDirectory(file);
> >                executor.setExitValue(1);
> >                CommandLine commandLine = new
> > CommandLine(s.getAbsolutePath());
> >
> >                try {
> >                    executor.execute(commandLine);
> >                    String line = "icecast -c icecast.xml";
> >                    commandLine = CommandLine.parse(line);
> >                    executor.execute(commandLine, new
> > DefaultExecuteResultHandler());
> >                } catch (ExecuteException e) {
> >                    e.printStackTrace();
> >                } catch (IOException e) {
> >                    e.printStackTrace();
> >                }
> >            }
> >        }
> >    }
> >
> > What should I do so a new Thread is created whenever the command is
> > executed? Or should I just create normal Thread classes as I've been
> doing
> > until now?
>
>

Re: [exec] Misunderstanding DaemonExecutor and DefaultExecutor for asynchronous execution

Posted by Siegfried Goeschl <si...@it20one.com>.
Hi Edgar,

had a quick look and I can spot no obvious issue (apart from starting batch files which is error prone). Having said that could you check out

* https://issues.apache.org/jira/browse/EXEC-57 <https://issues.apache.org/jira/browse/EXEC-57>
* http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java?view=markup <http://svn.apache.org/viewvc/commons/proper/exec/trunk/src/test/java/org/apache/commons/exec/issues/Exec57Test.java?view=markup>

Thanks in advance, 

Siegfried Goeschl


> On 03.12.2017, at 00:33, Edgar H <ka...@gmail.com> wrote:
> 
> Hey guys,
> 
> Recently I've been working with exec in order to execute several scripts
> via Java.
> 
> The thing is that I don't clearly understand how they work as I'm trying to
> perform asycnhronous tasks and the process seems to keep on blocking
> without continuing the execution, so what I did in the meantime is to
> create manual Java Thread classes to perform all of them, which isn't
> elegant at all.
> 
> For example, I'm trying to run Icecast as a background process, and keep on
> executing and instantiating more background ones, but it seems that with my
> approach it keeps blocking.
> 
>    private void runIcecast() {
>        File file = new File("Icecast");
>        for (File s : file.listFiles()) {
>            if (s.getName().equals("icecast.bat")) {
>                DaemonExecutor executor = new DaemonExecutor();
>                executor.setWorkingDirectory(file);
>                executor.setExitValue(1);
>                CommandLine commandLine = new
> CommandLine(s.getAbsolutePath());
> 
>                try {
>                    executor.execute(commandLine);
>                    String line = "icecast -c icecast.xml";
>                    commandLine = CommandLine.parse(line);
>                    executor.execute(commandLine, new
> DefaultExecuteResultHandler());
>                } catch (ExecuteException e) {
>                    e.printStackTrace();
>                } catch (IOException e) {
>                    e.printStackTrace();
>                }
>            }
>        }
>    }
> 
> What should I do so a new Thread is created whenever the command is
> executed? Or should I just create normal Thread classes as I've been doing
> until now?