I'm trying to start a java GUI program in windows via java code as below :
ProcessBuilder builder = new ProcessBuilder(Arrays.asList(new String[] {"cmd.exe", "/C",
"C:\\path\\to\\program\\program.cmd"}));
try {
builder.start();
} catch (IOException e) {
e.printStackTrace();
}
The cmd file starts the program with a "start javaw .." command with ... -cp program.jar -jar program.jar . When using the java code above, it throws an error that the program.jar is not found :
I also tried with the below, using cd first :
{"cmd.exe", "/C", "cd C:\\path\\to\\program\\ && program.cmd"}));
But the above does nothing at all.
Content of .cmd :
setlocal
SET JAVAHOME=..\java
SET PATH=%JAVAHOME%\jre\bin;%JAVAHOME%\jre\bin\client;%JAVAHOME%\bin;%PATH%
SET PATH=%PATH%;bin\
SET POLICY=java.policy
SET JAR_BOOT=program.jar
SET CONFIG_FILE=program.xml
IF EXIST jar\%JAR_BOOT% copy jar\%JAR_BOOT% . >NUL
start javaw -Xbootclasspath/p:jar/xercesImpl-2.9.1.jar;jar/xml-apis-1.3.04.jar;jar/xalan-2.7.1m1.jar;jar/serializer-2.7.1m.jar -Xmx1024M -XX:MaxPermSize=200M -cp %JAR_BOOT% -Dsun.java2d.noddraw=true -DJINTEGRA_NATIVE_MODE -Djava.security.policy=%POLICY% -jar %JAR_BOOT%
title Command Prompt
endlocal
So what's the proper way to do this ?
Using the suggestion from #JMax to use the directory() method of the ProcessBuilder to set the working directory has fixed the issue
Related
Problem Statement: I just want to start the HUB and Node to perform some tests using Selenium Grid.
I have two Batch files START HUB.bat and START NODE.bat which run perfectly when i manually run them.
But i want them to run using a Java Program #BeforeMethod.
I looked for answers
Runtime.getRuntime().exec("cmd /C start \"./BatchFiles/START HUB.bat\"");
This Opens Up the CMD but goes to the path of my .git project but doesnt run the bat file.
I tried using Process Builder but that doesn't open the cmd.
ProcessBuilder pb = new ProcessBuilder("cmd", "/C"," start", "START HUB.bat");
File dir = new File("D:\\work\\GIT REPOSITORY\\project.selenium.maven.jenkinsCI\\BatchFiles");
pb.directory(dir);
Process p = pb.start();
Can someone please help me with this issue. Below are the commands in the batch file.
D:
cd work
java -jar selenium-server-standalone-3.4.0.jar -role hub
So you want to execute the command line:
cmd /C start "./BatchFiles/START HUB.bat"
With cmd at beginning of the command line a new command process is already started with executing %SystemRoot%\System32\cmd.exe. This command process should automatically close after running the command as explicitly requested with option /C which means close as it can be read on running in a command prompt window cmd /?.
The command to execute in this command process is:
start "./BatchFiles/START HUB.bat"
The internal command start of cmd.exe is for starting an executable or script in a new process. Its help can be read on running in a command prompt window start /?.
The first double quoted string is interpreted by start as title of the new command process window opened when a batch file or a console application should be executed in a new command process.
And this is the reason why the batch file is not executed because "./BatchFiles/START HUB.bat" is interpreted as window title string.
And on Windows the directory separator is \ and not / as on Unix. / is used as begin of an option as you can see on /C. But Windows handles also file paths with / often correct because of replacing each / internally by \ in directory/file names with an absolute or relative path on accessing the directory or file.
So the solution is using either
Runtime.getRuntime().exec("cmd.exe /C start \"start hub\" \".\\BatchFiles\\START HUB.bat\"");
or using
Runtime.getRuntime().exec("cmd.exe /C \"BatchFiles\\START HUB.bat\"");
A path starting with a directory or file name is relative to current directory of the running process on Windows like using .\ at begin of a directory or file name string.
The first code starts a command process which executes the command start which starts one more command process with title start hub executing the batch file. The first command process started with cmd.exe immediately terminates after running start while the batch file is executed in second started command process. This means your Java application continues while the batch file is executed parallel.
The second code results in executing the batch file in the single command process started with cmd.exe and halting the execution of the Java application until entire batch file execution finished.
The usage of a batch file can be removed here by using:
Runtime.getRuntime().exec("cmd.exe /C start \"start hub\" /D D:\\work java.exe -jar selenium-server-standalone-3.4.0.jar -role hub");
With /D D:\work the working directory is defined for the command process started for executing java.exe with its parameters.
Alternatively without using start command:
Runtime.getRuntime().exec("cmd.exe /C cd /D D:\\work && java.exe -jar selenium-server-standalone-3.4.0.jar -role hub");
Run in a command prompt window cd /? for help on cd /D D:\work and see Single line with multiple commands using Windows batch file for an explanation of operator && used here to specify two commands to execute on one line whereby java.exe is executed only if cd could successfully change the working directory to D:\work.
class RunFile
{
public static void main(String[] arg){
Runtime runtime = null;
try{
runtime.getRuntime.exec("cmd /C start \"D:\\work\\GIT REPOSITORY\\project.selenium.maven.jenkinsCI\\BatchFilesmyBatchFile.bat\\START HUB.bat\"");
}
catch(RuntimeException e){
e.printStackTrace();
}
}
}
Did you try to pass the absolute path to the exec function?
As well as quote the path since you're having a whitespace between START and HUB
The explanation by #Mofi really helped here understanding as to how cmd treats each and every "/".
Runtime.getRuntime().exec("cmd.exe /C start \"start hub\" \".\\BatchFiles\\START HUB.bat\"");
Above is the solution that worked for me.
I need a multi command to bring the CMD to the root of the disc it runs on.
This is how the structure looks on the USB
\data
\data\commands
\Java
\Java\bin
App.jar
App.bat
This is how the "event" looks:
String command = "cmd /c cd\\data\\commands && wscript \"invisible.vbs\" \"Ready2Go.bat\"";
try {
Process p = Runtime.getRuntime().exec(command);
} catch (Exception e) {
e.printStackTrace();
}
This works perfekt when running App.jar file and "using" the java thats installd on the computer it self.
But when i try to run it with the java that i installd on the usb it will not work. (guide to install java on usb
app.bat file:
set Path=\Java\bin;%%Path%%
java -jar app.jar
So i need the a command to Leave the \java\bin dir. (for it is from there, I think the program is now running) and then run my command.
i have tried:
"cmd /c cd\\ && cd\\data\\commands && wscript \"invisible.vbs\" \"Ready2Go.bat\"
But without much luck.
I really hope you understand what I mean
write a startup batch start.bat like so
#echo off
rem change to this batch's folder
pushd "%~dp0"
set Path="%~dp0\Java\bin";%%Path%%
set JAVA_HOME=%~dp0\Java
java -jar App.jar
popd
and execute it as \data\commands\start.bat
Setting the current path of a process from java is done using ProcessBuilder and setting the directory-property. See a sample here
How to set working directory with ProcessBuilder
I am working on a minecraft control panel in Ubuntu and thus I need to start/stop a .jar filewith shell_exec();
When I try commands like "whoami", the output is normal. But when I try this:
shell_exec("screen -dmS mcsrv java -Xmx512M -jar /var/www/srv/craftbukkit.jar -o true nogui");
It does not do anything, I have checked the permissions too and www-data is the owner of the files
Try to redirect the standard error stream to stdout (by appending 2>&1 to the command), fetch that output and print it to check whether there was a meaningful error message
$cmd = "screen -dmS mcsrv java -Xmx512M -jar /var/www/srv/craftbukkit.jar -o true nogui";
$redirect = '2>&1';
// using variable substitution only for readability here
shell_exec("$cmd $redirect", $output);
var_dump($output);
I am starting a java programm under Red Hat Enterprise Linux Server release 5 (Tikanga).
directory structure:
- bin ->sc.jar,start-sc.sh,sc-lib-all.jar
- conf->log4j-sc.properties,sc.properties
command to run the java programm (which is perfectly working):
/usr/java/jdk1.6.0_37/bin/java -Xmx1024M -Dlog4j.configuration=file:../conf/log4j sc.properties -jar sc.jar -config ../conf/sc.properties
if i put it into a shell script the java programm can't find the prop file anymore.
shell script (start-sc.sh) looks like:
#!/bin/sh
/usr/java/jdk1.6.0_37/bin/java -Xmx1024M -Dlog4j.configuration=file:../conf/log4j-sc.properties -jar sc.jar -config ../conf/sc.properties
i am a newbie on shell scripting any ideas what i am missing? thx!
i guess you started your shell script not from the bin directory, which the dir start-sc.sh belongs to.
to explain it clear, let's make an example.
say, your script is here:
/foo/bar/bin/start-sc.sh
if you start it under /foo/bar/bin/, it (the relative path) should work.
but if you start your script from /home/yourHome/someDir/ , the relative path will point to $PWD/../, which is /home/yourHome/
you could either in your script first cd /foo/bar/bin/ before you start the java app. or do something like:
a=`dirname $0`
if [ $a = '.' ];then
a=`pwd`
fi
cd $a
/usr/java/jdkxxxx/java .....
It sound fine to me, does this version work?
#!/bin/sh
/usr/java/jdk1.6.0_37/bin/java -Xmx1024M -Dlog4j.configuration=file:$(pwd)/../conf/log4j-sc.properties -jar sc.jar -config $(pwd)/../conf/sc.properties
Edit #1:
Try put the following before launching your program:
echo `pwd`
The output tells you where you are running your script, so you can check if it's the right path or not.
Edit #2:
Try this script
#!/bin/bash
LOG4JCONF="/absolute/path/to/the/log4j/conf/file"
SCCONF="/absolute/path/to/the/other/conf/file"
/usr/java/jdk1.6.0_37/bin/java -Xmx1024M -Dlog4j.configuration=file:$LOG4JCONF -jar sc.jar -config $SCCONF
I would like to execute 2 or more commands sequentially through my Java Application using ProcessBuilder class. I Have tried multiple options as suggested in other responses/forums but no luck.
Here are the things I have tried:
ProcessBuilder processBuilder = new ProcessBuilder("ls", ";", "pwd");
Gives me following error :
Errors : ls: ;: No such file or directory
Errors : ls: pwd: No such file or directory
ProcessBuilder processBuilder = new ProcessBuilder("ls", "&&", "pwd");
Gives me similar error:
Errors : ls: &&: No such file or directory
Errors : ls: pwd: No such file or directory
List<String> command = new ArrayList<String>();
command.add("ls");
command.add(";");
command.add("pwd");
ProcessBuilder processBuilder = new ProcessBuilder(command);
Gives me following error:
Errors : ls: ;: No such file or directory
Errors : ls: pwd: No such file or directory
My OS is Linux/Mac-OSX.
Your approaches are equivalent to calling ls with the specified arguments. In Bash notation, what you're running is:
ls ';' pwd
ls '&&' pwd
If you want ls and pwd to be run as separate commands, you can use Bash (or another shell language) to wrap them into a single command:
bash -c 'ls ; pwd'
which you can call this way:
ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", "ls ; pwd");
I'm using ProcessBuilder to compile java program like this and it works for me:
ProcessBuilder b = new ProcessBuilder("cmd.exe","/c","cd " + dir,
" & javac " + mapClassName + ".java -cp " + pathToProjectClasses);
cmd.exe : it's start the command prompt.
\c : not sure what its doing but its important, you can see this link for more information (\? cmd commands)
cd + dir : is the first command and its change the directory to a certain path which is dir.
& : its mean start the second command after you finish the first one
javac : this word and the rest of the string is the second command
-cp : path to external class used by the class you want to compile.
So I have 2 commands, first one is cd command and second one is javac command and i execute them sequentially using &.
Sorry for my bad writing skills, if I haven't explained my code well please ask me about anything you want to know.
You could get the Process from ProcessBuilder.start() from the first command, wait using waitFor() and then launch the second one.