22 Ekim 2019 Salı

LogOutputStream Sınıfı

Giriş
Şu satırı dahil ederiz.
import org.apache.commons.exec.LogOutputStream;
processLine metodu
Açıklaması şöyle.
The implementation parses the incoming data to construct a line and passes the complete line to an user-defined implementation.
Örnek
Şöyle yaparız.
public class CollectingLogOutputStream extends LogOutputStream {
  private final List<String> lines = new LinkedList<String>();
  @Override
  protected void processLine(String line, int level) {
    lines.add(line);
  }   
  public List<String> getLines() {
    return lines;
  }
}

Exec PumpStreamHandler Sınıfı

Giriş
Şu satırı dahil ederiz.
import org.apache.commons.exec.PumpStreamHandler;
PumpStreamHandler  bir OutputStream nesnesi alır. Açıklaması şöyle.
Copies standard output and error of subprocesses to standard output and error of the parent process. If output or error stream are set to null, any feedback from that stream will be lost.
Örnek - ByteArrayOutputStream 
Şöyle yaparız.
ByteArrayOutputStream bao = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(bao);
CommandLine cl = CommandLine.parse("ls -al");
DefaultExecutor executor = new DefaultExecutor();
executor.setStreamHandler(psh);
executor.execute(cl);
System.out.println(bao.toString());
Örnek - LogOutputStream
LogOutputStream kullanabiliriz.

DefaultExecutor Sınıfı - Subprocess Başlatır

Giriş
Şu satırı dahil ederiz.
import org.apache.commons.exec.DefaultExecutor;
Açıklaması şöyle. Sanırım en iyi özelliklerinden birisi ExecuteWatchdog ile zaman aşımına uğrayan process öldürülür
CommandLine
helps handling command lines specifying processes to execute. 

DefaultExecutor 
the default class to start a subprocess.

The implementation allows to set a current working directory for the subprocess
a) provide a set of environment variables passed to the subprocess
b) capture the subprocess output of stdout and stderr using an ExecuteStreamHandler
c) kill long-running processes using an ExecuteWatchdog
d) define a set of expected exit values
e) terminate any started processes when the main process is terminating using a ProcessDestroyer
Kullanım örneği burada

Gradle
Şu satırı dahil ederiz
implementation group: 'org.apache.commons', name: 'commons-exec', version: '1.3'
constructor
Şöyle yaparız.
Executor executor = new DefaultExecutor();
execute metodu - CommandLine
Diğer uygulamayı senkron çalıştırır.

Örnek - ls komutu
Şöyle yaparız
CommandLine cl = CommandLine.parse("ls -al");
DefaultExecutor executor = new DefaultExecutor();
int exitCode = executor.execute(cl);
Örnek - shell script
Şöyle yaparız
CommandLine commandLine = CommandLine.parse("sh ./hello.sh blogger");
DefaultExecutor defaultExecutor = new DefaultExecutor();
defaultExecutor.execute(commandLine);
execute metodu - CommandLine + ExecuteResultHandler
Diğer uygulamayı asenkron çalıştırır. İmzası şöyle.
public void execute(CommandLine command, ExecuteResultHandler handler) 
                                               throws ExecuteException, IOException
Genellikle DefaultExecuteResultHandler sınıfından kalıtan bir nesne kullanılır. Bu nesnenin onProcessComplete() ve onProcessFailed() metodları override edilir.

execute metodu - CommandLine + Map + ExecuteResultHandler 
Diğer uygulamayı asenkron çalıştırır. İmzası şöyle. Diğerinden farklı olarak ortam değişkenlerini içeren bir Map nesnesi alır
public void execute(CommandLine command, Map<String,String> environment,
  ExecuteResultHandler handler) throws ExecuteException, IOException
setExitValue metodu
Şöyle yaparız
Executor executor = new DefaultExecutor();
executor.setExitValue(1);
setProcessDestroyer metodu
JVM kapanırken çalışmakta olan subprocess de öldürülür

Örnek
Şöyle yaparız
CommandLine cmd = new CommandLine("...")
  .addArgument("...")
  .addArgument("...")
  .addArgument("...")
  .addArgument("...");
logger.info("Command - "+ cmd.toString());

DefaultExecutor executor = new DefaultExecutor();
executor.setProcessDestroyer(new ShutdownHookProcessDestroyer());
executor.setStreamHandler(new PumpStreamHandler(null, null, null));
executor.setWatchdog(new ExecuteWatchdog(60_000));
executor.setExitValue(0);
try {
  int exitValue = executor.execute(cmd);
  if(exitValue != 0){
    ...
  }
} catch (IOException ex) {
  ...
} 
setStreamHandler metodu
ExecuteStreamHandler arayüzünden kalıtan PumpStreamHandler kullanılabilir.

setWatchDog metodu
Milisaniye cinsindendir. 0'dan büyük bir değer olmalı
Örnek
Şöyle yaparız. watchdog.killedProcess() çağrısı ile zaman aşımından dolayı process'in kapatılıp kapatılmadığı kontrol edilebilir.
long printJobTimeout = ...;
ExecuteWatchdog watchdog = new ExecuteWatchdog(printJobTimeout);
executor.setWatchdog(watchdog);