I'm facing a problem here and i'm thinking you guys might be able to help/point me toward appropriate documentation.
But first, context:
I'm working on this c++ script that can call and run different java runnables with arguments. But I'm a complete noob in c++, and in general coding. Started Java a couple weeks back.
this c++ script has for purpose (among other things) to intercept inputs and simulate other inputs that will then be read by already running java threads. The goal is for java to be able to run a loop like this:
public class CalledByCpp extends JFrame{
protected static KeyList listener = new KeyList(); //custom KeyListener
//frame constructor goes here
public void main(String[] args){
//initialization of bunch of things
this.addKeyListener(listener);
while(true){
requestFocus();
}
}
protected static class KeyList(){
//Handling of key pressed
}
Does this sounds possible? Or is there an easier method? And what's the event creation method i'm looking for in c++?
Side note: Both cpp and java would run on a Linux desktop (debian) without any screen attached so I assume it's safe for the java frame to loop on requestFocus(). Right?
Another lead I had was to build a driver, but I have no idea what's the difference, and how to do that, or even if it's a lead worth investing time and effort into when this cpp could act as a driver itself.
Thanks a lot!
You will probably want to give the input to Java through standard in. The 'event' to listen for could just be reading a line from standard in, or possibly multiple lines. You would just need to have some way of detecting when to stop reading and do something. Since all threads in your Java program would receive this data, you would also need some way of detecting which thread was intended to use that data. I would start your C++ program first, and then launch Java from within your C++ program, set up so that you can write data into standard in of the Java process from the C++ program. In a UNIX environment, there is a standard way to do this. From your C++ program, run something like the following (you will need to include the header unistd.h):
int fd[2];
// For sharing data with Java process
pipe(fd);
pid_t id = fork();
if (id < 0) {// system error
printf("Failed to fork process");
exit(1);
}
// parent process
else if (id > 0) {// id of child process (Java)
// optional: writes to standard out go to Java process
// can also use write(fd[1], <data>, <length>)
dup2(1, fd[1]);
close(fd[0]);
// do stuff and write to Java process as needed
// signal end of data to Java process
close(fd[1]);
// wait for Java process to exit and clean it up
if (wait(NULL) < 0) {// system error
exit(2);
}
}
else {// child (Java) process, id = 0
// Read stdin from parent (C++) process
dup2(0, fd[0]);
close(fd[1]);
char* path = "/path/to/java";
// Arguments to java. Always end with NULL
char* argv[] = {"Java_arg1", "Java_arg2", NULL}
// Run java
if (execv(path, argv) < 0) {// system error
printf("Failed to execute java command");
exit(1);
}
}
So I've had the time to try out a quick code. Using Xdotool, which you can find on github or apt-get install xdotool
//in the loop deciding which input to simulate
system("xdotool key T");
this would simulate one press of the key T. No console popping up, the script can run in background and generate inputs easily. They are actual system input so I've been able to read them in java.
Related
I am writing a program in java which can start up applications such as, for example, firefox.
Edit: This program is for linux, specifically ubuntu.
It's easy to start the program:
Runtime.getRuntime().exec("/usr/bin/firefox");
However, I want to retrieve details from the window once it is fully opened or running.
At the moment I'm just calling:
Thread.sleep(delay);
To make sure the window is ready, but this is a poor solution. Different windows requiring different delays is a problem.
Messy.
So my question is, is there any way that I can be notified when firefox (or any other external application for that matter) is fully setup? I don't think I could use Process.waitFor() because the Process won't be finished until firefox is closed.
Thanks in advance!
Update: Process.waitFor() doesn't work. I have tried it and it only returns when firefox is closed, not when it is fully setup. Just for anyone trying it themselves, if another firefox window is already open it will work (which fooled me at first) but if there is no existing window it won't!
You can use Process#waitFor to wait till the command gets executed and then check the exitValue like this:
Process p = Runtime.getRuntime().exec("/usr/bin/firefox");
p.waitFor();
if(p.exitValue()==0) {
//success
} else {
// fail read error stream or out stream for possible causes
}
Ok I have been doing some more thinking and I have a reasonably satisfactory answer.
Instead of waiting until the window is ready, continually search for it with xdotool:
while(line == null){
writer.write("xdotool search --onlyvisible --name " + name + "\n");
writer.flush();
if(reader.ready())
line = reader.readLine();
Thread.sleep(1000);
}
xdotool will only print a string if it finds a window called name.
So if the reader is ready() then you know the window is open.
The Thread.sleep() is necessary because if it is not present xdotool will spit out a bad window error and the reader will read that.
However, it seems to almost be faster to use a standard delay like I spoke about above but this solution will work even for windows which take longer to load, rather than trying to guess a delay.
I am developing a web application in which I am running Java in the front end and shell script at the back end. The application is mainly about analysis many files and the java program gets the inputs from the user such as which file they want to analyze from which date to which date they want to analyze.Lets assume user gives data from July 1-8. I need to process the 8 days file. Each day has about 100 files to be processed. So my goal is to make this process in parallel than doing this sequential. I have basically two ideas regarding this. I wanted to share this with you ppl and get ur suggestions.
PLAN 1:
There is a Java program(Business Layer), which invokes a shell script using process builder. Can I split the given date by the user, for instance (1-8) into 4 threads where each thread would do the operation of two days. such as (1-2) thread 1 and (3-4) thread 2 and it goes on. If I follow this approach what are all the pros and cons. Also how coordinate among the threads by this approach.
Plan 2:
Call the shell script from Java and inside the shell script spawn multiple processes and as I said earlier, I can spawn process 1 to do the job of date (1-2) and process 2 (3-4) and it goes on. What are all the pros and cons of this approach. And I am writing the processed output into a single file. So if I have multiple processes how can I make the single file updated by multiple processes.
Also any reference of any links related to my question
IMPORTANT:
As I told I need to process 100's of log files for each day inside a shell script, and one of my requirement is to constantly update my front end environment regarding the status of my jobs in shell script (i.e) day 1 has completed, day 2 has completed and so on . I know I can do echo from shell script and then I can get the value from Java. But the problem is if I do an echo inside the shell script, inside the loop of processing the files, my call terminates and I again have to call back from Java. Any ideas of how to make this update happen.
First, I would suggest considering the first rule of optimization: do not optimize.
Then if you really think you need to optimize it, I would pick the 1st approach and do as much as possible in Java.
One approach could be the following:
1) run all the processes with ProcessBuilder and create a List<Process>
2) Wrap each Process into a ShellScriptProcess and acquire a List<ShellScriptProcess>
class ShellScriptProcess implements Runneable() {
private Process process;
public ShellScriptProcess(Process process) {
this.process=process;
}
boolean synchronized finished = false;
public void run() {
process.waitFor(); //this will wait until the process terminates
finished = true;
}
public boolean isFinished(){
return finished;
}
}
3) wait for processes to finish
while(!allFinished) {
for (ShellScriptProcess sp : shellScriptProcesses) {
allFinished = true;
if (sp.isFinished()) {
// hurray, a process has finished, inform the UI
// you want to do something smarter here though,
//like removing the finished processes from the list
}
else {
allFinished = false;
}
}
}
This is only a very rough solution, just to demonstrate the idea of how this could be acomplished. And I didn't test the code, it might contain of syntax errors :) Hope this helps.
I'm using the javax.script.* package of the JDK. Specifically, I'm using the JavaScript engine, which, from what I've read, seems to be based on a Mozilla-developed JavaScript-in-Java interpreter called Rhino.
What I'm hoping to accomplish is to basically have my JavaScript able to "pause" itself at a certain point in the code (say, halfway through a function call) and only resume itself later when Java allows it to do so.
To illustrate what I mean, imagine this JavaScript code:
function myJSFunction() {
print("Hello ");
mysteriousPauseFunction(); // this is the part I'm wondering about. basically, the script should break here and resume later at Java's discretion...
// upon reaching this comment, we know now that Java has told JavaScript that it's okay to resume, so the next line will now be executed...
print("world");
}
If the "pausing"/"breaking" part involves binding a Java function and passing it a reference to the current ScriptEngine or whatever, that's cool with me. I'm thinking that's what this will probably involve: pausing the JavaScript from within Java.
I did some googling and found that the keyword here appears to be "continuations." From what I can tell, Rhino only supports continuations in interpreted mode (versus compiled mode), which I see is accomplished by setting the "context" to -2. Since the built-in JDK ScriptEngine doesn't seem to mention anything about contexts (or maybe I'm missing it), does this mean I have to download and use Mozilla's Rhino library directly instead?
And are Rhino continuations what I need to accomplish this? I've found a useful tutorial on Rhino continuations, but after reading through it, I'm not 100% sure if this is going to be able to accomplish what I described above. If this is what I'm looking for, then my follow-up question is about the "serialization" mentioned: does this mean that when I resume my script, all variables will have been unset unless I serialize them?
Update: It looks like this IS possible with Rhino. Here's what I have so far in my JavaScript; after the code, I'll explain what it does...
var end = new Continuation();
function myJSFunction()
{
print("Hello ");
var kont = new Continuation();
storePause(script, kont); // script is previously bound by Java into the JavaScript. it is a reference to the script itself.
end();
print("world");
}
My "storePause()" function is a Java function which I have written, and it is bound to the JavaScript, but right now, it doesn't do anything. My next goal will be to flesh out its code such that it stores the continuation and script information as Java objects, so that Java can resume the script later.
Right now, what it's doing is pausing/"breaking" the script after "Hello " is printed but before "world" is printed, so this proves to me that it is possible to pause a script this way.
So, all that I should have left to figure out at this point is how to resume a continuation. Note that the above works using the JDK scripting engine by default (I haven't needed to worry about interpreted mode vs compiled mode at this point -- it seems to default to interpreted mode), but it looks like the process of resuming a script will require Mozilla's Rhino library.
Alright, it took me many hours of digging through documentation, tutorials, and examples, and also posting on here and on the Rhino Google Group, but I've managed to compile a working solution. Since there seems to be no complete example, I'll post my findings here for anyone who stumbles across this in the future.
Actually, my findings are probably too long to post here, so I decided to write up a tutorial on my blog:
Tutorial: Continuations in Mozilla Rhino (a JavaScript interpreter for Java)
Hope that helps someone. As far as I know, this is the only complete Rhino tutorial that shows how to do all of the following: initialize Rhino, load a script from a JavaScript (*.js) file, automatically bind all of the functions in a particular Java class (e.g. ScriptFunctions) as global functions in JavaScript, and finally call a JavaScript function and handle continuations for that call.
Basically, the problem was that I needed to first download the Mozilla Rhino source code (because the version packed in with the JDK is outdated and doesn't support continuations), rewrite all of my code to use the official Rhino package's syntax (it is very different from JDK's ScriptingEngine syntax), write a Java function that throws a ContinuationPending exception and bind it to JavaScript so JavaScript can call it (because throwing a ContinuationPending directly from JavaScript results in a JavaScriptException being thrown, not a ContinuationPending being thrown, and even trying to call getCause() on that JavaScriptException results in null), and then in my Java code that calls my JavaScript function ("myJSFunction" in my original example), have try/catch blocks to check for a ContinuationPending (which is an exception), and then use that ContinuationPending
later to resume the script.
Phew. It was tough, but it's all worth it now.
You didn't explain why you were doing this, but I was emulating a program that interacts with an end user, like this:
print('Hello!');
a=Number(input('enter a number'));
b=Number(input('and another number'));
print('the sum of '+a+' plus '+b+' is '+(a+b))
I've got it working just by creating a print and an input function in javascript that checks for program state.
you can see a demo here.
it's all written in javascript so you can look at the source code with any browser.
Hope it helps
You could use wait/notify:
public final class Pause {
private final Object lock = new Object();
public void await() throws InterruptedException {
synchronized (lock) {
lock.wait();
}
}
public void resumeAll() {
synchronized (lock) {
lock.notifyAll();
}
}
}
Usage:
final Pause pause = new Pause();
class Resumer implements Runnable {
#Override public void run() {
try {
Thread.sleep(5000);
pause.resumeAll();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
new Thread(new Resumer()).start();
SimpleBindings bindings = new SimpleBindings();
bindings.put("pause", pause);
String script = "print('Hello, ');\n"
+ "pause.await();\n"
+ "println('ECMAScript!');\n";
new ScriptEngineManager().getEngineByName("ECMAScript")
.eval(script, bindings);
This is a relatively simplistic solution as you don't mention any other constraints. wait() causes the thread to block, which would not be acceptable in all environments. There is also no easy way to identify what threads are waiting on the Pause instance if you want to run scripts concurrently.
Note: the InterruptedException on await() should be handled either by the caller or by doing something more sensible in await().
I have a implemented a listener that notifies if we receive a new file in a particular directory. This is implemented by polling and using a TimerTask.
Now the program is so set up that once it receives a new file it calls another java program that opens the file and validates whether it is the correct file. My problem is that since the polling happens a specified number of seconds later there can arise a case in which a file is being copied in that directory and hence is locked by windows.
This throws an IOException since the other java program that tries to open it for validation cannot ("File is being used by another process").
Is there a way I can know when windows has finished copying and then call the second program to do the validations from java?
I will be more than happy to post code snippets if someone needs them in order to help.
Thanks
Thanks a lot for all the help, I was having the same problem with WatchEvent.
Unfortunately, as you said, file.canRead() and file.canWrite() both return true, even if the file still locked by Windows. So I discovered that if I try to "rename" it with the same name, I know if Windows is working on it or not. So this is what I did:
while(!sourceFile.renameTo(sourceFile)) {
// Cannot read from file, windows still working on it.
Thread.sleep(10);
}
This one is a bit tricky. It would have been a piece of cake if you could control or at least communicate with the program copying the file but this won't be possible with Windows I guess. I had to deal with a similar problem a while ago with SFU software, I resolved it by looping on trying to open the file for writing until it becomes available.
To avoid high CPU usage while looping, checking the file can be done at an exponential distribution rate.
EDIT A possible solution:
File fileToCopy = File(String pathname);
int sleepTime = 1000; // Sleep 1 second
while(!fileToCopy .canWrite()){
// Cannot write to file, windows still working on it
Sleep(sleepTime);
sleepTime *= 2; // Multiply sleep time by 2 (not really exponential but will do the trick)
if(sleepTime > 30000){
// Set a maximum sleep time to ensure we are not sleeping forever :)
sleepTime = 30000;
}
}
// Here, we have access to the file, go process it
processFile(fileToCopy);
I think you can create the File object and then use canRead or canWrite to know whether file ready to be used by the other java program.
http://docs.oracle.com/javase/6/docs/api/java/io/File.html
Other option is to try to Open file on first program and if it throws the exception then dont call the other java program. But I ll recommend the above 'File option.
I'm creating a Java application that will do some processing then needs to display a message to give the user feedback.
However, it appears to be incredibly slow - taking over two seconds to return.
I stripped the source down to the apparent culprit, and here is the code used:
package SwingPlay;
import javax.swing.JFrame;
public class Dialog
{
public static void main( String[] args )
{
JFrame frame = new JFrame( "DialogDemo" );
}
}
I'm executing this from the command line with:
java -classpath . SwingPlay.Dialog
As you can see - I'm doing nothing but create a JFrame, not even displaying it.
In case it is relevant, here is my java -version output:
java version "1.6.0_11"
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)
And this is (currently) running against Win XP SP2.
So, first question: Why is it so slow?
More importantly, I just want a simple message (GUI, not cmdline) to be displayed without delay - can anyone provide some code to do this?
Update:
A bit of background might be helpful:
I am creating an application which will have many 'heads' (i.e. different user interfaces all using the same core classes to do the complex parts).
I currently have a pure command line head which works fine - responds straight away.
I will also have a standard application with a regular point & click GUI, and don't foresee problems with this bit.
What I am currently working on is a hybrid of these two - it will be launched from a Run box (or similar launcher), possibly with arguments, and only needs to respond with, effectively, a status message, that can be dismissed with a key press.
This latter one is where the question is focused.
Whilst I am not opposed to using my existing command line version with shell scripts (though didn't think it would be necessary!), the existing answers seem to suggest that things are not running as fast for me as they are for others - one example takes 1460ms for me, versus 70ms - a significant difference.
The reason for the delay it because Java is an interpreted language and it takes time to start a new JVM ( the interpreter )
Actually creating the frame takes less than a few ms ( about 70 ms in my machine ).
If this is going to be used within a Java app, you don't need to worry about it. It will be almost instantaneous ( you should use JDialog or JOptionPane for this )
If this is NOT going to be used inside a Java app, and 2 secs it too much ( and I think it is too much ) you should consider another tool for the job.
Here's how I measure the time in your code:
import javax.swing.JFrame;
public class Dialog {
public static void main( String[] args ) {
long start = System.currentTimeMillis();
JFrame frame = new JFrame( "DialogDemo" );
System.out.println( "Took: " + ( System.currentTimeMillis() - start ) );
}
}
I would use a JOptionPane to show the message. Here's a simple example:
import javax.swing.*;
public class OptionDemo {
public static void main(String[] args) throws Exception {
JOptionPane.showMessageDialog(null, "Hello World");
}
}
I'm afraid I can't explain the delay you're experiencing though. On my system, your code snippet runs in 500 milliseconds.
Java is the wrong tool for this. Setting up the JVM involves a lot of stuff happening in the background before the first line of Java code can be executed, and there's really no way to get around it.
Also it would be a lot faster to create an AWT Window (or maybe a Frame) instead of a JFrame because the latter has to pull in a gazillion of additional class files.
Do you NEED to use java to display the message box? IF the box is coming from outside of your application, then you might want to use something else to generate a dialog.
To make a native windows app that just shows a message box from a command line string would only take a few hours at most. Most of the common scripting languages should have ways to do it too. here's an example from some guy through javascript via command line:
http://www.snee.com/bobdc.blog/2009/01/displaying-a-message-box-from.html
Oh, and if you don’t really need to show the dialog from Java you could look into using KDialog (or it’s GNOME counterpart) or something similar.
You could use the JOptionDialog
JOptionPane.showMessageDialog([parent frame], [message], [title], JOptionPane.MESSAGE_TYPE);
Since you're interested in speeding this up, and since most of the overhead seems to be JVM startup overhead, check out Nailgun which aims to address slow JVM startup by keeping a JVM running in the background all the time. In your case, after one run the Swing library too will end up being cached (and hopefully after a few more runs JITed too), further reducing the overhead.
However this approach will lead to increased memory usage due to the background JVM and also cause other problems since it may not be straightforward to determine when to shut it down.
What you're probably looking for is the new SplashScreen functionality in Java 6. Instead of having to wait for the JVM to load (there's always a cost to load any VM), this will load a screen beforehand.
Have you tried running it through a profiler like NetBeans? If there's a bottleneck deep inside the standard library, that's a good way to find it.