Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Runtime Exec on Windows Fails with Unicode in Arguments

I want to launch a browser and load a web page using Java's Runtime exec. The exact call looks like this:

String[] explorer = {"C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE", 
    "-noframemerging", 
    "C:\\ ... path containing unicode chars ... \\Main.html"};
Runtime.getRuntime().exec(explorer);

In my case, the path contains "\u65E5\u672C\u8A9E", the characters 日本語.

Apparently it's a java bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4947220

My question is: is there a viable workaround that can be done solely using Java? It appears that it is possible to write a JNI library for this, but I'd like to avoid that if possible. I have tried URI-encoding the path as ascii and writing the commands to a batch file, without success.

like image 950
Bear Avatar asked Dec 09 '09 20:12

Bear


2 Answers

At the mentioned Java bug page you will find a workaround that is reported to work using ProcessBuilder and wrapping the parameters in environment variables. Here is the source code from Parag Thakur:

String[] cmd = new String[]{"yourcmd.exe", "Japanese CLI argument: \ufeff\u30cb\u30e5\u30fc\u30b9"};        
Map<String, String> newEnv = new HashMap<String, String>();
newEnv.putAll(System.getenv());
String[] i18n = new String[cmd.length + 2];
i18n[0] = "cmd";
i18n[1] = "/C";
i18n[2] = cmd[0];
for (int counter = 1; counter < cmd.length; counter++)
{
    String envName = "JENV_" + counter;
    i18n[counter + 2] = "%" + envName + "%";
    newEnv.put(envName, cmd[counter]);
}
cmd = i18n;

ProcessBuilder pb = new ProcessBuilder(cmd);
Map<String, String> env = pb.environment();
env.putAll(newEnv);
final Process p = pb.start();
like image 168
Mot Avatar answered Oct 22 '22 22:10

Mot


Create a .bat/.sh file. Write your commands to that file and execute it. Make sure that you have changed the code page to unicode in case of windows(chcp 65001). For example to execute the below command in windows:

String[] command ={"C:\\aconex\\学校\\mysql\\bin\\mysql", "-esource", "大村箕島a\\data.sql"};

Create a temp file called temp.bat and execute with the Runtime.getRuntime().exec temp.bat

chcp 65001
C:\aconex\学校\mysql\bin\mysql -esource 大村箕島a\data.sql
like image 40
Arshed Avatar answered Oct 22 '22 22:10

Arshed