I have a batch process that converts WAV to MP3 sequentially. The problem is that after a few thousand there are too many files left open, and it runs up against the file limit.
The reason it does this is because of the code in SystemCommandTasklet:
FutureTask<Integer> systemCommandTask = new FutureTask<Integer>(new Callable<Integer>() {
public Integer call() throws Exception {
Process process = Runtime.getRuntime().exec(command, environmentParams, workingDirectory);
return process.waitFor();
}
});
This has the nasty side effect of making me rely on the JVM to clean up the processes, leaving files open and such.
I’ve rewritten it to be so:
FutureTask<Integer> systemCommandTask = new FutureTask<Integer>(new Callable<Integer>() {
public Integer call() throws Exception {
Process process = Runtime.getRuntime().exec(command, environmentParams, workingDirectory);
int status = process.waitFor();
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().flush();
process.getOutputStream().close();
process.destroy();
return status;
}
});
I’m 95% certain that this works on my mac (thanks to lsof), but how do I make a proper test that will work on any system to PROVE that what I am trying to do is actually working?
A proof will be difficult. But …
Create a (Dummy)command that doesn’t do much but keeps a lock on the files, just as the real thing. This makes sure your test doesn’t depend on the actual command used.
Create a test that starts SystemCommandTask, using the old version, but the DummyCommand. Make it start the task often, until you get the expected exception. Lets call the number of Tasks needed N
Change the test to start 100xN Tasks.
Change the Task to the new version. If the test goes green you should be reasonably sure that your code works.