Question

I want to execute a batch file within my java application.

I want to execute it this way:

   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();
            }

For explaination:
Let us consider I would use a normal cmd execution. I would open cmd, then i would go to my directory:

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

Afterwars I would start the batch file with the following command:

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

On the command line this works fine, it starts the batch and inside this batch there is a subprocess wich gets started:

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?)

But with my execution inside my Java application I have the following problem: It only prints the first echo of my batch file but the subprocess does not start. When I catch the errorstream (like shown in the code on top) it says:

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

After some reseach I found out that the cmd has problems to start subprocesses because of the current working directory or something like that. I did not really understand that.

The actual thing is, that I want to execute the batch file with its neccesary parameters (start, -f and the path) within my Java application. When I execute the statements directly on the cmd everything works fine but inside my java application it sucks.

Here is the full batch file, maybe this is helpful:

@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
Was it helpful?

Solution

As you touched on, it is highly likely that your problem is that you are not executing the batch file from the proper directory. When you open the command line console and cd into the directory containing the batch file, THAT action sets the proper current working directory (CWD).

You can resolve it by changing the CWD before, or after, you enter your batch file.


Let's start by working with the CWD in the batch file; we've got a number of options here also, but let's keep it simple and just change the CWD:

set MYDIR=%~dp0
cd %MYDIR%

The first line uses a bit of batch-file magic to obtain the directory in which the currently executing batch file lives. That would be "C:/Users/User1/Desktop/Bachelor Thesis/JDBC Connector/jdbc_5.2_sp1_patch05/bin/"

Alternative

You could use an alternate form of the Runtime.getRuntime().exec() to change the CWD:
Runtime.getRuntime().exec(String[] cmdarray, String[] envp, File dir)

Invoke as:

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

I'd strongly suggest you declare a static final const value for your working dir, or find some way to eliminate the hard-coding of that value in your program.

OTHER TIPS

I would like to write down the correct answer now as a summary. But I have to mention that this is the idea of Richard Sitze and not mine.

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();
            }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top