使用ProcessBuilder调用exe连接数据库时环境变量不生效问题求助
Hey Paul, let's break down why your Java code is throwing that "role 'PAUL' doesn't exist" error even though it works perfectly in the command prompt. The root issue isn't actually with the environment variable setup—it's how you're passing command arguments to ProcessBuilder.
核心问题:多余的引号破坏了参数解析
在Windows命令提示符里,我们用引号把包含空格的内容打包成单个参数,但ProcessBuilder不需要这些引号——它会把字符串数组里的每个元素当作独立的、完整的参数。你当前代码里给"ESRI Shapefile"、PG连接串等参数加了转义引号(\"),这会让ogr2ogr把这些引号当成参数的一部分来解析,导致逻辑出错。
比如你代码里传递的PG连接串:
"PG:\"host=127.0.0.1 user=postgres dbname=mydbname password=mypassword\""
ogr2ogr会把它识别成带字面引号的PG:"host=...",无法正确解析其中的user=postgres配置,于是 fallback 到系统默认的USERNAME环境变量(也就是你的PAUL)。
修复步骤:去掉参数中的多余引号
把命令数组里所有转义引号都去掉,让每个参数保持原始内容。修正后的代码如下:
public void exec(){ String[] command = new String[] { "C:\\Program Files\\bin\\ogr2ogr.exe", "-f", "ESRI Shapefile", "C:\\Temp\\mydata.shp", "PG:host=127.0.0.1 user=postgres dbname=mydbname password=mypassword", "mytable" }; ProcessBuilder pb = new ProcessBuilder(command); pb.redirectErrorStream(true); // 现在不需要修改USERNAME环境变量了! // PG连接串里已经明确指定了user,ogr2ogr会直接使用这个配置 try { Process p = pb.start(); BufferedReader bufIn = new BufferedReader(new InputStreamReader(p.getInputStream())); String str1 = null; while ((str1 = bufIn.readLine()) != null) { textOutput.append(str1 + "\n"); System.out.println(str1); } // 新增:检查进程退出码,方便排查后续问题 int exitCode = p.waitFor(); System.out.println("进程退出码:" + exitCode); } catch (IOException | InterruptedException e) { e.printStackTrace(); } }
为什么环境变量修改没起作用?
你虽然在ProcessBuilder里把USERNAME改成了postgres,但因为连接串解析失败,ogr2ogr根本没用到这个配置。一旦连接串格式正确,它会优先使用串里的user=postgres参数,完全不需要改动环境变量。
额外建议:完善错误处理
我在代码里加了p.waitFor()来获取进程退出码——0代表执行成功,非0值则说明有错误,这能帮你更快定位后续可能出现的问题。
内容的提问来源于stack exchange,提问作者Paul

