How do I call and initialize the Java Access Bridge API? - java

The Java Access Bridge API documentation states:
The Java Access Bridge API calls are contained in AccessBridgeCalls.h
and to use them, you must also compile the file AccessBridgeCalls.c,
which acts as the interface between your application and
WindowsAccessBridge.dll.
But when I tried to create a dll out of AccessBridgeCalls.h & AccessBridgeCalls.c, it says missing AccessBridgeDebug.h file.
How do I call the initiateAccessBridge() method? I am looking to perform tasks similar to JavaMonkey.exe, such as identifying components in a Java Swing application.
When I call isJavaWindow(int) from the Access Bridge, it always returns false for all handlers.

JAB relies on the Windows Messaging mechanism to perform inter-process communications. You have to set up a thread to run message pump loop and call initiateAccessBridge() in that thread, otherwise some methods like isJavaWindow() will always return false.
Here is a C# reference:
var accessBridge = new AccessBridge();
// Use WPF UI thread if there is one
var messageLoopDispatcher = Application.Current?.Dispatcher;
if (messageLoopDispatcher == null)
{
var readyEvent = new ManualResetEvent(false);
var messageLoopThread = new Thread(() =>
{
messageLoopDispatcher = Dispatcher.CurrentDispatcher;
readyEvent.Set();
Dispatcher.Run();
});
messageLoopThread.SetApartmentState(ApartmentState.STA);
messageLoopThread.Start();
readyEvent.WaitOne();
}
messageLoopDispatcher.Invoke(() =>
{
accessBridge.Initialize();
});

Related

Java Application Window not recognized as java window in C# InterOp

I am using Java Access Bridge API with interop in C#. When trying to create a new AccessibleWindow with the hwnd obtained from the user32.dll method GetForegroundWindow(), it does not recognize the window as a java window, returning null. IsJavaWindow() returns false, but calling it a second time returns true. I tested this out with the example "SwingSet2" application.
public void Initialize()
{
if(!Initialized)
{
accessBridge = new AccessBridge();
var hwnd = WindowsNativeMethods.GetForegroundWindow();
var window = accessBridge.CreateAccessibleWindow(hwnd);
window.AccessBridge.Initialize();
window.AccessBridge.Functions.GetAccessibleContextFromHWND(hwnd, out vmId, out mainContext);
Initialized = true;
}
}
I am also using code from this repo: Google Access Bridge
Initialize() or the initialization code in general needs to called in a UI thread or a message pumping thread.
Using the IntPtr from GetForegroundWindow() or GetActiveWindow() always returns false in IsJavaWindow(), but using FindWindow() works from user32.dll's methods.

embedded Nashorn - sandboxing execution

I would like to get a clear answer on how to Sandbox execution Nashorn within a Java Application.
I have seen 'similar questions' (which I will refer to) but ultimately none of the answer seem to address my concerns.
Let me start with definitions.
Assume we start with this:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
engine.put("map",new HashMap());
engine.eval(jsCode); // jsCode can access 'map' only.
By "Sandboxing" I mean ensure that the JavaScript must not access any java object except the one added in the scope.
so the following evals should be fine.
engine.eval("map.toString()");
engine.eval("map.size()");
engine.eval("map.put('name','jeff'); ");
engine.eval("map.getClass()");
But the following evals will not:
engine.eval("var m = new java.util.HashMap();"); // <-- stop accessing Java
engine.eval("map.getClass().forName('java.io.File'); "); // stop. it's trying to be sneaky
Finally, I am not concerned about this:
engine.eval("while(1) {;}"); // this is impossible to detect. Maybe it's possible for this simple case... but sneaky users could make it impossible to detect... anyway this is not what I am asking. I am only concerned on accessing java objects.
So by sandboxing I intend to prevent jsCode to access java objects that I don't define.
I saw that this might be a potential solution:
jdk.nashorn.api.scripting.NashornScriptEngineFactory factory = new jdk.nashorn.api.scripting.NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new jdk.nashorn.api.scripting.ClassFilter() {
public boolean exposeToScripts(String s) {
return false;
}
});
but is it 'safe' to access a package beginning with jdk.* directly ?
Another approach I saw is even more mysterious:
final ScriptEngine engine =
new NashornScriptEngineFactory().getScriptEngine(new String[] { "--no-java" });
I saw that one here:
Safely re-using sandboxed Nashorn containers
Can somebody let me know ?
You can use jdk.nashorn.api.scripting.* API if that would help in your application. javadoc for the same is here -> https://docs.oracle.com/javase/8/docs/jdk/api/nashorn/
And yes, --no-java is the option for preventing java package access from script code.

ScriptEngine clear and dispose

My application uses a ScriptEngine to offer plugin-ability to my end-users.
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
Whenever a user makes changes to his script, then the application replaces the engine instane by a new instance.
String newScript = ...;
engine = engineManager.getEngineByName("nashorn");
engine.eval(newScript);
Two closely related questions:
Should I try to reuse engines and perform some kind of clear() on them ?
If I just replace my engine with a new instance, should I dispose the previous instance in some way, to avoid memory leaks ? (e.g. I can imagine that the user could manage to create a script that starts a thread.)
The problem is, I cannot find any method that looks like a clear() or a dispose(). Does that mean that my current approach is correct ?
You can use a single engine instance but use separate Bindings objects. Bindings acts as a top-level program environment, so if you want to evaluate a script into what is basically a "new global scope" then you could do that. Look into javax.script API docs on how to do this. You can either use ScriptEngine.eval that takes a Bindings as second argument or the one that takes ScriptContext as second argument.
Even if there's no script code surviving from the previous evaluation, you'll save some initialization time as the script engine will already have predefined various JavaScript data-holder classes and property maps ("hidden classes").
Also: yes, everything is garbage collected. There's no need for an explicit "disposal" API.
I just wanted to share what I tested myself. It makes perfect sense, but for those still in doubt: Created threads do continue to run if you just replace engine instances:
public static void main(String[] args) throws ScriptException {
ScriptEngineManager manager = new ScriptEngineManager();
String script =
"new java.lang.Thread(function() {\n" +
" for(;;) {" +
" print('Here\\'s Johnny !');" +
" java.lang.Thread.sleep(1000);" +
" }\n" +
"}).start();";
ScriptEngine engine = manager.getEngineByName("nashorn");
try {
engine.eval(script);
} catch (ScriptException e) {
e.printStackTrace();
}
// replace engine
engine = manager.getEngineByName("nashorn");
engine.eval("print('please, make it stop!!!');");
// please collect !!!
System.gc();
}
Output:
Here's Johnny !
please, make it stop!!!
Here's Johnny !
Here's Johnny !
Here's Johnny !
...
I guess that the garbage collector can clean the scripts, but not their actions outside their context. I think created threads are not even linked to the scripts in any way (i.e. outside their scope). So, I think it's just impossible for the jvm to detect or decide that these threads are linked to a replaced script and may or may not be stopped.
But this leads us too far for one stackoverflow question. Let's just focus on the ability to dispose/clear the bindings (i.e. ScriptContext).
Block java threads in nashorn scripts:
A possible solution, is to narrow down the available functionality. Here follow a couple of ways to avoid the creation of threads:
The following disables all java functionality:
// the option -nj is short for --no-java
ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine("-nj");
But you can also disable specific classes, using a ClassFilter.
ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine((className) -> {
if ("java.lang.Thread".equals(className)) return false;
if ("java.lang.Runnable".equals(className)) return false;
if ("java.util.Timer".equals(className)) return false;
if (className.startsWith("java.util.concurrency")) return false;
if (className.startsWith("javafx")) return false;
if (className.startsWith("javax.swing")) return false;
if (className.startsWith("java.awt")) return false;
return true;
});
Note: as soon as you define a ClassFilter also reflection classes are blocked automatically. So, you don't have to block those packages explicitly.

Is there a language-independent way to add a function to JSR223 scripting bindings?

The JSR223 Bindings class allows you to expose arbitrary Java objects to scripting languages. But they have to be objects. I would like to define a function quit() that can be called from the scripting environment that turns into quitObject.run() in Java. But JSR223 doesn't define the concept of a function object. Is there a language-independent way to do the following in Javascript, namely to take a Runnable() and create a function in the scripting environment?
static private Object asFunction(ScriptEngine engine, Runnable r)
throws ScriptException
{
final Bindings bindings = engine.createBindings();
bindings.put("r", r);
return engine.eval(
"(function (r) { var f = function() { r.run(); }; return f;})(r)",
bindings);
}
Runnable quitObject = /* get/create a Runnable here */
Bindings bindings = engine.createBindings();
bindings.put("quit", asFunction(engine, quitObject));
With the builtin Javascript support for JSR223 this creates a sun.org.mozilla.javascript.internal.InterpretedFunction which does what I want. But it obviously won't work in Jython or whatever, and I'd like to make this language-independent.
I don't want my script users to have to type quitObject.run() as that's clumsy, and I don't want to parse script input to find quit() as it could be buried within other code.
If you look at javascript engine source code you'll find how oracle/sun implemented 2 functions (print, and println) which are magically (or not so magically) present when you fire up your engine.
Those function are 'scripted' , which is more or less what you did.
What I would do is : load and evaluate a bootstrap.[language_extension] before evaluating any other input in the new context.
You could easily create such scripts for each language you intend to support.

Bind method call in JavaScript script in Java Scripting

Suppose I have a Javascript file
function js_main(args){
/* some code */
var x = api_method1(some_argument);
/* some code */
}
And I try to run it with javax.scripting the usual way
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
engine.eval(...);
Now the I'd like to handle the call to api_method1 in Javascript with my Java class. I'd like to have some kind of mapping/binding of calls i.e. each time the script calls api_method1(arg) a method
public Object api_method1(Object arg){ ... }
(placed in the same class as the engine) would be called.
Can I achieve this?
use engine.createBindings() to make a Bindings object;
put an object exposing your method into the bindings with some name:
Bindings b = engine.createBindings();
b.put("api", yourApiObject);
engine.setBindings(b, ScriptContext.ENGINE_SCOPE);
Then in JavaScript there'll be a global "api" object you can call:
api.method1( "foo", 14, "whatever" );
The facility is easy to use, but be careful with what you pass back and forth; it doesn't do that much to convert JavaScript types to Java types.

Categories