Using java.lang.ProcessBuilder on a Java application running on a Linux machine (Ubuntu 18.04 specifically), what can be done such that the command executed would be able to run and not throw Permission Denied.
Here's the code:
boolean isWindows = System.getProperty("os.name")
.toLowerCase().startsWith("windows");
ProcessBuilder builder = new ProcessBuilder();
if (isWindows) {
builder.directory(new File(System.getProperty("user.home")));
builder.command("cmd.exe", "/c", command);
} else {
builder.directory(new File(System.getenv("HOME")));
builder.command("sh", "-c", command);
}
Process process = builder.start();
Tested on Ubuntu 18.04:
import java.io.File;
public class Application {
public static void main(String[] args) throws Exception{
boolean isWindows = System.getProperty("os.name")
.toLowerCase().startsWith("windows");
ProcessBuilder builder = new ProcessBuilder();
if (isWindows) {
builder.directory(new File(System.getProperty("user.home")));
builder.command("cmd.exe", "/c", "");
} else {
builder.directory(new File(System.getenv("HOME")));
// i used the docker command as an example, because it needs a root access (default configuration of Docker)
builder.command("/bin/bash", "-c", "sudo docker image ls > result.txt 2> errors.txt");
}
Process process = builder.start();
// When running the command java Application in terminal, i noticed that when prompted to type the root password
// the program exits so i decided to make the current thread sleep for 5 seconds, to give me time to type the password
Thread.sleep(5000);
}
}
Hope that will be helpful :)
Related
I'm writing a program that includes a feature where the user can type in Java code into a text box and be able to compile and run it. The error I get is:
The two directories shown at the top are correct, and the command works when I do it manually through command prompt from the same working directory. I'm using Windows 10, and also here's the code:
public Process compile() throws IOException {
save(); //saves changes to source file
System.out.println(file.getCanonicalPath());
ProcessBuilder processBuilder = new ProcessBuilder("javac", file.getCanonicalPath());
processBuilder.directory(new File(settingsFile.getJdkPath()));
System.out.println(processBuilder.directory());
Process process = processBuilder.start(); //Throws exception
this.compiledFile = new File(file.getParentFile(), file.getName().replace(".java", ".class"));
return process;
}
File to compile:
Working directory:
Using this code, I was able to compile a Test.java file into a Test.class file on my Desktop.
import java.io.IOException;
public class App {
public static Process compile() throws IOException {
String myFilePath = "C:\\Users\\redacted\\Desktop\\Test.java";
String javacPath = "C:\\Program Files\\Java\\jdk1.8.0_171\\bin\\javac.exe";
ProcessBuilder processBuilder = new ProcessBuilder(javacPath, myFilePath);
return processBuilder.start();
}
public static void main(String[] args) throws IOException {
Process process = compile();
}
}
Using String javacPath = "javac.exe"; also worked, but that could be because my JDK bin is on my PATH variable.
There is something wrong with your paths or permissions in the ProcessBuilder constructor call.
Although the titles are very similar, this questions is NOT a duplicate of Process output from apache-commons exec.
I am trying to get the output of a command by using apache-commons exec. Here is what I am doing
import org.apache.commons.exec.*;
import java.io.ByteArrayOutputStream;
public class Sample {
private static void runCommand(String cmd) throws Exception {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(stdout);
CommandLine cl = CommandLine.parse(cmd);
DefaultExecutor exec = new DefaultExecutor();
exec.setStreamHandler(psh);
exec.execute(cl);
System.out.println(stdout.toString());
}
public static void main(String... args) throws Exception {
String cmd1 = "python -c \"print(10)\"";
String cmd2 = "python -c \"import datetime; print(datetime.datetime.now())\"";
runCommand(cmd1); // prints 10
runCommand(cmd2); // should print the current datetime, but does not!
}
}
The problem is that runCommand(cmd2) does not print anything to the output. When I try running the command on terminal, it works fine.
I have tried this program with and without the IDE so I'm sure this has nothing to do with the IDE console.
Here's a screenshot
Here's a screenshot of the terminal
Python command running on the terminal
It works fine on mine PC from IDEA. Try to recreate the project. Add more information about your environment.
Try to put your python code into .py file and run it like "python test.py".
A colleague was able to come up with a solution to this problem. Changing
CommandLine cl = CommandLine.parse(cmd);
to
CommandLine cl = new CommandLine("/bin/sh");
cl.addArguments("-c");
cl.addArguments("'" + cmd + "'", false);
solved the issue.
The complete code looks as follows:
import org.apache.commons.exec.*;
import java.io.ByteArrayOutputStream;
public class Sample {
private static void runCommand(String cmd) throws Exception {
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(stdout);
// CommandLine cl = CommandLine.parse(cmd);
CommandLine cl = new CommandLine("/bin/sh");
cl.addArguments("-c");
cl.addArguments("'" + cmd + "'", false);
DefaultExecutor exec = new DefaultExecutor();
exec.setStreamHandler(psh);
exec.execute(cl);
System.out.println(stdout.toString());
}
public static void main(String[] args) throws Exception {
String cmd1 = "python -c \"print(10)\"";
String cmd2 = "python -c \"import datetime; print(datetime.datetime.now())\"";
runCommand(cmd1); // prints 10
runCommand(cmd2);
}
}
i'd like to run a command that executes a shell script with the java class "DefaultExecutor", but i get this error:
Cannot run program "get_encrypted_password.sh" (in directory "C:\Temp\scripts"): CreateProcess error=2 specified file not found".
the script works well with git bash.
can someone tell me where i'm doing wrong?
public Entity updateWithEncryptedPassword(Entity entity) throws IOException {
String password = entity.getPwd();
String security_key = "00000000000000000000000000000000";
String path = "C:/Temp/scripts";
CommandLine commandLine = CommandLine.parse("get_encrypted_password.sh");
commandLine.addArgument(password);
commandLine.addArgument(security_key);
String encrypted_password = Utils.runCommandAndGetOutput(commandLine, path);
entity.setNewPwd(encrypted_password);
return super.update(entity);
}
public static String runCommandAndGetOutput(CommandLine commandLine, String path) throws IOException {
DefaultExecutor defaultExecutor = new DefaultExecutor();
defaultExecutor.setExitValue(0);
defaultExecutor.setWorkingDirectory(new File(path));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(outputStream);
defaultExecutor.setStreamHandler(streamHandler);
defaultExecutor.execute(commandLine);
return outputStream.toString();
}
Instead of executing "get_encrypted_password.sh", which cannot be ran under Windows, execute "bash", (probably git bash,) and pass "get_encrypted_password.sh" as a parameter to it, so that bash will execute your script.
I am getting error while executing sh file by using java code.From terminal, it is working fine
sudo: no tty present and no askpass program specified
My Code :-
package com.test;
import java.io.IOException;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.exec.DefaultExecutor;
import org.apache.commons.exec.ExecuteException;
public class TestScript {
int iExitValue;
String sCommandString;
public void runScript(String command){
sCommandString = command;
CommandLine oCmdLine = CommandLine.parse(sCommandString);
DefaultExecutor oDefaultExecutor = new DefaultExecutor();
oDefaultExecutor.setExitValue(0);
try {
iExitValue = oDefaultExecutor.execute(oCmdLine);
} catch (ExecuteException e) {
System.err.println("Execution failed.");
e.printStackTrace();
} catch (IOException e) {
System.err.println("permission denied.");
e.printStackTrace();
}
}
public static void main(String args[]){
TestScript testScript = new TestScript();
testScript.runScript("sh /home/FTP-SCP-Project/shellscript.sh");
}
}
sh file :-
sudo scp -i /home/FTP-SCP-Project/src/lib/demo.pem -r /home/FTP-SCP-Project/test-output3 user#xx.xxx.xx.xxx:/var/www/html/projects/demo_reports/reporttest112
I have tried all other java code also but they are giving error while I have giving them all permision like chmod 777 or 755 or 600
String Pemfilepath="/home/shubham/Experiment_zone/FTP-SCP-Project/src/lib/cuelogic.pem";
String targetFolder = "/home/shubham/Experiment_zone/FTP-SCP-Project/test-output3";
String[] command = { "sudo scp -i "+Pemfilepath+" -r "+targetFolder+" "+"ubuntu#54.152.13.148:/var/www/html/projects/kumo_reports/reporttest1"};
// String command = "ls";
System.out.println(command[0]);
Process process = Runtime.getRuntime().exec(new String[] { "sudo ", "scp ", "-i " ,Pemfilepath," ", "-r"," ",targetFolder," ","user#xx.xxx.xx.xxx:/var/www/html/projects/demo_reports/reporttest1" });
BufferedReader reader = new BufferedReader(new InputStreamReader(
process.getInputStream()));
String s;
while ((s = reader.readLine()) != null) {
System.out.println("Script output: " + s);
}
But they are also giving error as below :-
Exception in thread "main" java.io.IOException: Cannot run program
"sudo ": error=2, No such file or directory at
java.lang.ProcessBuilder.start(ProcessBuilder.java:1047) at
java.lang.Runtime.exec(Runtime.java:617) at
java.lang.Runtime.exec(Runtime.java:485) at
com.test.shelllocallaunch.main(shelllocallaunch.java:14) Caused by:
java.io.IOException: error=2, No such file or directory at
java.lang.UNIXProcess.forkAndExec(Native Method) at
java.lang.UNIXProcess.(UNIXProcess.java:187) at
java.lang.ProcessImpl.start(ProcessImpl.java:130) at
java.lang.ProcessBuilder.start(ProcessBuilder.java:1028) ... 3 more
I have observe that if the command is small like ls everything is fine but my above command is not executing while it is working fine from terminal.
Please help if I missing anything
"echo "+pass+" | "+"sudo -S Worked for me
My full code seems like below :-
String pass = "\"Yourpassword\"";
out.println("echo "+pass+" | "+"sudo -S scp -i "+Pemfilepath+" -r "+targetFolder+" "+"user#xx.xxx.xx.xxx:/var/www/html/projects/demoproject");
Hope it will help you :)
i want to execute the following command using a java program.
"java -jar Demo.jar readExcelDemo.Hvd"
public class ExcelDriver {
public static void main(String[] args) throws IOException {
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec("cmd","/c", "cmd.exe","java -jar Demo readExcelDemo.Hvd");
}
}
Try this:
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec("java -jar Demo.jar readExcelDemo.Hvd");
If above code is not okay, try this:
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec("cmd.exe /c start java -jar Demo.jar readExcelDemo.Hvd");
If you want to watch cmd, you can use below code.
It will immediately close because of the /c flag.
Process p = runTime.exec("cmd.exe /c start cmd /k java -jar Demo.jar readExcelDemo.Hvd");
create a .bat or .cmd file with content
java -jar Demo readExcelDemo.Hvd
change your code to
public class ExcelDriver {
public static void main(String[] args) throws IOException {
Runtime runTime = Runtime.getRuntime();
Process process = runTime.exec("cmd","/c", "myfile.cmd");
}
}
You can just call:
Runtime.getRuntime().exec(command);