Search code examples
javaconcurrencyprocessbuilder

Java Servlets - how to synchronize ProcessBuilder?


I guess this isn't necessarily a servlet related question - but I'm using the code in a servlet setting to give a little background. I'm using the windows cscript tool via ProcessBuilder in order to convert MS Office documents (e.g. ppt, doc etc..) into PDF. I have a vb script that does this.

One problem I've noticed in the past is that some of the apps (powerpoint) don't run in a windowless environment; that is the vb script script briefly pops open a PowerPoint window when its run. PowerPoint is a single instance application, so issue arise when you try and run this script concurrently.

I've considered java synchronized blocks - however my understanding is that they are more geared towards shared resources such as files and IO resources - & don't think they would properly control access to a particular script that ProcessBuilder was executing.

Code Sample:

ProcessBuilder pb = new ProcessBuilder("cscript", "C:\\Users\\Foo User\\Documents\\office2pdf.vbs", "C:\\Users\\Foo User\\Documents\\SomePPTFile.pptx"); 
            Process pr = pb.start();
            int i = pr.waitFor() ;

I've used OpenOffice in the past which has a good Java API - however would prefer to stick with MS Office, as it does a better job of converting PDFs. Any suggestions would be much appreciated.


Solution

  • You can have a private static object in your servlet:

    private static final Object processLock = new Object();
    

    The you can lock access to the entire process builder:

    synchronized (processLock)
    {
        // only one servlet thread at a time in here...
        ProcessBuilder pb = new ProcessBuilder("cscript", "C:\\Users\\Foo User\\Documents\\office2pdf.vbs", "C:\\Users\\Foo User\\Documents\\SomePPTFile.pptx"); 
        Process pr = pb.start();
        int i = pr.waitFor() ;
    }