Interpreting JavaScript in Java with Rhino: pausing/resuming scripts - java

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().

Related

Simulate input in c++ and read it in JAVA?

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.

What is the correct way to use v8::Locker, and why must I use it?

I'm trying to embed v8 in an Android application using NDK.
I have a JNI module that looks something like this (JNI mapping code not shown):
#include <jni.h>
#include <android/log.h>
#include <v8.h>
using namespace v8;
static jlong getMagicNumber() {
HandleScope handle_scope;
Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
Handle<String> source = String::New("40 + 2");
Handle<Script> script = Script::Compile(source);
Handle<Value> result = script->Run();
context.Dispose();
return result->NumberValue();
}
The first time I run getMagicNumber, it correctly runs and returns 42. The second time I try to run it, it crashes.
Specifically, this ASSERT seen in v8's isolate.h fails:
// Returns the isolate inside which the current thread is running.
INLINE(static Isolate* Current()) {
Isolate* isolate = reinterpret_cast<Isolate*>(
Thread::GetExistingThreadLocal(isolate_key_));
ASSERT(isolate != NULL);
return isolate;
}
It sounds a lot like this problem, which suggests using v8::Locker to obtain "exclusive access to the isolate".
By adding a simple Locker l; to the top of getMagicNumber, the crash no longer occurs. Problems that fix themselves that easily tend to break themselves when I'm not paying attention.
I only have the most tenuous understanding of why this fixes my problem, and I'm getting compiler warnings that I'm using v8::Locker in a deprecated fashion. The recommended method is to provide it with a v8::Isolate as an argument to v8::Locker's constructor, but I have no idea how I'm supposed to "obtain" an isolate.
Ultimately: What is the proper way to solve this problem according to the current state of v8, and why?
As I understand it, a V8 isolate is an instance of the V8 runtime, complete with a heap, a garbage collector, and zero or more V8 contexts. Isolates are not thread-safe and must be protected via v8::Locker.
In general, to use V8 you must first create an isolate:
v8::Isolate* isolate = v8::Isolate::New();
Then, to use the isolate from any thread:
v8::Locker locker(isolate);
v8::Isolate::Scope isolateScope(isolate);
At this point the thread owns the isolate and is free to create contexts, execute scripts, etc.
Now, for the benefit of very simple applications, V8 provides a default isolate and relaxes the locking requirement, but you can only use these crutches if you always access V8 from the same thread. My guess is that your application failed because the second call was made from a different thread.
I am just learning V8 now, but I think you need to call:
v8::Locker locker(isolate);
This will create a stack allocated Locker object which will block the Isolate from being used on another thread. When the current function returns this stack object's destructor will be called automatically causing the Isolate to be unlocked.
The you need to call:
v8::Isolate::Scope isolateScope(isolate);
This sets the current thread to run this Isolate. Isolates can only be used on one thread. The Locker enforces this, but the Isolate itself needs to be configured for the current thread. This creates a stack allocated object which specifies which Isolate is associated with the current thread. Just like the Locker, when this variable goes out of scope (when the current function returns) the Scope destructor gets called to un-set the Isolate as the default. I believe this is needed because many of the V8 API calls need a reference to an Isolate, but don't take one as a parameter. Therefore they need one they can access directly (probably through per-thread variables).
All the Isolate::Scope class does is call isolate::Enter() in the constructor and isolate::Exit() in the destructor. Therefore if you want more control you can call Enter()/Exit() yourself.

In Java, how to log a message every time a given object's monitor is entered or exited?

I am trying to debug some C/Java bindings that use some custom refcounting/locking. I would like to have the JVM print a message every time a given object has its monitor entered or exited. Is there any way to do this? Basically, I want this:
synchronized(lock) {
...
System.out.println("hi");
...
}
to print this:
*** "lock" monitorenter
hi
*** "lock" monitorexit
I have looked at the XX options and found nothing. This is OpenJDK 6.
Good question. The only solution I could come up with is basically this:
Use a custom class-loader and preprocess the files with using a bytecode manipulation library such as ASM. (ASM has a good example of how to work with bytecode rewriting in class loaders.)
Then simply add a call to System.out.println before each monitorenter and monitorexit.
Thanks to the nice visitor pattern in the ASM library, this shouldn't be more than a screen or two of code.
Trying to debug a concurreny issue with creative uses of print statements is a losing battle, as your print statements could have their own concurrency bug and not print in the order you expect. Trying to debug or println your way out of a concurreny bug may sound good, but I don't think it will get you the result you want. You need to use careful thinking and logic to reason that your code is correct (more Computer Science than Software Engineering).
Concurrency issues are very hard. If you haven't read Concurrency in Practice, make sure you go read it. Then look at all the possible ways that your synchronized block can be reached, all the things it can change that are outside the scope of the lock, etc.
This would be a perfect situation to use dTrace.
Unfortunately that requires Solaris or OS X.
Fortunately OpenSolaris can still be downloaded and run in a virtual machine. It runs best in VirtualBox.
I don't believe there is a way to bind to a "locking" event in java. But you can look into java.lang.management for various locking information. For example, there is ThreadMXBean.findDeadlockedThreads()
Unless you write your own locking class (or modify the existing one) my guess is that it would be rather difficult to do what you want, specially if you are using a synchronized block over a monitor object and not a Lock class. However you can use the jstack command supplied with the JDK to analyze your process at runtime, check here for the man page, and also there is the JVM option -XX:-PrintConcurrentLocks for printing your locks if you stop your JVM process using Ctrl-Break (more options here).
I will suggest you to implement existing implementation of Lock class or implement one of you own (http://download.oracle.com/javase/tutorial/essential/concurrency/newlocks.html).
Now you can override the lock and unlock method. So instead of using synchronized methods/statements make use of this facility and in lock/unlock methods put your logging :)

JACOB doesn't release the objects properly

I have an eclipse plugin, which connects to a COM component using Jacob. But after I close the plugin entirely, the .exe file stays hanging in Windows processes.
I use ComThread.InitMTA(true) for initialization and make sure that SafeRelease() is called for every COM object I created before closing the app and I call ComThread.Release() at the very end.
Do I leave something undone?
Some further suggestions:
Move the call to ComThread.Release() into a finally block, otherwise the thread will remain attached if an exception is thrown.
Check that you are calling ComThread.InitMTA and ComThread.Release in every thread that uses a COM object. If you forget to do this in a worker thread then that thread will be attached automatically and never detached.
Avoid InitSTA and stick to InitMTA. Even when there is only one thread using COM, I have found InitSTA to be flaky. I don't know how JACOB's internal marshalling mechanism works but I have ended up with "ghost" objects that appear to be valid but do nothing when their methods are invoked.
Fortunately I have never yet needed to modify any code in the JACOB library.
I ran into this issue myself. After messing with initMTA,etc. I found a simple fix - when you start Java add the following to your command line:
-Dcom.jacob.autogc=true
This will cause the ROT class to use a WeakHashMap instead of a HashMap and that solves the problem.
You can also use -Dcom.jacob.debug=true to see lots of informative debug spew and watch the size of the ROT map.
Had the same problem with TD2JIRA converter. Eventually had to patch one of the Jacob files to release the objects. After that all went smooth.
The code in my client logout() method now looks like this:
try {
Class rot = ROT.class;
Method clear = rot.getDeclaredMethod("clearObjects", new Class[]{});
clear.setAccessible(true);
clear.invoke(null, new Object[]{});
} catch( Exception ex ) {
ex.printStackTrace();
}
The ROT class wasn't accessible initially, AFAIR.
Update
The correct way to release resources in Jacob is to call
ComThread.InitSTA(); // or ComThread.InitMTA()
...
ComThread.Release();
Bad thing though is that sometimes it doesn't help. Despite Jacob calls native method release(), the memory (not even Java memory, but JVM process memory) grows uncontrollably.

Calling function when program exits in java

I would like to save the programs settings every time the user exits the program. So I need a way to call a function when the user quits the program. How do I do that?
I am using Java 1.5.
You can add a shutdown hook to your application by doing the following:
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
public void run() {
// what you want to do
}
}));
This is basically equivalent to having a try {} finally {} block around your entire program, and basically encompasses what's in the finally block.
Please note the caveats though!
Adding a shutdown hook addShutdownHook(java.lang.Thread) is probably what you look for. There are problems with that approach, though:
you will lose the changes if the program aborts in an uncontrolled way (i.e. if it is killed)
you will lose the changes if there are errors (permission denied, disk full, network errors)
So it might be better to save settings immediately (possibly in an extra thread, to avoid waiting times).
Are you creating a stand alone GUI app (i.e. Swing)?
If so, you should consider how you are providing options to your users how to exit the application.
Namely, if there is going to be a File menu, I would expect that there will be an "Exit" menu item.
Also, if the user closes the last window in the app, I would also expect it to exit the application.
In both cases, it should call code that handles saving the user's preferences.
Using Runtime.getRuntime().addShutdownHook() is certainly a way to do this - but if you are writing Swing applications, I strongly recommend that you take a look at JSR 296 (Swing Application Framework)
Here's a good article on the basics: http://java.sun.com/developer/technicalArticles/javase/swingappfr/.
The JSR reference implementation provides the kind of features that you are looking for at a higher level of abstraction than adding shutdown hooks.
Here is the reference implementation: https://appframework.dev.java.net/

Categories