I am aware we can use ScriptEngineManager to execute scripts for example: java script.
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
public class Test {
public static void main(String[] args) throws Exception{
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
}
}
But this is a very trivial example and I am not sure in what real scenarios ScriptEngineManager can be used? Please elaborate.
Let me try to answer this from my project standpoint.
We have a framework that will make outbound calls and allow the integrators to extract the portions from json response and map it into internal data model.
This is completely driven by metadata, integrator uses the jsonpath (similar to xpath but for json ) to specify what to extract and what to map it to.
But there are times, where the integrator want to specify some of these conditionally.
For example, if the json value extracted is null, I want model to have 0.
If the array length is 0, then i want to use certain value.
We have exposed these logic as javascript. We execute the javascript using this engine to find out what the inetgrator wanted to do with the data ( basically we execute the script provided by integrator on the data obtained and set that value on the model, which eventually gets persisted )
Hope this answers your question.
There are many possible uses. For example: automation. The Microsoft Office programs and also Adobe Photoshop can run scripts to automatically execute functions of the program. You could use the Java script engine API for something similar in a Java application.
I used it once in a project where our software had to do some complex data processing. Certain parts of the processing could be customized by running a script. The advantage of this was that the script could be modified easily; if we would have written the custom processing in Java that would mean that every time when some small change was necessary, we would have to make a whole new build of the system.
Going by the differences, Java is statically typed, implying, the program written in Java, is first compiled and then run but in case of dynamically typed languages, like JavaScript and Python, we can execute even a part of the program for it is not compiled as a whole as such.
Coming to the question, suppose you have a server(eg: WildFly) on which you have deployed your application. Now building and hosting is a time intensive process, thus if you have to make any small change, you'll have to rebuild it and then again go through that time consuming process but if you could have used any dynamically typed language like JavaScript in place of it, it would have taken no time and in the next implementation, you would have been ready with the updated code. That's the main advantage of using JS and thus ScriptEngine was added in JSR.
Currently I'm working with JBoss to add ScriptEngine functionality to their WildFly server so have been spending time with it in the real time.
Related
I've been using Nashorn for awk-like bulk data processing. The idea is, that there's a lot of incoming data, coming row by row, one by another. And each row consists of named fields. These data are processed by user-defined scripts stored somewhere externally and editable by users. Scripts are simple, like if( c>10) a=b+3, where a, b and c are fields in the incoming data rows. The amount of data is really huge. Code is like that (an example to show the use case):
ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine(
new String[]{"-strict", "--no-java", "--no-syntax-extensions", "--optimistic-types=true"},
null,
scr -> false);
CompiledScript cs;
Invocable inv=(Invocable) engine;
Bindings bd=engine.getBindings(ScriptContext.ENGINE_SCOPE);
bd.remove("load");
bd.remove("loadWithNewGlobal");
bd.remove("exit");
bd.remove("eval");
bd.remove("quit");
String scriptText=readScriptText();
cs = ((Compilable) engine).compile("function foo() {\n"+scriptText+"\n}");
cs.eval();
Map params=readIncomingData();
while(params!=null)
{
Map<String, Object> res = (Map) inv.invokeFunction("foo", params);
writeProcessedData(res);
params=readIncomingData();
}
Now nashorn is obsolete and I'm looking for alternatives. Was googling for a few days but didn't found exact match for my needs. The requirements are:
Speed. There's a lot of data so it shall be really fast. So I assume as well, precompilation is the must
Shall work under linux/openJDK
Support sandboxing at least for data access/code execution
Nice to have:
Simple, c-like syntax (not lua;)
Support sandboxing for CPU usage
So far I found that Rhino is still alive (last release dated 13 Jan 2020) but I'm not sure is it still supported and how fast it is - as I remember, one of reasons Java switched to Nashorn was speed. And speed is very important in my case. Also found J2V8 but linux is not supported. GraalVM looks like a bit overkill, also didn't get how to use it for such a task yet - maybe need to explore further if it is suitable for that, but looks like it is complete jvm replacement and cannot be used as a library.
It's not necessary shall be javascript, maybe there are other alternatives.
Thank you.
GraalVM's JavaScript can be used as a library with the dependencies obtained as any Maven artifact. While the recommended way to run it is to use the GraalVM distribution, there are some explanations how to run it on OpenJDK.
You can restrict things script should have access to, like Java classes, creating threads, etc:
From the documentation:
The following access parameters may be configured:
* Allow access to other languages using allowPolyglotAccess.
* Allow and customize access to host objects using allowHostAccess.
* Allow and customize host lookup to host types using allowHostLookup.
* Allow host class loading using allowHostClassLoading.
* Allow the creation of threads using allowCreateThread.
* Allow access to native APIs using allowNativeAccess.
* Allow access to IO using allowIO and proxy file accesses using fileSystem.
And it is several times faster than Nashorn. Some measurements can be found for example in this article:
GraalVM CE provides performance comparable or superior to Nashorn with
the composite score being 4 times higher. GraalVM EE is even faster.
I have a Java application that I want to automate for testing. Unfortunately, the app window only registers as a SunAWTFrame, which means none of the controls are exposed to typical window analysis and automation tools.
My search has lead me to C# and utilising Java Access Bridge DLLS in a C# program to automate it.
Has anyone had any experience of this?
Oracle provides JavaAccessBridge (JAB) with some DLLS to help with this as I understand it after reading a few articles around the internet. There are some code examples but I'm really not groking it right now. By breaking it down, I think this is what needs to be achieved:
Import / load / parse the JAB dlls
Map functions in the JAB dll to methods / calls within my program
Have the Java application to automate run (with JAB enabled) and get handle of it to my program
Utilise the JAB functions to control the Java application
I don't know C# as well as I know Java, but that's not going to stop me.
If anyone can provide help, guidance, pointers or anything to get me started, that'd be truly awesome.
As of 2019 we have a great tool AccessBridgeExplorer created and open-sourced by google. It's a really good staring point that contains a WindowsAccessBridgeInterop project which encapsulates almost every JAB API into a class oriented, .NET friendly assembly.
One notable thing, AccessBridge.Initialize() must be called in WPF/WinForm UI thread or in your own messaging pump thread, otherwise some methods like AccessBridge.EnumJvms() will always return false/empty.
Building on Stackia's great tip to use Google's AccessBridgeExplorer, Here are some tips to get you going:
Download Access Bridge Explorer
Use the WindowsAccessBridgeInterop.dll in your own (WinForms not Console) project (Add> Project Reference> Select the DLL)
Create a new access bridge object
AccessBridge Java = new AccessBridge();
Initialize the Access Bridge object
Java.Initialize();
Call Application.DoEvents() - A hack to wait for Java.Initialize to complete (My simple understanding is Java Access Bridge Uses a hidden window or similar)
Application.DoEvents(); //this waits for Java Bridge to initilize ;)
Get the handle of the Java Window
(plenty of examples online of how to get a Window Handle in C#)
Get Access to the Java Object that represents the window:
Java.Functions.GetAccessibleContextFromHWND(Handle, out int vmid, out JavaObjectHandle javaObjectHandle);
Get AccessibleWindow Object for Window (so you can find its children)
AccessibleWindow win = Java.CreateAccessibleWindow(handle);
Come up with your own way to cycle through the children, and the childrens children until you find the object you are after:
//Similar to:
foreach(var child in win.GetChildren())
JavaObjectHandle? javaObject = Java.Functions.GetAccessibleChildFromContext(node.JvmId, parentJavaObject, child.GetIndexInParent());
//to get the label or title of the object:
child.GetTitle();
To Interact with an object (eg click a button), do similar to the following:
(please note where it says JavaObject - it means the child java object (eg. to click a button you need to get the JavaObject for that button using GetAccessibleChildFromContext as i mentioned above)
//Get Possible Actions
JavaAutomation.Java.Functions.GetAccessibleActions(VMID, JavaObject, out AccessibleActions accessibleActions);
foreach( var action in accessibleActions.actionInfo)
{
Log.Info($"DoAction: {action.name}");
}
AccessibleActionsToDo accessibleActionsToDo = new AccessibleActionsToDo();
accessibleActionsToDo.actions = accessibleActions.actionInfo;
accessibleActionsToDo.actionsCount = accessibleActions.actionsCount;
//Do Actions
JavaAutomation.Java.Functions.DoAccessibleActions(VMID, JavaObject, ref accessibleActionsToDo, out int failure);
Is there any way to include (or load) a external script to the script engine so that all the functions defined in the external script are available in the engine.eval() method ?
In our application we execute some java script code based on user inputs. When a user requests comes the application create a ScriptEngine instance and execute the appropriate javascript code based on the input parameters.
The problem here is there are some repeated functionality in the javascript. Consider an example :
Scenario 1 : Calculate distance when user input is decimal latitudes and longitudes
-> Here I can simply calculate and return the distance.
Scenario 2 : Calculate distance when user input is Degrees-Minutes-Seconds latitudes and longitudes.
-> Here convert the Degrees-Minutes-Seconds input into decimal latitudes and longitudes and then process same as Scenario 1.
As they are different scenario calculateDistance code is duplicated.
So is there any way I could have an script containing reusable functions and load it when I create a ScriptEngine instance.
Note : I am using Java 8 along with the bundled Nashorn JavaScript Engine.
Any ideas and/or suggestion ?
You can use the load() function in your javascript code (doc here). Someting like :
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval("load('myScript.js');");
It's an easy way, but doesn't fit for deployment (relative paths always change, ressources access may be different in your IDE, Jar, war...).
I personnaly use a very simple interface to provide the script content, which then came from a ressource, external file, DB... and then use the result in eval().
public interface ScriptLoader {
public String getScriptContent(String relativePath);
}
ScriptLoader loader;
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
engine.eval(loader.getScriptContent('myScript.js'));
If your script source is not dynamic, it may also be usefull to keep your engine's instance cached, as the first cold start/parsing can be very long.
Scenario
I'm working with a Java model built from scratch in Eclipse. What's important in this model is that we save our output to MATLAB (.mat) files. I constantly add new features, which require new fields that in turn will have to be exported to the .mat file at every iteration. Upon restarting a crashed simulation, I might have to import the .mat file. To export or import my .mat file I use JMatIO.
For example, if I would add a new field rho_m (a simple double) to my class CModel, I have to add to my Save() method:
mlModel.setField("rho_m", new MLDouble(null, new double[] {rho_m}, 1));
And to my Load() method:
rho_m = ((MLDouble)mlModel.getField("rho_m")).getReal(0);
Note that even though rho_m is a double, it needs to be treated as a double[] in JMatIO. This probably has something to do with MATLAB being orientated towards matrices and matrix operations.
Problem
Instead of doing this manually (prone to errors, annoying to maintain) I would like to automate this procedure. Ideally, I would like my IDE to detect all the fields in CModel and write the code based on the field's name and type. Is there any way to do this in Java/Eclipse?
Ideas so far
I have no formal training in low-level programming languages (yes, Java is low-level to me) and am still relatively new to Java. I do have some experience with MATLAB. In MATLAB I think I could use eval() and fieldnames() in a for loop to do what I mentioned. My last resort is to copy-paste the Java code to MATLAB and from there generate the code using a huge, ugly script. Every time I want to make changes to the model I'd rerun the MATLAB script.
Besides that idea I've found terms like UML, but do not have the background knowledge to figure out if this is what I'm looking for or not.
Any help, even if it's just a small push in the right direction, is greatly appreciated. Let me know if I need to further clarify anything.
Looking at your scenario, you are doing model-driven code generation, that is, you have a model and want to get some code generated according to your current model. Therefore, you need a model-driven code generator.
I lead the ABSE/AtomWeaver project, so I'll outline what you can do to get what you want using AtomWeaver (There are however other solutions like MetaEdit+, XText or Eclipse's own GMT/EMF sub-system).
AtomWeaver is an IDE where you can build a model and generate code from that model. You can change your model as many times you want and hit the "Generate" button to get an updated version of your code. ABSE is the name of the modeling method.
We don't need to go into details, but essentially ABSE follows a "building-block" approach. You create a Template that represents a feature or concept of your model. Then, you can associate a mini-code generator just to that concept. You can then "instantiate" and combine those building blocks to quickly build your models. Variables increase the flexibility of your models.
You can also change your models, or add new features ("blocks") and generate again. The generators are built using the Lua programming language, a very simple language with C-Like syntax.
The best way to understand the ABSE development method and the AtomWeaver IDE is to download the IDE and see the samples or try the tutorials. And yes, you can use AtomWeaver for free.
Hi
I want to write a program to be able to parse & execute some files
The file consists of some custom commands (I want to be able to define commands and appropriate methods so when program see that command it should execute the appropriate method)
It's grammar is not important for me; I just want to be able to define commands
Something like a simple and small interpreter written in java.
Is there any library for this purpose?
Or I need to write by myself?
Thanks
Java 6 (and newer) have this in the standard library: have a look at the API documentation of the package javax.script. You can use this to run scripts from your Java program (for example to automate your program) using any scripting language for which there is a plug-in engine available for the javax.script API. By default, support for JavaScript is supplied.
See the Java Scripting Programmer's Guide.
Simple example from that guide:
import javax.script.*;
public class EvalScript {
public static void main(String[] args) throws Exception {
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a JavaScript engine
ScriptEngine engine = factory.getEngineByName("JavaScript");
// evaluate JavaScript code from String
engine.eval("print('Hello, World')");
}
}
Have you considered looking at BeanShell?
Provides for having Java-like snippets interpreted at runtime.
If you need a bit more than that, then consider embedding e.g. JPython or another small interpreter. Just choose one that is JSR-233 compliant to get generic debugging support.
What you need is called "scripting engine". Quick search reveals Rhino. This is a good option cause it's JavaScript, and many people know JavaScript and there exists a certain amount of third-party extensions (libraries and code snippets) for it.
You could use ANTLR, but you will have to define a grammar (the parser will be generated for you).
Check this expression elevator example, it is similar to your problem, but instead of reading files it reads from the standard input.
If you choose ANTLR, take I look at ANTLRWorks, it is a GUI that will help with ANTLR development (I think it is also available as an Eclipse plugin).
I know this an old thread, but some time ago I've implemented a small interpreter for language similar with JavaScript (with more restrictions), the code is published in Github at https://github.com/guilhermelabigalini/interpreter
But it does support IF/CASE/LOOPS/FUNCTIONs, see below:
function factorial(n) {
if (n == 1)
return 1;
return n * factorial(n - 1);
}
var x = factorial(6);