A new JavaFX 2.0 has been released! I remember that I have been trying for a while to work with previous versions 1.1 and 1.2, and to be honest it was horrible experience. I did that because I have been searching for the tool which allows to create true multimedia application in JAVA. Also I wanted to create a very nice GUI. Well I think that previous versions of JavaFX were completely failures...
Need to check 2.0 though, because I saw some video tutorials and it looks really nice!
UPDATE
So I could not resist myself and today I downloaded JDK 1.7u2 (with JavaFX 2.0 support) and NetBeans 7.1. Unfortunately I had to work on Windows, because I could not find proper version of JavaFx SDK for 64bit Linux, on which I usually work. I managed to do some simple tutorials from http://docs.oracle.com/javafx/index.html.
My first impression is that the whole API is very simple and in a few lines of code we get really nice GUI! What is more, there is also a set of classes that allows to integrate Swing with JavaFX. Not to mention about using CSS for application skinning and creating application layouts and components inside XML files. Oh! And there is even a possibility to use for example JavaScript or Groovy to write applications' logic!
Looking forward to JavaFX 2.0 for 64bit Linux architecture. Finally we can create nice looking desktop application in Java, which can also handle multimedia content as well. It is time to start thinking about rewriting my old Swing projects :)
Wednesday, January 25, 2012
Tuesday, January 17, 2012
Bash Shell in Java: “Cannot run program ”/bin/bash“: java.io.IOException: error=24, Too many open files”
Recently i have faced a problem as in the title. I was using JAVA's ProcessBuilder class, which allows to use bash shell and its scripts. Unfortunately my program after a while started to log that it "Cannot run program".
If you encounter similar problem, googling a while will give you plenty of pages with some more or less accurate solutions. Most of them will tell to check how many files are currently open in the system (by unix command lsof) and how's that number related to your system limit (check by bash command ulimit -n). Increasing maximum number of open files at a time is short-term solution in my opinion.
Let's get back to the core of problem. In my code I was using below lines:
After using new ProcessBuilder and reader of input stream we must assure that InputStreamReader will be closed after reading as it should release any associated files. So I have added following lines:
Above code should be used in finally block. This solution works but not always, because it will not close all pipes and subprocesses triggered by shell command. For example when I have used
I was creating multiple unnamed pipes, which stayed open and were increasing the total number of open files. To cleanup after executing shell command all subprocesses have to be stopped:
Destroying all subprocesses will do the thing. It will not impact on the result of shell command as in the code we have following line
To summarize, if we want to avoid this problem we should use something similar to below function:
That's all. Hope it will help :)
If you encounter similar problem, googling a while will give you plenty of pages with some more or less accurate solutions. Most of them will tell to check how many files are currently open in the system (by unix command lsof) and how's that number related to your system limit (check by bash command ulimit -n). Increasing maximum number of open files at a time is short-term solution in my opinion.
Let's get back to the core of problem. In my code I was using below lines:
ProcessBuilder pb = new ProcessBuilder("bash", "-c", command);
pb.redirectErrorStream(true); // use this to capture messages sent to stderr
Process shell = pb.start();
InputStream shellIn = shell.getInputStream(); // this captures the output from the command
int shellExitStatus = shell.waitFor(); // wait for the shell to finish and get the return code
InputStreamReader reader = new InputStreamReader(shellIn);
BufferedReader buf = new BufferedReader(reader);
// Read lines using buf
After using new ProcessBuilder and reader of input stream we must assure that InputStreamReader will be closed after reading as it should release any associated files. So I have added following lines:
if(reader != null) {
try {
reader.close();
} catch (IOException ex) {
log.error(ex, ex);
}
}
if(shellIn != null) {
try {
shellIn.close();
} catch (IOException ex) {
log.error(ex, ex);
}
}
Above code should be used in finally block. This solution works but not always, because it will not close all pipes and subprocesses triggered by shell command. For example when I have used
ps aux | grep java | awk '{if($1=="root") print $11}' | grep test | wc -l
I was creating multiple unnamed pipes, which stayed open and were increasing the total number of open files. To cleanup after executing shell command all subprocesses have to be stopped:
if(shell != null) {
try {
shell.destroy();
} catch (Exception ex) {
log.error(ex, ex);
}
}
Destroying all subprocesses will do the thing. It will not impact on the result of shell command as in the code we have following line
int shellExitStatus = shell.waitFor();
To summarize, if we want to avoid this problem we should use something similar to below function:
public String bashCommand(String command) {
ProcessBuilder pb = new ProcessBuilder("bash", "-c", command);
pb.redirectErrorStream(true); // use this to capture messages sent to stderr
Process shell = null;
String result = "";
InputStream shellIn = null;
InputStreamReader reader = null;
try {
shell = pb.start();
shellIn = shell.getInputStream(); // this captures the output from the command
int shellExitStatus = shell.waitFor();
reader = new InputStreamReader(shellIn);
BufferedReader buf = new BufferedReader(reader);
String line;
while ((line = buf.readLine()) != null) {
result += line + "\n";
}
} catch (InterruptedException ig) {
// Handle error
} catch (IOException ignoreMe) {
// Handle error
} finally {
if(reader != null) {
try {
reader.close();
} catch (IOException ex) {
// Handle error
}
}
if(shellIn != null) {
try {
shellIn.close();
} catch (IOException ex) {
// Handle error
}
}
if(shell != null) {
try {
shell.destroy();
} catch (Exception ex) {
// Handle error
}
}
}
return result;
}
That's all. Hope it will help :)
Subscribe to:
Posts (Atom)