J'ai récemment développé un petit gestionnaire de processus (écrit en Groovy) pour faciliter l'exécution des commandes systèmes/bash (traitement asynchrone pour le lancement d'un nouveau processus pris en charge) et ainsi permettre plus facilement la création de bootstrap ou tout autre type de programme pouvant servir plus ou moins d'amorce.
L'utilisation du gestionnaire est très simple:
En Java:
class yourClass
{
public yourClass()
{
ProcessManager processManager = new ProcessManager();
processManager.setCommand(processManager.new ProcessWrapper(Runtime.getRuntime().exec("your command")));
processManager.runProcess();
}
}
En Groovy:
def processManager = new ProcessManager()
processManager.setCommand(new ProcessWrapper(processManager, Runtime.getRuntime().exec('your command')))
processManager.runProcess()
Bien évidemment, si quelqu'un l'utilise et rencontre des problèmes ou bugs incompréhensibles, me mp.
Code source du module:
import java.lang.Thread
import java.lang.Process
import java.io.InputStream
import java.io.InputStreamReader
import java.io.BufferedReader
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import java.util.concurrent.ExecutorService
/**
* @author songbird
* This class encapsulates a "process manager" to catch output and error streams of the targeted process
*/
class ProcessManager
{
final def service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())
def processPool = new java.util.LinkedList<ProcessWrapper>()
ProcessManager()
{
}
/**
* Awesome process object wrapper :D
* Example:
* new ProcessWrapper(new ProcessManager(), Runtime.getRuntime().exec('your command'))
*
*/
public class ProcessWrapper
{
/**
* log managers
*/
synchronized StreamGobbler errorManager, inputManager
/**
* the process
*/
synchronized Process process
ProcessWrapper(process)
{
assert process in Process : "parameter isn't Process object: $process"
this.process = process
}
protected void setErrorManager(final errorManager)
{
assert errorManager in StreamGobbler : "parameter isn't a StreamGobbler object: $errorManager"
this.errorManager = errorManager
}
protected void setInputManager(final inputManager)
{
assert inputManager in StreamGobbler : "paramater isn't a StreamGobbler object: $outputManager"
this.inputManager = inputManager
}
Process getProcess()
{
return process
}
}
class StreamGobbler implements Runnable
{
final InputStream inputStream
StreamGobbler(final inputStream)
{
assert inputStream in InputStream : "parameter is NOT input stream: $inputStream"
this.inputStream = inputStream
}
public void run()
{
try
{
def reader = new BufferedReader(new InputStreamReader(inputStream))
def line = null
while(!null.equals(line = reader.readLine()))
{
println line
}
}catch(java.io.IOException ioe0)
{
ioe0.getMessage()
}
}
}
/**
* @param process The process to prepare
*
* Prepare and add process to the pool
* Example:
* def processManager = new ProcessManager()
* processManager.setCommand(new ProcessWrapper(processManager, Runtime.getRuntime().exec('your command')))
*
* Have fun ! :D
*
*/
void setCommandProcess(process)
{
def name = ProcessWrapper.class.getName()
assert process in ProcessWrapper : "parameter isn't a $name object: $process"
process.setErrorManager(new StreamGobbler(process.getProcess().getErrorStream()))
process.setInputManager(new StreamGobbler(process.getProcess().getInputStream()))
processPool.add(process)
}
/**
* Example:
* def processManager = new ProcessManager()
* processManager.setCommand(new ProcessWrapper(processManager, Runtime.getRuntime().exec('your command')))
* processManager.runProcess()
* Have fun ! :D
*/
void runProcess()
{
if(!processPool.isEmpty())
{
for(ProcessWrapper wrapper : processPool)
{
service.execute(wrapper.errorManager)
service.execute(wrapper.inputManager)
service.execute(new Runnable()
{
@Override
public void run()
{
wrapper.getProcess().waitFor()
}
})
}
}
else
{
println "The process pool is empty."
Runtime.getRuntime().exit(0x1)
}
}
}
Have fun !