Date post: | 31-Dec-2015 |
Category: |
Documents |
Upload: | jemima-wilkerson |
View: | 222 times |
Download: | 3 times |
How Java becomes agile riding Rhino
Xavier CasellatoVP of engineering, Liligo.com
Let the ride begin !
Change request : Simon says
We need a white rectangle
We need a white rectangle The rectangle
should be blue
The rectangle should be blue
The rectangle should be blue when it’s sunny
and white when it rains
The rectangle should be blue when it’s sunny
and white when it rains
The rectangle must be yellow if temperature is less than 23°
The rectangle must be yellow if temperature is less than 23°
Who decided it must be a rectangle ?
Who decided it must be a rectangle ?
Didn’t we say it should be orange
?
Didn’t we say it should be orange
?
The border should be
yellow except if it’s sunny
The border should be
yellow except if it’s sunny
The rectangle is circle if
temperature is less than 0° and it’s
sunny
The rectangle is circle if
temperature is less than 0° and it’s
sunny
The circle must be green
The circle must be green
The rectangle is blue and green every
Monday
The rectangle is blue and green every
Monday
Tuesday we want a circle but only if it
rains
Tuesday we want a circle but only if it
rains
Why don’t we do a triangle ?
Why don’t we do a triangle ?
Flexibility is required
Many inputs affect the final result Many rules can be applied Rules change often
Modeling flexibility
Database needs a modelXML needs a DTDHome made data storage ! Are you sure it’s a
solution ?
None of these solutions are really flexible.
Stuck !?
Constraints
Application behavior must be modified quickly Deploying compiled code is time consuming Compiled code required IT resources
Needs
Empower business decision Reduce change requests delay Introduce customizable business logic in
application
Rhino, inside the beast
Rhino History
Netscape project started in 1997 First Release in 1998 Embedded in JVM since Java Standard Edition 1.6
What is Rhino ?
Full-java API Rhino contains
All the features of JavaScript 1.6 A JavaScript shell for executing JavaScript
scripts A JavaScript compiler to transform JavaScript
source files into Java class files A JavaScript debugger for scripts executed with
Rhino
Embed and execute JavaScript codesinside a Java application
General concepts
Context stores information about the execution
environment of a script. Scope
set of JavaScript objects Host
Host objects implement special JavaScript features like dynamic properties.
How it works
Basic Rhino Execution sequence
// Create ContextContext cx = Context.enter();// Initialize standard objectsScriptableObject scope = cx.initStandardObjects();// Build scopescope.put(“input”,input1);// use Script…// Exit Contextcx.exit();
// Create ContextContext cx = Context.enter();// Initialize standard objectsScriptableObject scope = cx.initStandardObjects();// Build scopescope.put(“input”,input1);// use Script…// Exit Contextcx.exit();
Access javascript variables with java
Object x = scope.get("x", scope); if (x == Scriptable.NOT_FOUND) {
System.out.println("x is not defined."); } else {
System.out.println("x = " + Context.toString(x));}
Object x = scope.get("x", scope); if (x == Scriptable.NOT_FOUND) {
System.out.println("x is not defined."); } else {
System.out.println("x = " + Context.toString(x));}
“X” variable is read from script
Using javascript function in Java
Object fObj = scope.get("f", scope); if (!(fObj instanceof Function)) { System.out.println("f is undefined or not a function."); } else { Object functionArgs[] = { "my arg" }; Function f = (Function)fObj; Object result = f.call(cx, scope, scope, functionArgs); String report = "f('my args') = " + Context.toString(result); System.out.println(report); }
Object fObj = scope.get("f", scope); if (!(fObj instanceof Function)) { System.out.println("f is undefined or not a function."); } else { Object functionArgs[] = { "my arg" }; Function f = (Function)fObj; Object result = f.call(cx, scope, scope, functionArgs); String report = "f('my args') = " + Context.toString(result); System.out.println(report); }
Call expects two scriptable objects :
scope to execute the function relative to
JavaScript this object
Create java object in Javascript
String script = "var x =5; System.out.println(x);";
result = cx.evaluateString(scope, script, “<cmd>", 1, null);
String script = "var x =5; System.out.println(x);";
result = cx.evaluateString(scope, script, “<cmd>", 1, null);
“X” variable is declared in the JavaScript and console output is called from JavaScript.
You can access to native java classes from JavaScript.
Sharing java object with javascript
Object wrappedOut = Context.javaToJS(System.out, scope); ScriptableObject.putProperty(scope, "out", wrappedOut); Object wrappedOut = Context.javaToJS(System.out, scope); ScriptableObject.putProperty(scope, "out", wrappedOut);
Object is wrapped as a scope element.
Method calls uses reflection.
Host object
Host is a java class that can be manipulated as a JavaScript prototype.
Naming pattern should be applied to the methods Constructor Getter and Setter Functions
Declare a constructor for Host object
Host class signature
public class Counter extends ScriptableObject { public void jsConstructor(int a) {
…
}
Javascript
…
var counter = new Counter(7);
…
Getter and setter syntax
Host class signature
public int jsGet_field()
{
return field;
}
public void jsSet_field(int value)
{
field = value;
}
Javascript
…
var x =counter.field;
counter.field = x;
…
Host object : functions
Host class signature
public int jsFunction_increment()
{
field++;
}
Javascript
…
counter.increment();
…
Declare host object
ScriptableObject.defineClass(scope, Counter.class);
Host object definition must be declared in the scope.
The line above declares the counter class a JavaScript prototype.
Java class becomes a JavaScript prototype.
You can refer it using as a JavaScript object.
Scope types
Shared scopeUse it to share object defined in a scope without modifying their values between to concurrent scope execution.
Sealed shared scopeObject sealed properties can not be added/deleted to the object and the existing object properties can not be changed
Dynamic scopeAllow to enclose common functions and shared objects in a multi-threaded environment.
Rhino performances
Execution time almost 3 times faster with compiled code
Even compiled code is almost 10 times slower than java compiled code.
Performances concerns
There is a huge difference between evaluated script and compiled ones.
To keep good performances you must compile your script before execution and focus the Rhino usage to the relevant code part.
Rhino in action
Identify use cases
Identify logical components which requires adaptive behavior.
Need to have a flexible behavior
Identify complex rules Various input data and outputs
Estimate execution frequency JavaScript is slower than compiled Java
Embedding strategy
JAVA JAVA
Script Script
Java Native classes
Function Host objects
Out-of-box integration
Deep integration
Storing the script
Flexibility works with a correct storage support !
Don’t miss your target !
SCRIPT MUST BE EASILY MANAGEABLE
Customizable function
JAVA BEANJAVA BEAN
Javascript function
Script Source is an attribute of the object.
Script execution is a bean method.
Customizable process
Java bean initial state
(Host)
Java bean initial state
(Host)
Bean Manager(Context)
Bean Manager(Context)
JavaScript function
JavaScript function
Java beannew state
Host object
Java beannew state
Host object
State change
Rhino Use case : Workflow
Workflow Manager ( Context manager )
Workflow Manager ( Context manager )
Workflow taskHost object
Workflow taskHost object
Workflow definition
Workflow definition
Workflow taskHost object
Workflow taskHost object
Liligo use case 1 : Categorization
Storage processStorage processScript
Storage rules
ScriptStorage
rules
SkiSki Week-endsWeek-ends CruisesCruises
Package offersPackage offers
Liligo use case 2 : Flexible processing
Data processingScript
Data processingScript
Data Host object
Data Host object
HTMLHTMLXMLXML CSVCSV Text fileText file
A few more words
J2SE integrates a higher level of integration which allows you to decide the scripting engine you want to use.
JRuby, Jython are alternative to JavaScript and Rhino.
Helma framework embeds Rhino to provide a full JavaScript server-side framework.
To learn more
www.mozilla.org/rhino/ https://scripting.dev.java.net/ http://java.sun.com/developer/technicalArticles/
J2SE/Desktop/scripting/
Conclusion
Rhino is a really powerful tool.
Rhino is easy to integrate especially since the J2SE1.6.
Performance concerns imply to clearly identify the right embedding strategy.
Properly used in your application it will convert a monolithic java application
into a customizable user-oriented one !!!
Any questions ?
“ and don’t hesitate to contact me with questions or if you were interested in working in our
team: [email protected] ”