0

我想在我的 java 应用程序中执行一个批处理文件。

我想这样执行它:

   String[] args = new String[] {
                    "C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/connect.bat",
                    "start",
                    "-f",
                    "C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/etc/db.xml" };

Process p = Runtime.getRuntime().exec(args);
p.waitFor();

            BufferedReader prout = new BufferedReader(new InputStreamReader(p.getErrorStream()));
            String buffer;
            while ((buffer = prout.readLine()) != null) {
                System.out.println(buffer);
                buffer = prout.readLine();
            }

解释:
让我们考虑我会使用正常的 cmd 执行。我会打开 cmd,然后我会转到我的目录:

cd C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin

Afterwars 我将使用以下命令启动批处理文件:

connect start -f C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/etc/db.xml

在命令行上这工作正常,它启动批处理,在这个批处理中有一个子进程启动:

if exist %JAVA_HOME%\bin\java.exe (
java -XX:NewSize=%NEWSIZE% -XX:NewRatio=1 -Xms%MAXHEAP% -Xmx%MAXHEAP% -Dfile.encoding=%ENCODING% -Djava.ext.dirs=%EXT_DIR% com.fastsearch.esp.connectors.jdbc.JDBCConnector %1 %2 %3 %4 %5 %6 %7
) else (echo Is JAVA_HOME=%JAVA_HOME% set correctly?)

但是在我的 Java 应用程序中执行时,我遇到了以下问题:它只打印我的批处理文件的第一个回显,但子进程没有启动。当我捕捉到错误流(如顶部代码所示)时,它说:

UNC-Pfade werden nicht unterstützt. (UNC-Paths are not supported)
java.lang.NoClassDefFoundError: com/fastsearch/esp/connectors/jdbc/JDBCConnector

经过一番研究,我发现由于当前工作目录或类似的原因,cmd 在启动子进程时存在问题。我真的不明白。

实际情况是,我想在我的 Java 应用程序中执行带有必要参数(开始、-f 和路径)的批处理文件。当我直接在 cmd 上执行语句时,一切正常,但在我的 java 应用程序中它很糟糕。

这是完整的批处理文件,也许这会有所帮助:

@echo off
rem This bat file should setup the java env and run the connector manager
SETLOCAL

echo Copyright (c) Microsoft Corporation.  All rights reserved.

rem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
rem Java 1.6 must be installed and set here
rem !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

if NOT defined JAVA_HOME (
   echo Sorry..
   echo You have NOT set JAVA_HOME - Should point to where JRE 1.6.x or later is installed
   echo Exiting.......
   goto end
)
set JAVA_HOME=%JAVA_HOME%
:: Remove quotes if exist, then add quotes in case spaces
SET JAVA_HOME=###%JAVA_HOME%###
SET JAVA_HOME=%JAVA_HOME:"###=%
SET JAVA_HOME=%JAVA_HOME:###"=%
SET JAVA_HOME=%JAVA_HOME:###=%
SET JAVA_HOME="%JAVA_HOME%"

SET PATH=%JAVA_HOME%\bin
SET EXT_DIR=..\lib;%JAVA_HOME%\lib;%JAVA_HOME%\lib\ext
SET CLASSPATH=..\etc
SET MAXHEAP=1408m
SET NEWSIZE=256m
SET ENCODING=UTF8

if exist %JAVA_HOME%\bin\java.exe (
java -XX:NewSize=%NEWSIZE% -XX:NewRatio=1 -Xms%MAXHEAP% -Xmx%MAXHEAP% -Dfile.encoding=%ENCODING% -Djava.ext.dirs=%EXT_DIR% com.fastsearch.esp.connectors.jdbc.JDBCConnector %1 %2 %3 %4 %5 %6 %7
) else (echo Is JAVA_HOME=%JAVA_HOME% set correctly?)

:end
4

2 回答 2

1

正如您所提到的,您的问题很可能是您没有从正确的目录执行批处理文件。当您打开命令行控制台并cd进入包含批处理文件的目录时,该操作将设置正确的current working directory(CWD)。

您可以通过在输入批处理文件之前或之后更改 CWD 来解决它。


让我们从批处理文件中的 CWD 开始;我们在这里也有很多选项,但让我们保持简单,只需更改 CWD:

set MYDIR=%~dp0
cd %MYDIR%

第一行使用了一些批处理文件魔法来获取当前正在执行的批处理文件所在的目录。那将是“C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/”

选择

您可以使用另一种形式Runtime.getRuntime().exec()来更改 CWD:
Runtime.getRuntime().exec(String[] cmdarray, String[] envp, File dir)

调用为:

File workingDir = new File("C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/");
Runtime.getRuntime().exec(args, null, workingDir);

我强烈建议您static final const为您的工作目录声明一个值,或者找到一些方法来消除程序中该值的硬编码。

于 2012-07-30T14:55:40.117 回答
0

我现在想把正确答案写下来作为总结。但我不得不提一下,这是 Richard Sitze 的想法,而不是我的想法。

static final String workingdirectory = "C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin"; 
    String[] args = new String[] {"C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/connect.bat",
            "start",
            "-f",
            "C:/Users/User1/Content-Integration Testing Framework/JDBC Connector/etc/db.xml" };
    Process p = Runtime.getRuntime().exec(args2, null, workingDir);
    BufferedReader prout = new BufferedReader(new InputStreamReader(p.getInputStream()));
                String buffer;
                while ((buffer = prout.readLine()) != null) {
                    System.out.println(buffer);
                    buffer = prout.readLine();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
于 2012-08-02T07:12:31.603 回答