I am trying to run a shell command from my application directory and I am getting "working directory null and environment null.
I have looked at several posts here but I'm not quite sure where to go from here.
Error:
Error running exec(). Command: [/data/user/0/com.netscout.iperf3_clientls] Working Directory: null Environment: null
public void startApp() {
StringBuffer output = new StringBuffer();
Process process = null;
String appFileDir = getApplicationInfo().dataDir;
// String commandLine = appFileDir + "/iperf3 -c 129.196.197.116 --forceflush -O3 -Z -P2";
String commandLine = appFileDir + "ls";
try {
process = Runtime.getRuntime().exec(commandLine, null, null);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
// output.append(line + "/n");
Log.e("Line", String.valueOf(line));
Log.e("output", String.valueOf(output));
}
} catch (IOException e) {
e.printStackTrace();
Log.i("Output", String.valueOf(e));
}
}
Try setting a working directory for the script to run from. Also I would suggest to use a ProcessBuilder for doing your job:
https://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
Related
I'm trying to run
docker-compose up -d
in Java application. Here's my code:
List<String> commands = new ArrayList<>();
commands.add("zsh");
commands.add("-c");
commands.add("docker-compose up --build");
Process dockerComposeCommand;
ProcessBuilder pb = new ProcessBuilder();
pb.command(commands);
pb.directory(new File(server_config.getDOCKERFILE_PATH()));
String path = System.getenv("PATH");
pb.environment().put("PATH","/usr/bin:"+path);
pb.redirectErrorStream(true);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
List<String> result = new ArrayList<>();
try {
dockerComposeCommand = pb.start();
dockerComposeCommand.waitFor();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(dockerComposeCommand.getInputStream()))) {
String line = reader.readLine();
while (line != null) {
result.add(line);
line = reader.readLine();
System.out.println(line);
}
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
However, the result was
zsh:1: command not found: docker-compose
I've checked my .zshrc file and add
export PATH="$PATH:/usr/local/bin"
to include docker-compose's path.
Did I miss something or docker-compose just can't simply execute by Java?
Any advice would be helpful!
I am trying to execute a curl command using Java using the code below
String myUrl= "https://someIp:somePort";
String username = "someusername";
String password = "somepassword";
String command = "curl -k -d \"client_id=someId\" -d \"username="+username+"\" -d \"password="+password+"\" -d \"grant_type=password\" -d \"client_secret=\" \""+myUrl+"/myauth/openid-connect/token\"";
Process process = Runtime.getRuntime().exec(command);
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = process.getInputStream().read(buffer)) != -1) {
result.write(buffer, 0, length);
}
String response = result.toString(StandardCharsets.UTF_8.name());
This works on windows machine but not on linux. Is there any difference between linux and windows in the way curl command is executed using exec method ?
Both execution are done using same JRE. On windows I get the token successfully but in Linux I get the following response :
Response = {"error":"invalid_request","error_description":"Missing form parameter: grant_type"}
Thank you
After investigation it seems that when someone executes this java code in linux enviroment the curl command is not properly constructed.
I used the following code and everything worked fine :
String cUrlToKeyCloak = "curl -k -d \"client_id=someId\" -d \"username="+username+"\" -d \"password="+password+"\" -d \"grant_type=password\" "+keyCloakUrl+"/auth/realms/master/protocol/openid-connect/token";
ProcessBuilder processBuilder = new ProcessBuilder();
if(!System.getProperty("os.name").contains("Windows"))
processBuilder.command("bash", "-c", cUrlToKeyCloak );
else
processBuilder.command("cmd.exe", "/c", cUrlToKeyCloak );
String cKeyResponse = "";
try {
Process process = processBuilder.start();
StringBuilder output = new StringBuilder();
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
}
int exitVal = process.waitFor();
if (exitVal == 0) {
LOGGER.info("Curl command to keyCloak requested ...");
LOGGER.info("cKey response = "+output);
cKeyResponse = output.toString();
} else {
LOGGER.error("Curl command to keyCloak executed with error ...");
LOGGER.info("cKey response = "+output);
return false;
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
I want to talk to the program cordova in Java. In the terminal I can do this to get the version:
cordova -v
and in the terminal will return:
3.4.1-0.1.0
But if I ask Java to run cordova -v It returned Error: java.io.IOException: Cannot run program "cordova": error=2, No such file or directory.
I tried this in the terminal:
/usr/local/bin/cordova -v
and it still returned:
3.4.1-0.1.0
But when I asked Java to run /usr/local/bin/cordova -v it didn't return anything. Got a fix for my problem?
Edit
Pasted from comment
I'm calling my runShell function like
runShell("cordova -v");
private String runShell(String command) {
StringBuffer output = new StringBuffer();
Process p;
try {
p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader reader =
new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine())!= null) {
output.append(line + "\n");
}
} catch (Exception e) {
System.out.println(e); return "Error: " + e;
}
return output.toString();
}
You want
Runtime.getRuntime().exec(new String[]{ "/usr/local/bin/cordova", "-v" });
You have to pass the command and each of its arguments separately, because you're not invoking a shell to parse the command line for you.
So I want to execute sh script from java
Code:
String command = "/__data/1.sh";
ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command);
Process p = null;
try {
p = pb.start();
} catch (IOException e) {
System.out.println("Could not execute script");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(
p.getInputStream()));
try {
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(command + " says: " + line);
}
} catch (IOException e) {
System.out.println("Error reading response");
}
1.sh:
echo Hello
mkdir QWE
echo Hello2
What I got:
/__data/1.sh says: Hello
/__data/1.sh says: Hello2
Mkdir takes no effect
1.sh chmodded to 777
What's the problem?
UPD: oh, my fault, forgot the line, now edited. But the main question is why other commands do not work. Yea, like mkdir.
When I call /bin/bash -c /__data/1.sh from console it works propertly
UPD: oh, it seems, mkdir doesn't work propertly because I did not set full path. Sorry. Solved
You're missing + line at the end of println. That should at least get rid of some of the confusion. Not sure why mkdir isn't working though.
Am trying to run the source code from this link
Compile and run source code from Java application
I installed the Mingw32 compiler changed the compiler location path and getting this error when running a sample .cpp file in Eclipse.
public class C_Compile {
public static void main(String args[]){
String ret = compile();
System.out.println(ret);
}
public static String compile()
{
String log="";
try {
String s= null;
//change this string to your compilers location
Process p = Runtime.getRuntime().exec("cmd /C \"C:\\MinGW\\bin\\mingw32-gcc-4.6.2.exe\" C:\\MinGW\\bin\\Hello.cpp ");
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
boolean error=false;
log+="\n....\n";
while ((s = stdError.readLine()) != null) {
log+=s;
error=true;
log+="\n";
}
if(error==false) log+="Compilation successful !!!";
} catch (IOException e) {
e.printStackTrace();
}
return log;
}
public int runProgram()
{
int ret = -1;
try
{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("cmd.exe /c start a.exe");
proc.waitFor();
ret = proc.exitValue();
} catch (Throwable t)
{
t.printStackTrace();
return ret;
}
return ret;
}}
Errors:
mingw32-gcc-4.6.2.exe: error: CreateProcess: No such file or directory
Can anyone tell me where to place my Source .cpp File. Thanks
The error message indicates, that the gcc compiler itself was not found.
Why don't you use gcc.exe instead of mingw32-gcc-4.6.2.exe anyway? If you do an update of MinGW, the latter will get invalid!
Also you do not need to use \" in the string, when the path does not contain whitespace characters.
You can place your cpp file then anywhere you want, providing the path to that gcc. Exec should also have a parameter dir, that you can set to the directory of your cpp.
public static void CompileCprog(String filename){
File dir = new File("C://Users//JohnDoe//workspace//Project");
try {
String exeName = filename.substring(0, filename.length() - 2);
Process p = Runtime.getRuntime().exec("cmd /C gcc " + filename + " -o " + exeName, null, dir);
// Process p = Runtime.getRuntime().exec("cmd /C dir", null, dir);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
This works perfectly for me.
The "dir" variable can be set to any location you want.
The first "p" process compiles a program and produces a .exe file with the same name (minus the .c) in the same location of the program you are compiling.
The buffered reader can be used if there is output from your command.
If you changed the command string to .exec("cmd /C dir"); the result of this will be printed in the output. (im using eclipse)