Recently, I have spent few happy hours chasing a bug in my code. It was connected to the ProcessBuilder class. This class was introduced to Java 5 in order to simplify calling of external processes.
I needed to run following rsync command, to synchronize some files from the server. It simply takes all *.txt files from all directories and ignores all other files.
rsync -vtlr --include="*.txt" --include="**/" --exclude="*" rsync.example.org::module ./mirror
With ProcessBuilder it is easy, you just have to write the following code.
It works good, without any problem. But only on Windows. When I deployed the application on the Linux server, it synchronized all the files. It looked like that –exclude directive was simply ignored.
The weird thing was, that when I run the command from the shell it worked as it was supposed to run. The usual suspects were the quotes. Since the command worked, only some parameters were ignored, it was evident that the problem is subtle. I tried to replace double quotes with single quotes, put all parameters to one. I even tried to call the command using Runtime.exec(). It was just vain effort. (Runtime.exec() internally uses ProcessBuilder). The solution is simple. Just remove all the quotes from all parameters.
Like this, it works on both Linux and Windows.