Commits

Michael Heemskerk committed 122363c

CRUC-4793: Fix for JVM bug with unicode cmdline arguments

Comments (0)

Files changed (1)

processutils/src/main/java/com/atlassian/utils/process/ExternalProcess.java

 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.ThreadFactory;
         this.monitors.remove(monitor);
     }
     
+    private boolean isWindows() {
+    	return System.getProperty("os.name").toLowerCase().contains("windows");
+    }
+    
+    private Process createWinProcess(String[] cmdArray, String[] environment, File workingDir) throws IOException {
+        // workaround for JVM bug on windows. See http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4947220 for details
+        Map<String, String> newEnv = new HashMap<String, String>();
+        if (environment == null) {
+            // inherit the environment of the current process
+            newEnv.putAll(System.getenv());
+        } else {
+            // add the env entries
+            for (String env: environment) {
+                String[] values = env.split("=");
+                if (values.length > 1) {
+                    newEnv.put(values[0], values[1]);
+                }
+            }
+        }
+        String[] i18n = new String[cmdArray.length + 3];
+        i18n[0] = "cmd";
+        i18n[1] = "/C";
+        i18n[2] = "/u";
+        i18n[3] = cmdArray[0];
+        for (int counter = 2; counter < cmdArray.length; counter++) {
+            String envName = "JENV_" + counter;
+            i18n[counter + 3] = "%" + envName + "%";
+            newEnv.put(envName, cmdArray[counter]);
+        }
+        cmdArray = i18n;
+
+        ProcessBuilder pb = new ProcessBuilder(cmdArray);
+        Map<String, String> env = pb.environment();
+        env.putAll(newEnv);
+        return pb.start();
+    }
+    
+    private Process createProcess(String[] cmdArray, String[] environment, File workingDir) throws IOException {
+    	if (isWindows()) {
+    		return createWinProcess(cmdArray, environment, workingDir);
+    	} else {
+    		return Runtime.getRuntime().exec(cmdArray, environment, workingDir);
+    	}
+    }
+    
     /**
      * Start the external process and setup the IO pump threads needed to
      * manage the process IO. If you call this method you must eventually call the
     public void start() {
         try {
             this.startTime = System.currentTimeMillis();
-            this.process = Runtime.getRuntime().exec(cmdArray, environment, workingDir);
+            this.process = createProcess(cmdArray, environment, workingDir);
             setupIOPumps();
         } catch (IOException e) {
             processException = new ProcessException(e);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.