apache commons exec
DESCRIPTION
Apache Commons Exec. Reliably Executing External Processes. Siegfried Goeschl. History. Code originated from Apache Ant Started 2005 by Niclas Gustavsson Dormant in the Commons Sandbox Resurrected in 2008 In 2009 release of version 1.0 Version 1.1 just hit the road. Common Use Cases. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/1.jpg)
Apache Apache Commons ExecCommons Exec
Reliably Executing Reliably Executing
External ProcessesExternal Processes
Siegfried Goeschl
![Page 2: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/2.jpg)
History
• Code originated from Apache Ant
• Started 2005 by Niclas Gustavsson
• Dormant in the Commons Sandbox
• Resurrected in 2008
• In 2009 release of version 1.0
• Version 1.1 just hit the road
2Apache Commons Exec
![Page 3: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/3.jpg)
Common Use Cases
• ImageMagick to convert images
• Foxit Reader for printing PDFs
• WinSCP for secure file transfer
3Apache Commons Exec
![Page 4: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/4.jpg)
Why To Use Commons Exec
“How to bring down an Application
Server?!”
“How to bring down an Application
Server?!”
Launch an external process!
4Apache Commons Exec
![Page 5: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/5.jpg)
The Problems Ahead
• JDK provides only low-level API– ProcessBuilder & Runtime– Difficult to use– Error prone
• When you mess up– Synchronization Issues– Resource Depletion
5Apache Commons Exec
![Page 6: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/6.jpg)
Synchronization Issues
• Process.waitFor can wait forever– Launched process may never terminate
• Process output must be promptly consumed to avoid deadlock– Writes into a fixed-size buffer
• Process.waitFor does not clear thread interrupt flag when it throws InterruptedException
6Apache Commons Exec
![Page 7: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/7.jpg)
Resource Depletion Ahead
• Process resources are not automatically freed until finalization– Leaves stdin, stdout, stderr open
• Process.destroy() might not work– OpenVMS
• Process.destroy() doesn’t kill process grandchildren depending on OS– Affects all Windows platforms
7Apache Commons Exec
![Page 8: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/8.jpg)
What is the one thing you What is the one thing you want your audience to want your audience to
remember?!remember?!8Apache Commons Exec
![Page 9: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/9.jpg)
9Apache Commons Exec
![Page 10: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/10.jpg)
How I Became Contributor
“Siegfried, can we actually print a PDF invoice?!”
“Siegfried, can we actually print a PDF invoice?!”
Sure!
10Apache Commons Exec
![Page 11: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/11.jpg)
The First Print Job
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();CommandLine commandLine = CommandLine.parse(line);DefaultExecutor executor = new DefaultExecutor();int exitValue = executor.execute(commandLine);
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();CommandLine commandLine = CommandLine.parse(line);DefaultExecutor executor = new DefaultExecutor();int exitValue = executor.execute(commandLine);
Blows up because the exit code ‘1’ is always returned!Blows up because the exit
code ‘1’ is always returned!
11Apache Commons Exec
![Page 12: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/12.jpg)
Handling the Exit Value
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();CommandLine commandLine = CommandLine.parse(line);DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);int exitValue = executor.execute(commandLine);
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();CommandLine commandLine = CommandLine.parse(line);DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);int exitValue = executor.execute(commandLine);
Got stuck when printerwas out of paper!
Got stuck when printerwas out of paper!
12Apache Commons Exec
![Page 13: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/13.jpg)
Tame the Runaway Process
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();CommandLine commandLine = CommandLine.parse(line);DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);ExecuteWatchdog watchdog = new ExecuteWatchdog(60000);executor.setWatchdog(watchdog);int exitValue = executor.execute(commandLine);
String line = "AcroRd32.exe /p /h " + file.getAbsolutePath();CommandLine commandLine = CommandLine.parse(line);DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);ExecuteWatchdog watchdog = new ExecuteWatchdog(60000);executor.setWatchdog(watchdog);int exitValue = executor.execute(commandLine);
Failed miserably when printing 'C:\\Document And Settings\\documents\\
432432.pdf'
Failed miserably when printing 'C:\\Document And Settings\\documents\\
432432.pdf'
13Apache Commons Exec
![Page 14: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/14.jpg)
Quoting Is Your Friend
String fileName = file.getAbsolutePath();String line = "AcroRd32.exe /p /h \"“ + fileName + "\"";CommandLine commandLine = CommandLine.parse(line);DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);ExecuteWatchdog watchdog = new ExecuteWatchdog(60000);executor.setWatchdog(watchdog);int exitValue = executor.execute(commandLine);
String fileName = file.getAbsolutePath();String line = "AcroRd32.exe /p /h \"“ + fileName + "\"";CommandLine commandLine = CommandLine.parse(line);DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);ExecuteWatchdog watchdog = new ExecuteWatchdog(60000);executor.setWatchdog(watchdog);int exitValue = executor.execute(commandLine);
Building the command line sucks!
Building the command line sucks!
14Apache Commons Exec
![Page 15: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/15.jpg)
Incremental Command Line CommandLine cmdLine = new CommandLine("AcroRd32.exe");cmdLine.addArgument("/p");cmdLine.addArgument("/h");cmdLine.addArgument("${file}");Map map = new HashMap();map.put("file", new File(„invoice.pdf"));cmdLine.setSubstitutionMap(map);DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);ExecuteWatchdog watchdog = new ExecuteWatchdog(60000);executor.setWatchdog(watchdog);int exitValue = executor.execute(cmdLine);
CommandLine cmdLine = new CommandLine("AcroRd32.exe");cmdLine.addArgument("/p");cmdLine.addArgument("/h");cmdLine.addArgument("${file}");Map map = new HashMap();map.put("file", new File(„invoice.pdf"));cmdLine.setSubstitutionMap(map);DefaultExecutor executor = new DefaultExecutor();executor.setExitValue(1);ExecuteWatchdog watchdog = new ExecuteWatchdog(60000);executor.setWatchdog(watchdog);int exitValue = executor.execute(cmdLine);
Would be nice to printin the background!
Would be nice to printin the background!
15Apache Commons Exec
![Page 16: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/16.jpg)
CommandLine cmdLine = new CommandLine("AcroRd32.exe");cmdLine.addArgument("/p");cmdLine.addArgument("/h");cmdLine.addArgument("${file}");Map map = new HashMap();map.put("file", new File("invoice.pdf"));commandLine.setSubstitutionMap(map);
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);Executor executor = new DefaultExecutor();executor.setExitValue(1);executor.setWatchdog(watchdog);executor.execute(cmdLine, resultHandler);
// some time later ...int exitValue = resultHandler.waitFor();
CommandLine cmdLine = new CommandLine("AcroRd32.exe");cmdLine.addArgument("/p");cmdLine.addArgument("/h");cmdLine.addArgument("${file}");Map map = new HashMap();map.put("file", new File("invoice.pdf"));commandLine.setSubstitutionMap(map);
DefaultExecuteResultHandler resultHandler = new DefaultExecuteResultHandler();
ExecuteWatchdog watchdog = new ExecuteWatchdog(60*1000);Executor executor = new DefaultExecutor();executor.setExitValue(1);executor.setWatchdog(watchdog);executor.execute(cmdLine, resultHandler);
// some time later ...int exitValue = resultHandler.waitFor();
16Apache Commons Exec
![Page 17: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/17.jpg)
Tips and Tricks (1)
• Creating complex command line– CommandLine.parse() is fragile when
mixing single & double quotes– Build the command line incrementally– You can control quoting per argument– Use “printargs” script for debugging
17Apache Commons Exec
![Page 18: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/18.jpg)
Tips and Tricks (2)
• Redirecting streams– Redirection is implemented by the shell
• Killing a process– Killing a process works (mostly)– Its child processes might not be killed at
all depending on your OS (Windows)– If in doubt avoid convenience scripts to
start a process
18Apache Commons Exec
![Page 19: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/19.jpg)
Conclusion
• Using plain Java API is error prone– Deadlocks– Resource Depletion
• Use commons-exec instead– Automatic stream pumping– Killing of run-away processes– Asynchronous processing
19Apache Commons Exec
![Page 20: Apache Commons Exec](https://reader036.vdocuments.site/reader036/viewer/2022062314/5681344b550346895d9b3281/html5/thumbnails/20.jpg)
Resources• http://commons.apache.org/exec/
• http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html
• http://kylecartmell.com/?p=9
• http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4890847
• http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4770092
20Apache Commons Exec