How can I start a .jar in xterm with args? - java

if (args.length == 0&&runningFromIntelliJ()==false) {
String OS = System.getProperty("os.name", "generic").toLowerCase(Locale.ENGLISH);
if (OS.indexOf("win") >= 0) {
String path = CODE.run.class.getProtectionDomain().getCodeSource().getLocation().getPath().substring(1);
String decodedPath = null;
try {
decodedPath = URLDecoder.decode(path, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
try {
Runtime.getRuntime().exec("cmd"+" /c start java -jar \"" + decodedPath + "\" run");
} catch (IOException e) {
e.printStackTrace();
}
System.exit(0);
}
}
}
This Code is Starting a programm in cmd after i double clicked it. the problem is that it only works in windows And I want to run it on my raspberry pi. The problem now is that I habe no Idea how a can start a .jar with args in xterm.
runningFromIntelliJ() is just testing if I am running the programm in IntelliJ and skips that part if I do.

It seems like your app will do nothing once there's an argument passed to the jar.
if(args.length==0)
will be false hence the whole if. If you have other code to run with Arguments, try this:
java -jar yourJar.jar "arg 1" arg2#
Otherwise, review your code.

Here is one way to start a program with xterm.
xterm -hold -e '/bin/bash -c "ls -l"'
In this example, the program is simply the ls command, but it should be self-explanatory how to use it for java; just use the example found in another answer.
In your java code, what that looks like is:
Runtime.getRuntime().exec(String.format("xterm -hold -e '/bin/bash -c \"%s\"'", "java -jar '" + decodedPath + "' run"));
or without a shell:
Runtime.getRuntime().exec(String.format("xterm -hold -e 'java -jar \"%s\" run'", decodedPath));

Related

Adding double quotes symbol in ProcessBuilder

I am using ProcessBuilderto build my command. I want to build my command following this post:How do I launch a java process that has the standard bash shell environment?
Namely, my command is something like this:
/bin/bash -l -c "my program"
However, I am having difficulties to pass the double quotes into ProcessBuilder, as new ProcessBuilder(List<String> command) failed to phrase the command if I natively add double quotes to List<String> command. ProcessBuilder recognizes the double quotes as an argument.
Relevant code:
//Construct the argument
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"");
csi.add(csi_path);
csi.add(pre_hash);
csi.add(post_hash);
csi.add("\"");
String csi_output = Command.runCommand(project_directory, csi);
public static String runCommand(String directory, List<String> command) {
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(new File(directory));
Process process;
String output = null;
try {
process = processBuilder.start();
//Pause the current thread until the process is done
process.waitFor();
//When the process does not exit properly
if (process.exitValue() != 0) {
//Error
System.out.println("command exited in error: " + process.exitValue());
//Handle the error
return readOutput(process);
}else {
output = readOutput(process);
System.out.println(output);
}
} catch (InterruptedException e) {
System.out.println("Something wrong with command: " +e.getMessage());
} catch (IOException e) {
System.out.println("Something wrong with command: " +e.getMessage());
}
return output;
}
Ps: I do want to use ProcessBuilder instead of Runtime.getRuntime.exec() because I need to run the command in a specific directory. I need to use ProcessBuilder.directory().
Ps: The command will exit with 2 after running. It seems that the system can recognize this command. The strange thing is that it has no output after exiting with 2.
Ps: The expected command is /bin/bash -l -c "/Users/ryouyasachi/GettyGradle/build/idea-sandbox/plugins/Getty/classes/python/csi 19f4281 a562db1". I printed the value and it was correct.
Best way to troubleshoot your problem is to construct the command first and pass it to the list. So, instead of doing all this.
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"");
csi.add(csi_path);
csi.add(pre_hash);
csi.add(post_hash);
csi.add("\"");
You should first construct the command
StringBuilder sb = new StringBuilder();
sb.append("/bin/bash -l -c");
sb.append("\""+csi_path+pre_hash+post_hash+"\"");// add whitespace between the varaible, if required.
System.outprintln(sb.toString()); //verify your command here
csi.add(sb.toString());
Also, verify all above variable values.
Thx for #Ravi 's idea!
//Construct the argument
csi.add("/bin/bash");
csi.add("-l");
csi.add("-c");
csi.add("\"" + csi_path + " " + pre_hash+ " " + post_hash + "\"");
String csi_output = Command.runCommand(project_directory, csi);
The Process has to take each argument separately in order to recognize the command. The tricky part is that, in my desired command
/bin/bash -l -c "/mypath/csi"
"/mypath/csi" needs to be viewed as one single argument by Process.

How to load bashrc in java program and execute command

public CGAOperationStatus downloadMetaData() {
CGAOperationStatus retCgaOperationStatus = new CGAOperationStatus();
try {
createDirectoryIfNeeded("/sure/replication/metadata");
String prepareRsyncCommand = "gsutil -m rsync -d -r gs://"
+ storeCredentials.getStoreAccount()
+ "/sure/metadata /sure/replication/metadata'";
Process p = Runtime.getRuntime().exec(prepareRsyncCommand);
p.waitFor();
} catch (Exception e) {
System.out.print("Exception in downloading metadata from GoogleBucket");
retCgaOperationStatus
.setScgaError(CGAError.SCGA_EXCEPTION_OCCURRED);
ExceptionHandler.logException(logger, e);
retCgaOperationStatus.setErrorMessage(e.getMessage());
}
return retCgaOperationStatus;
}
I have installed and Gcloud SDK on linux machine and i am trying to run gsutil command from a Jar File and my jar is executed from some outside program over ssh . But it just not working.
If i am running same command manually it works fine. May be because .bashrc is loaded when i am running command.
How can i do same thing from java.
You should use a String[] instead of a simple String as a parameter in the call to Runtime.
Runtime.getRuntime().exec(new String[]{"gsutil", "-m", "rsync", "-d", "-r", "gs://"+ storeCredentials.getStoreAccount(), "/sure/metadata /sure/replication/metadata'"});

trying to execute mysqldump from java app, multiple problems

I am writing a java app that needs to perform mysql dump, and I am using the runtime.exec, based in the when runtime.exec won't article. The code is below:
public int exectuteCommand(){
Runtime rt = Runtime.getRuntime();
logger.debug("exexuting cmd: " + showCommand());
int exit = -1;
try {
Process proc = rt.exec(cmd);
ExtProcessStreamHandler errorHandler = new ExtProcessStreamHandler(proc.getErrorStream(), "ERROR");
ExtProcessStreamHandler outHandler = new ExtProcessStreamHandler(proc.getInputStream(), "OUTPUT");
// kick it off
errorHandler.start();
outHandler.start();
exit = proc.waitFor();
} catch (IOException e) {
logger.error("ERROR!! ~~ executing command " + showCommand(), e);
e.printStackTrace();
} catch (InterruptedException e) {
logger.error("ERROR!! ~~ unexpected return for " + showCommand() + " , returned " + exit, e);
e.printStackTrace();
}
return exit;
}
1) The command that the process returns works in the shell (I'm running this on a mac). The first error I had was an inability to find the mysqldump command. That results in this error:
java.io.IOException: Cannot run program "mysqldump": error=2, No such file or directory
I resolved that by adding the complete path of the file to the command. The $PATH var shows
/usr/local/mysql/bin/mysqldump
as the complete path. How can I make sure my java app has that info?
2) when adding the complete path to the command, I get this error msg:
INFO [Thread-1] (ExtProcessStreamHandler.java:28) - external process ERROR : mysqldump: Couldn't find table: ">"
Here is the code that builds the command array:
return new String[] {MYSQLDUMP_CMD, "-u", USER_DEFAULT, "-p"+ PW_DEFAULT, TEST_DB_NAME,
">", DUMP_LOC};
again, when I copy the command passed to the java app into the shell on my mac, it works. Not sure what I'm doing wrong.
thanks in advance!
It thinks ">" is an argument intended for mysqldump. You are invoking an executable, not evaluating a shell expression. If you want to pipe your output, do it with the outHandler and errorHandler in your code.
An alternative is to invoke a shell and pass the expression you want to evaluate as an argument:
expr = new StringBuilder()
.append(MYSQLDUMP_CMD).append(' ')
.append("-u").append(USER_DEFAULT).append(' ')
.append("-p").append(PW_DEFAULT).append(' ')
.append(TEST_DB_NAME).append(' ')
.append(">").append(' ')
.append(DUMP_LOC)
.toString();
return new String[] {"/bin/bash", "-c", expr};
If your code to build the command array doesn't wrap spaced arguments in single quotes (or if the JDK doesn't do this for you), then modify the StringBuilder statement to create the wrapped quotes for you.
Below Code is worked for me
public static void backup() {
String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd"));
String backupPath = String.format("%s/%s.%s", Helper.BACKUP_PATH, currentDate, "sql");
File backupFile = new File(backupPath);
if (!backupFile.exists()) {
try {
backupFile.createNewFile();
String mysqlCom=String.format("mysqldump -u%s -p%s %s",USER_NAME,PASSWORD,DB);
String[] command = new String[] { "/bin/bash", "-c",mysqlCom};
ProcessBuilder processBuilder = new ProcessBuilder(Arrays.asList(command));
processBuilder.redirectError(Redirect.INHERIT);
processBuilder.redirectOutput(Redirect.to(backupFile));
Process process = processBuilder.start();
process.waitFor();
LOGGER.info("Backup done");
} catch (IOException e1) {
e1.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
LOGGER.info("Database already backuped today");
}
}

How to run sh script from jenkins

I need launch sh script from jenkins, it is simple, but my script change symlink for JAVA_HOME, in fact im switching between JDK versions using sh script. It works when Im launching job without jenkins(job writen on bash), but it does not working under jenkins... Jenkins remember JAVA_HOME after start and use this path... how can I change JAVA_HOME from sh script under jenkins ? may be from script invoke jenkins reload config if it's possible... thx for any help!
Just try as below ;
public static void execShellCmd(String cmd) {
try {
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(new String[] { "/bin/bash", "-c", cmd });
int exitValue = process.waitFor();
System.out.println("exit value: " + exitValue);
BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = buf.readLine()) != null) {
System.out.println("exec response: " + line);
}
} catch (Exception e) {
System.out.println(e);
}
}
For more details : Shell Script Running with java
Problem solved!!! soulution is simple, I have sh script that was launched in jenkins job like this:
./MY_SCRIPT.sh
And after that script launched under jenkins and I had problems with switching JAVA_HOME.
All is need to do launch script like this:
sh MY_SCRIPT.sh
and it will launched smt like from the system.

Firing command using java runtime class on a windows machine

I am trying to fire the following command on a windows(that came as part of a product we have bought):
start /wait setup /z"/sfC:\temp\input_file.txt" /s /f2"C:\temp\newlogfile.log"
Now the sad part is that I am failing to run the command using a java program that I wrote. (I have to run it as a part of something else, hence the need of running it through java)
Here is my code:
String[] cmd = new String [6];
cmd[0] = "start";
cmd[1] = "/wait";
cmd[2] = "setup";
cmd[3] = "/z\"/sfC:\\temp\\input_file.txt\"";
cmd[4] = "/s";
cmd[5] = "/f2\"C:\\temp\\newlogfile.log\"";
try
{
Runtime.getRuntime().exec(cmd);
}
catch(IOException e)
{
e.printStackTrace();
}
Please tell me what I am doing wrong here.
This is the output I am getting:
java.io.IOException: CreateProcess: start /wait setup /z"/sfC:\temp\input_file.txt" /s /f2"C:\temp\newlogfile.log" error=2
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(ProcessImpl.java:108)
at java.lang.ProcessImpl.start(ProcessImpl.java:56)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:466)
at java.lang.Runtime.exec(Runtime.java:607)
at java.lang.Runtime.exec(Runtime.java:480)
at SilentAgent.fireCommand(SilentAgent.java:316)
at mainClass.main(mainClass.java:15)
Try with this:
String[] cmd = {
"cmd.exe",
"/c",
"start",
"/wait",
"setup",
"/z\"/sfC:\\temp\\input_file.txt\"",
"/s",
"/f2\"C:\\temp\\newlogfile.log\""
};
Runtime.getRuntime().exec(cmd);
Reason: start is an internal command available only from inside a cmd shell.
Do this way:-
Runtime.getRuntime().exec(new String[] {
"start ",
"/wait ",
"setup ",
"/z\"/sfC:/temp/input_file.txt\" ",
"/s ",
"/f2\"C:/temp/newlogfile.log\""});
Are you sure that you java program is located in the same directory of the 'start' program?
If not, pass the command string as a whole string
try {
String command = "start /wait setup /z\"/sfC:\\temp\\input_file.txt\" /s /f2\"C:\\temp\\newlogfile.log\"";
// The third parameter is the current working directory
Process p = runtime.exec(c, null, new File());
} catch (Exception e) {
e.printStackTrace();
}

Categories

Resources