Am trying to run a .mpkg application from my java code :
public void runNewPkg(){
try {
String command = "sudo installer -pkg Snip.mpkg -target /Applications";
Process p = Runtime.getRuntime().exec(command);
System.out.println(p.getErrorStream());
} catch (Exception ex) {
ex.printStackTrace();
}
}
And am getting the following error and my terminal window hangs..
java.lang.UNIXProcess$DeferredCloseInputStream#2747ee05
Password:
Sumit-Ghoshs-iMac-3:downloads sumitghosh3$ Password:
Password:
-bash: **********: command not found
Sumit-Ghoshs-iMac-3:downloads sumitghosh3$
I Think i need to provide the password also to run the pkg from the command line
Could you tell me how i can do that?
You can provide the password to sudo:
echo "p#sw0rd" | sudo -S cal -y 2011
The command above runs 'cal -y 2011' with root permissions.
I would actually try editing your /etc/sudoers file to not prompt for a password. If you use the NOPASSWD tag, you should be able to do that. An example entry would be:
sumitghosh3 ALL=(ALL) NOPASSWD: ALL
If you want an interactive solution for elevating privilege, I have used openscript to elevate privilege of a wrapped shell script. It goes something like this:
import java.io.File;
import java.text.MessageFormat;
/**
* OsxExecutor.java
*/
public class OsxExecutor {
private String error = null;
private String output = null;
/**
* Privileged script template format string.
* Format Arguments:
* <ul>
* <li> 0 = command
* <li> 1 = optional with clause
* </ul>
*/
private final static String APPLESCRIPT_TEMPLATE =
"osascript -e ''try''"
+ " -e ''do shell script \"{0}\" {1}''"
+ " -e ''return \"Success\"''"
+ " -e ''on error the error_message number the error_number'' "
+ " -e ''return \"Error: \" & error_message''"
+ " -e ''end try'';";
public void executeCommand(String command, boolean withPriviledge) {
String script = MessageFormat.format(APPLESCRIPT_TEMPLATE,
command,
withPriviledge
? "with administrator privileges"
: "");
File scriptFile = null;
try {
scriptFile = createTmpScript(script);
if (scriptFile == null) {
return;
}
// run script
Process p = Runtime.getRuntime().exec(scriptFile.getAbsolutePath());
StreamReader outputReader = new StreamReader(p.getInputStream());
outputReader.start();
StreamReader errorReader = new StreamReader(p.getErrorStream());
errorReader.start();
int result = p.waitFor();
this.output = outputReader.getString();
if (result != 0) {
this.error = "Unable to run script "
+ (withPriviledge ? "with administrator privileges" : "")
+ "\n" + script + "\n"
+ "Failed with exit code: " + result
+ "\nError output: " + errorReader.getString();
return;
}
} catch (Throwable e) {
this.error = "Unable to run script:\n" + script
+ "\nScript execution "
+ (withPriviledge ? " with administrator privileges" : "")
+ " failed: " + e.getMessage();
} finally {
if (scriptFile.exists()) {
scriptFile.delete();
}
}
}
}
If withPriviledge flag is true, a password dialog will be raised. Not shown is createTmpScript() which creates an executable file in /tmp, and StreamReader which extends Thread and is used to capture both stdout and stderr streams.
Related
I am trying to execute git clone in Java using Java's Runtime.getRuntime().exec() in Linux and the interpreter is /bin/bash. However, I get "no such file or directory" in error stream. I searched the stackoverflow and found no answer can solve my problem. Here is my program in Test.java:
import java.io.*;
public class Test {
public static void main(String[] args) throws IOException, InterruptedException {
String version = "10.1.1";
String repo_url = "https://github.com/postcss/postcss-url";
String directory = "./tmp";
String cmd = "\"/usr/bin/git clone --branch " + version + " " + repo_url + " --depth=1 " + directory + "\"";
// String cmd = "git -h";
String interpreter = "/bin/bash";
cmd = " -c "+ cmd;
System.out.println(interpreter + cmd);
Process process = Runtime.getRuntime().exec(new String[]{ interpreter, cmd });
print(process.getInputStream());
print(process.getErrorStream());
process.waitFor();
int exitStatus = process.exitValue();
System.out.println("exit status: " + exitStatus);
File[] files = new File(directory).listFiles();
System.out.println("number of files in the directory: " + files.length);
}
public static void print(InputStream input) {
new Thread(new Runnable() {
#Override
public void run() {
BufferedReader bf = new BufferedReader(new InputStreamReader(input));
String line = null;
try {
while ((line = bf.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("IOException");
}
}
}).start();
}
}
./tmp is surely an empty directory. I use javac Test.java to compile the code and then run java Test. Besides, I tried sudo java Test and got the same result. I get output like this:
/bin/bash -c "/usr/bin/git clone --branch 10.1.1 https://github.com/postcss/postcss-url --depth=1 ./tmp"
exit status: 127
/bin/bash: -c "/usr/bin/git clone --branch 10.1.1 https://github.com/postcss/postcss-url --depth=1 ./tmp": No such file or directory
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:18)
When I use "git -h" or "ls", it works just fine. But, this command /bin/bash -c "/usr/bin/git clone --branch 10.1.1 https://github.com/postcss/postcss-url --depth=1 ./tmp" works in shell but failed in Java. How can I solve this problem?
You have to pass -c as a separate parameter, and you shouldn't add literal double quotes to the command:
new String[]{ "bash", "-c", "git clone ..." }
This is because spaces and quotes are shell syntax, and Runtime.exec doesn't invoke one to run the command (which happens to be a shell invocation, but that's unrelated)
I am trying to pass scm command programmatically using java and trying to get the result of that particular command on eclipse console but i am unable to perform so,here is the approach that i followed :
public SCMCommand(final String repositoryURI, final String userId, final String password,
final String scmtoolspath, String streamName) {
this.repositoryURI = repositoryURI;
this.userId = userId;
this.password = password;
this.scmtoolspath = scmtoolspath;
this.streamName = streamName;
}
public void setCommand() throws IOException
{
String line;
String tempPath1 = this.scmtoolspath + "\\scm";
this.command = "cmd /c " + tempPath1 + " show operations -r " + this.repositoryURI + " -u "+ this.userId + " -P " + this.password + " " + this.streamName;
System.out.println(this.command);
ProcessBuilder processBuilder = new ProcessBuilder();
// Run this on Windows, cmd, /c = terminate after this run
processBuilder.command(this.command);
try {
Process process = processBuilder.start();
// blocked :(
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
}
catch (IOException e) {
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Your Help will be appreciated,
Thanks in advance!!!!
Also the output what i am getting on my console
java.io.IOException: Cannot run program "cmd /c C:\AB_TOOLS\ALMAddons\CodeReviewMetrics\libs\SCMTools\jazz\scmtools\eclipse\scm show operations -r ****8** -u **** -P **** streamName": CreateProcess error=2, The system cannot find the file specified
Build Result: All Streams Loaded Successfully
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at com.bosch.airbag.StreamHistory.SCMCommand.setCommand(SCMCommand.java:52)
at com.bosch.airbag.StreamHistory.App.main(App.java:75)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(ProcessImpl.java:386)
at java.lang.ProcessImpl.start(ProcessImpl.java:137)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 2 more
Important Notes
-The path of the file is correct
-when i am running the given command i.e" cmd /c C:\AB_TOOLS\ALMAddons\CodeReviewMetrics\libs\SCMTools\jazz\scmtools\eclipse\scm show operations -r ****8** -u **** -P **** streamName"
-its running fine on command prompt but not on eclipse ide
I am working on a java UNO project, OS : Ubuntu 14. I am calling exec via passing command to run via a jar file with some set of sub commands of that jar file.
String finalOutputMSG = "";
String[] cmd = {JAVA_LOCATION, " -jar ", JAR_LOCATION, " " + inputFile, " -dir ", ".isc", " -out xml"};//java location provides java location, jar location provides jar location, inputfile contains input file's location -dir provides output directory with name .isc, -out is output file with file format for output is xml
Similar command ran properly without showing any errors but in a case where I am trying to import a file and convert it into another format eg .xlsx to .xml, is giving error. In commands it worked, I have already generated outputs from an input file.
finalOutputMSG = exec(cmd);
/**
* exec() is executed and outputs are displayed
*
* #param String[] command passed to jar
* #return output message containing outputs or output message
*/
private static String exec(String[] cmd) {
String outputMSG = "";
Process proc = null;
try {
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);//any error output generated by subprocesses merged with the standard output,
//read using the Process.getInputStream()
///* Start the process */
proc = pb.start();
if (debug) {
System.out.println("Process started !");
}
outputMSG = getOutput(proc);
if (debug) {
System.out.println("outputMSG " + outputMSG);
}
} catch (IOException e) {
if (debug) {
System.out.println("Exception in exec " + e.getMessage());
JOptionPane.showMessageDialog(null, "Exception in exec ");
}
// StringBuilder append = appendToFile.append("Exception in exec ").append(e.getMessage());
} catch (Exception e) {
if (debug) {
System.out.println("Exception in exec " + e.getMessage());
JOptionPane.showMessageDialog(null, "Exception in exec ");
}
} finally {
///* Clean-up */
proc.destroy();
if (debug) {
System.out.println("Process ended !");
}
}
return outputMSG;
}
/**
* Reads output from current process
*
* #param current process
* #return output read in current process
*/
private static String getOutput(Process p) {
StringBuilder outStream = new StringBuilder();
if (debug) {
System.out.println("StringBuilder initialized in getOutput");
}
try {
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
if (debug) {
System.out.println("BufferedReader initialized in getOutput");
}
String line = null;
if (debug) {
System.out.println("in.readLine() in getOutput abt to be read");
}
while ((line = in.readLine()) != null) {
outStream.append(line);
if (debug) {
System.out.println("line in getOutput " + line);
System.out.println("outStream in getOutput " + outStream);
}
outStream.append("\n");
}
} catch (IOException e) {
if (debug1) {
System.out.println("IOException in getOutputs " + e.getMessage());
}
} catch (Exception ex) {
if (debug1) {
System.out.println("Exception in getOutputs" + ex.getMessage());
}
}
return outStream.toString();
}
Error Message depicted by Netbeans
Error: Could not find or load main class -jar
I have searched on the issue, but could not find any help that is useful, I could not understand, what is missing.
Solution:
String[] cmd = {JAVA_LOCATION, " -jar ", JAR_LOCATION, " " + inputFile, " -dir ", ".isc", " -out xml"};
I replaced the values that printed in console, and ran the command so got on terminal, it worked fine.
Solution: the command to be used must be without any spaces in the ends. Because terminal in linux interprets the commands like for "ls", but in java/ any programming language, it doesn't interprets for ls, so in case of the following parameter cmdarray
public Process exec(String[] cmdarray)
throws IOException
takes the command as it is.
String[] cmd = {JAVA_LOCATION, "-jar", JAR_LOCATION, inputFile, "-dir", ".isc", "-out", "xml"};
I'll start with saying that I found a lot of topics simular to mine, but none were able to provide me with the correct answer.
I'm trying to insert a string into an xml file using following shell script :
#!/bin/bash
cd /var/lib/tomcat7/webapps/Config || exit
sudo sed -i '/<\/home>/i <entry>'"$#"'</entry>' data.xml
when executing the script like this ./script.sh "test entry", my xml-file will look like this :
<home>
<entry>test entry</entry>
</home>
which is what I want. But when I try to call this script trough java, I'm not able to successfully escape the quotes.
My java code is this :
String entry = "test entry";
String command = "/home/user/addentry.sh " + "\"" + entry + "\"";
Process p = null;
Runtime run = Runtime.getRuntime();
try {
p = run.exec(command);
}
.....
When the code is executed my xml file looks like this :
<home>
<entry>"test
</home>
As you can see, the quote is also passed as part of my input.
When changing the java code to :
String command = "/home/user/addentry.sh " + entry;
it works fine for strings without a space (so only 1 parameter for the script)
Thanks in advance
Try this:
package org.script.test;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Invalid arguments");
return;
}
String entry="\"" +args[0]+ "\"";
System.out.println("adding: " + entry);
Process pr = null;
try {
pr =
Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", "cd /home/oracle/testscript ; . ./test.sh " + entry });
} catch (IOException e) {
e.printStackTrace();
}
}
}
Called by:
assume package org.script.test
java -Xms128M -Xmx128M -classpath testScript.jar org.script.test.Main "test entry"
It works even if you don't pass the arguments:
package org.mihai.script;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
String entry = "test entry 2";
System.out.println("adding: " + entry);
Process pr = null;
try {
pr =
Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", "cd /home/oracle/testscript ; . ./test.sh " + "\"" + entry +"\"" });
} catch (IOException e) {
e.printStackTrace();
}
}
}
Call:
java -Xms128M -Xmx128M -classpath testScript.jar org.mihai.script.Main
Output data.xml:
<home>
<entry>test entry</entry>
<entry>test entry 2</entry>
</home>
I tried to run the following code which is to create a backup of my database but it shows some run time errors.
But, I tried to run the System.out.println() output part, (which I've commented in the given code) in mysql shell and it worked.
It shows io file problem. Plz somebody help me.
package files;
public class tableBackup_1 {
public boolean tbBackup(String dbName,String dbUserName, String dbPassword, String path) {
String executeCmd = "mysqldump -u " + dbUserName + " -p" + dbPassword + " --add-drop-database -B " + dbName + " -r " + path;
Process runtimeProcess;
try
{
System.out.println(executeCmd);//this out put works in mysql shell
runtimeProcess = Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
if (processComplete == 0)
{
System.out.println("Backup created successfully");
return true;
}
else
{
System.out.println("Could not create the backup");
}
} catch (Exception ex)
{
ex.printStackTrace();
}
return false;
}
public static void main(String[] args){
tableBackup_1 bb = new tableBackup_1();
bb.tbBackup("test","harin","1234","C:/Users/Master/Downloads/123.sql");
}
}
mysqldump -u harin -p1234 --add-drop-database -B test -r C:/Users/Master/Downloads/123.sql
java.io.IOException: Cannot run program "mysqldump": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(ProcessBuilder.java:460)
at java.lang.Runtime.exec(Runtime.java:593)
at java.lang.Runtime.exec(Runtime.java:431)
at java.lang.Runtime.exec(Runtime.java:328)
at files.tableBackup_1.tbBackup(tableBackup_1.java:12)
at files.tableBackup_1.main(tableBackup_1.java:34)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(ProcessImpl.java:81)
at java.lang.ProcessImpl.start(ProcessImpl.java:30)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:453)
... 5 more
Please check whether your Global PATH environment variable has <Path to MySQL>\bin in it (Do a echo %PATH% and see). Effectively you should be able to type your System.out.println() content in a Plain DOS prompt and should be able to run it.
Even with that if it doesn't work try changing the code to execute like below
runtimeProcess = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", executeCmd });
This should ideally fix the issue.
UPDATE:
If you don't have it in the PATH environment variable change the code to following
String executeCmd = "<Path to MySQL>/bin/mysqldump -u " + dbUserName + " -p" + dbPassword + " --add-drop-database -B " + dbName + " -r " + path;
runtimeProcess = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", executeCmd });
i tried this one but it didn't work so i replaced it with
this runtimeProcess = Runtime.getRuntime().exec(executeCmd);
and it worked
I solved this problem by giving full path to mysqldump.exe
You can get SO environment variables by
Map<String, String> env = System.getenv();
final String LOCATION = env.get("MYSQLDUMP");
I setup the system variable like this :
Variable Name : MYSQLDUMP
Value : D:\xampp\mysql\bin\mysqldump.exe
Now just execute this code below,
String executeCmd = LOCATION+" -u " + DBUSER + " --add-drop-database -B " + DBNAME + " -r " + PATH + ""+FILENAME
Process runtimeProcess = = Runtime.getRuntime().exec(executeCmd);
Note : If you don't have configured password for mysql server just remove the -p PASSWORD attribute from the code. And don't forget to restart your computer after creating a new system variable.