I have an executable file (ffmpeg) that I'm trying to run with a Java program on a Mac. I used the Java program to send the command chmod 777 /path/to/ffmpeg, but when I try to run ffmpeg, I get the following error:
java.io.IOException: Cannot run program "/Users/james/WalkTheHall/ffmpeg": error=13, Permission denied
But when I run chmod 777 /path/to/ffmpeg from Terminal on my own before opening the Java application, the command to ffmpeg will run just fine in the Java program.
Is there a difference between calling chmod from within the Java program and calling it on my own? Why will it not work? Thank you!
I just had the same problem in my code.
i solved this by add waitFor after exec. The "chmod" process is not finished when next command is executed. the code may look like:
p = Runtime.getRuntime.exec("chmod 777 xxx");
p.waitFor();
Runtime.getRuntime.exec("./xxx");
I'd guess that chmod is a shell command, not an executable. Try running chmod through your shell. See more details here: Want to invoke a linux shell command from Java
Yes, there is a difference. When you run the command from the terminal, it is you who is performing the action, and thus it is performed using your credentials. The Java application is running the command using the Java application's permissions. This is to prevent an application from running and then making dangerous, unwanted changes to the file system. Perhaps someone else can elaborate and give guidance to a workaround for this.
I am currently working on a project that also makes use of FFMpeg on OSX. I store FFMpeg in the JAR and extract it and set executable on use as you seem to be doing. This is what I do, and it seems to work.
public static void setExecutable(File file, boolean executable)
{
Process p = Runtime.getRuntime().exec(new String[] {
"chmod",
"u"+(executable?'+':'-')+"x",
file.getAbsolutePath(),
});
// do stuff to make sure p finishes & capture output
}
The code is GPL, so feel free to check it out. Its not the nicest codebase, and even the FFMpeg stuff is perhaps overly complex, but it works.
Source is viewable at http://korsakow.net
These two files in particular might be interesting for you
FFMpegEncoderOSX.java
FileUtil.java
Try this:
File commandFile = new File("myFile.txt");
commandFile.setExecutable(true);
Process p = Runtime.getRuntime.exec(commandFile.getAbsoluteFile());
to start an program on OSX you need this:
Runtime.getRuntime().exec("chmod 777 "+path); //in order to execute it
Runtime.getRuntime().exec(path); //execute it
Runtime.getRuntime().exec("chmod 744 "+path); //undo every change
path should be the path to the exc of the program, for example:
AppStore -> Applications/App\ Store.app/Contents/MacOS/App\ Store
Related
I would like to check whether a jar of mine is running on the users system, to then relaunch if it is closed.
I am aware of the command jps -l which makes it possible to check the current running jars. Only problem is that for that line to work, it requires the user to have a JDK installed. So I was then wondering whether or not there is an equivalent to the jps -l line, which doesn't need a JDK or anything, but just checks whether a specific jar is running.
In the past I have also used the line cmd /c tasklist for Windows and the line top -F -R -o cpu for Mac. To check whether an app or exe was running, but that doesn't really seem to be working. When running the tasklist line on Windows and I then check for an exe called "myApp", it doesn't find it. Even though it might be running. Otherwise this would have been a perfect method, to check for a running app, exe or jar.
Here is an example code of how I tried to use the tasklist command to check for a specific executable.
try {
String procss;
Process pRun = Runtime.getRuntime().exec("cmd /c tasklist");
BufferedReader input = new BufferedReader(new InputStreamReader(pRun.getInputStream()));
while ((procss = input.readLine()) != null) {
if(!procss.contains("myApp"))
{
//Runtime command to launch exe or app.
}
}
input.close();
} catch (Exception err) {
err.printStackTrace();
}
Basically I would like to just edit the code above, to have a command line, of which is able to actually check whether the exe, app or jar is running. Maybe there is an alternative to cmd /c tasklist and top -F -R -o cpu, which is able to get all processes running on a pc and not just .exe or .app
On windows, you could use the wmic command to get the command line parameters a program was launched with.
For example, using wmic process where "name like '%java%'" get commandline,processid (basically just means "get the PID and command line arguments of process with a name like java") gives me this output for a test program:
616
"C:\Program Files\Java\jre1.8.0_111\bin\javaw.exe" -jar "A:\Programmering\Java\Pong\out\artifacts\Pong_jar\Pong.jar"
As you can see, you can get the location of the jar file which is running (which you could then use to check if it's your program). In this case, I just launched it by double clicking the jar file, you may get different outputs if you launch it in a different way, but there should always be something you can use to identify the java process (like a main class or jar file).
I want my directory to give executable permissions (by default) to all the shell scripts which are going to be created in that directory after I run my Java program. I tried the following commands:
setfacl -d -m group:name:rwx /path/to/your/dir
find ./ -name "*.sh" -exec chmod +x {} \;
The first one is not showing any response while the second one works fine but I have to execute this command manually in terminal after my Java program has created all the scripts. This is not what i seek. I want this thing to be automatic. Here is what I am trying to achieve:
My Java program creates the .sh files in a directory.
Now the program would try to execute this script file.
Here is a Java code snippet which shows how it is going to execute the script files:
ExecuteShellComand obj = new ExecuteShellComand();
String command2 = "./script.sh";
String output2 = obj.executeCommand(command2);
It doesn't run unless I give the executable permissions to the script.sh. How do I do it? Is there any way around it? If I am not doing something in a way it should be done, feel free to give your suggestions. Thanks
Default ACL permissions are masked by the file's creation mode as specified in open and mkdir syscalls.
Since files are usually created with a default mode of 0666, execute permissions will be masked instead of inherited.
It's the responsibility of the program that creates the files to create them with the right permissions. If you set the permissions correctly when creating the scripts, you won't need ACL or chmod at all. The best way to fix this would be for your program to set the mode in the open call to 0777.
Java appears to have Files.createFile for this. Additionally, you have a more fuzzy File.setExecutable to do it after the fact, which is not Unix canonical behavior, but probably fine for your use case.
Very basic command-line related question:
I have never tried to run anything in command line from java before and am struggling with the basics - other online information doesn't seem to work for my example, or I'm not understanding it.
In command line this is what it looks like:
C:\gnuplot\binary>gnuplot 15FebPlotFile.gp
All I have to do in command line is navigate to the correct file location (C:\gnuplot\binary) and then type gnuplot 15FebPlotFile.gp and it runs the thing I need (which simply generates a PDF and saves it to that file location)
I've seen people use Runtime and Process like on this site http://www.java-tips.org/java-se-tips/java.util/from-runtime.exec-to-processbuilder.html but I don't understand how I call the various command, like cd C:\gnuplot\binary and then from that location get it to run gnuplot 15FebPlotFile.gp.
If anyone could give me any advice on an approriate site to look at or some lines of code that might help me I'd be really greatful.
Thank you
You can work with ProcessBuilder, and then you can set the working directory of the process using ProcessBuilder#directory(File dir):
ProcessBuilder processBuilder = new ProcessBuilder("gnuplot", "15FebPlotFile.gp");
processBuilder.directory(new File("C:\\gnuplot\\binary"));
Process p = processBuilder.start();
I hope here you can find some code examples and solutions
Run command prompt from java?
changing the working-directory of command from java
I'm trying to write Java code that executes some terminal commands. The code should execute this command sudo mount -o loop system.img system. But there are several problems. First, to execute this command I have to be root. I know that I can be by sudo su, but how can I stay as root when I close the terminal window? If I use the command sudo mount -o loop system.img system how can I provide the password in the Java code?
The second issue is: can I execute the command as below?
File f2 = new File("/home/user1/Desktop/aDirectory");
String[] commands = new String[]{"sudo mount", "-o", "loop", "/home/user1/Desktop/aDirectory/system.img"};
Runtime.getRuntime().exec(commands, null, f2);
I think I can't. So how can I do it? Any ideas?
Notes: system.img is a compiled Android os file. and the system is an empty directory. The thing I'm trying to do is mount the system.img file into the system directory.
Programs like sudo read the password directly from the terminal device, not from stdin, so this is unfortunately not a trivial thing to do. I'm not sure if this is realistic for Android or not, but on a general UNIX system the easiest solution is to use expect, which is a library for simulating a terminal and thereby automating these kinds of interactions. It's often used as a standalone program embedded in Tcl, and I've thrown together systems in which Java launched expect to talk to tools like sudo, and it works fine.
expect includes a sort of declarative scripting language that tells it how to run another program and how to react to that program's output.
What you would do is use Runtime.exec() to execute the expect program, supplying a script that just runs "sudo mount", watches for the password prompt, and provides the password. The script would probably just look something like (G4rb4geB4rg3 is the password):
spawn sudo mount -o loop /home/user1/Desktop/aDirectory/system.img
expect "password:"
send "G4rb4geB4rg3\r"
expect eof
The problem was solved, by using shell script.
I wrote a script includes just this line :
echo myPassword | sudo -S mount -o loop system.img system
then I run it in my java code, such :
Runtime.getRuntime().exec("sh 1.sh");
I'm pretty sure 'sudo' and 'mount' would be separate, since it's not a single executable you're invoking. Also, if you start sudo with the -S command line switch it can take the password directly from stdin, so you just need to start the process and pass in whatever the password's configured as to the input stream.
everyone. I'm quite new here so please be tolerant if I make any mistakes.
I have a .bat file containing a command line to open up a .jar file that contains a program that has a GUI in it. The only line that's in the .bat file is:
java -jar "NewServer.jar"
I've been trying to use Runtime() to get this to run, but most the instructions I find to open a .bat file in a java program are for Windows. I'm currently using Fedora 12 (don't tell me to upgrade, I can't) if that makes a difference and programming using Eclipse. I also found this ProcessBuilder thing, but I couldn't get it to work so unless you have very explicit directions on how to use it, please don't include it in your answer. I would much rather use Runtime. It looked simpler.
Here's my code to test using Runtime in a java program. I'm hoping that if I can get this to work, I can get it to work in my real program.
import java.io.IOException;
public class testbat {
public static void main(String[] args) {
Process proc = null;
try {
proc = Runtime.getRuntime().exec("./ myServer.bat");
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Cool");
}
The last line is just there for me to see if the program actually ran in case the GUI doesn't open. Also, I've already tried many combinations of things to include in the area after ".exec". I've tried using a path like "~/user/workspace/ProjectServer/dist/myServer.bat" to no avail.
I also already know that .bat files are for windows, but I'm able to execute it in linux, so I don't know if that makes a difference. I also tried using a .sh file the same way and it didn't work.
Please bear in mind that I'm not that great at Java, but I had to use it for this particular program, so if your answers could be really descriptive that would be awesome.
Just take that line out of the bat file, and run it. Yo're making it too hard.
$ java -jar "NewServer.jar"
will work. The quotes aren't necessary, so
$ java -jar NewServer.jar
will work as well. If you want to have the equivalent of your bat file, create a file named, say, run_newserver containing that line. Change its mode to executable:
$ cat > run_newserver
java -jar NewServer.jar
^D
$ chmod a+x run_newserver
$ ./run_newserver
Ideally, since you shouldn't have scripts without comments, do this. In your favorite editor, create a file run_newserver containing
#!/usr/bin/env bash
java -jar NewServer.jar
and chmod that. The line with #! -- often called a "shebang line" -- is UNIX magic that lets you say what interpreter you want. The program env in usr/bin finds your program and runs it (needed because different systems put bash in different directories.)
You could even put explanatory comments in the file too.
I'm a little unclear why you want to use Runtime#exec to run it at all -- it seems you'll just need a shell script to start that program.
Why are you using Java to run a Batch file, that in turn runs a Java program? Why have Batch in the loop at all? Just put the jar in your classpath and call it directly.
Batch (.bat) files are only for Windows environment. So, Try using shell script
Process proc = Runtime.getRuntime().exec("myServer.sh");
Just open up terminal and do this
vi /dir/to/exec/exec.sh
tap "i" and write this
#!/bin/sh
java -jar "NewServer.jar"
or if you want to run it in the background
#!/bin/sh
java -jar "NewServer.jar" & > /tmp/JavaServer.log
hit esc and type ":wq" and you have saved the file.
type this into the terminal
chmod +x /dir/to/exec/exec.sh
this give executable privileges and then you should run the file like
sh /dir/to/exec/exec.sh
Process is only initialized by your first call. You need to run:
proc.waitfor();
to get it to actually run your app.