Message-ID: <57331672.1631.1411265891909.JavaMail.email@example.com> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_1630_482219350.1411265891909" ------=_Part_1630_482219350.1411265891909 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
Say you build an e-commerce system, which computes the shipping cost for= the items that the user put into his/her shopping cart. Because you don't = know the merchant's shipping cost model at implementation time, you could i= mplement a set of shipping cost models that come to mind (flat charge, by w= eight, by number of items, ...) and select one of those at run-time.
In practice, you will most certainly find that the shipping cost models = you implemented will rarely match what the merchant wants, so you must add = custom models, which are merchant-specific. If the merchant's model changes= later, you must change your code, re-compile and re-distribute your softwa= re.
Because this is so unflexible, the shipping cost expression should be sp= ecified at run-time, not at compile-time. This implies th= at the expression must be scanned, parsed and evaluated at run-time, which = is why you need an expression evaluator.
A simple expression evaluator would parse an expression and create a &qu= ot;syntax tree". The expression "a + b * c", for example, wo= uld compile into a "Sum" object who's first operand is parameter = "a" and who's second operand is a "Product" object who'= s operands are parameters "b" and "c". Such a syntax tr= ee can evaluated relatively quickly. However, the run-time performance is a= bout a factor of 100 worse than that of "native" JavaTM code executed directly by the JVM. This limits the use of such an express= ion evaluator to simple applications.
Also, you may want not only do simple arithmetics like "a + b * c %= d", but take the concept further and have a real "scripting"= ; language which adds flexibility to your application. Since you know the J= avaTM programming language already, you may want to have a synta= x that is similar to that of the JavaTM programming language.
All these considerations lead to compilation of JavaTM code a= t run-time, like some engines (e.g. JSP engines) already do. However, compi= ling JavaTM programs with SUN's JDK is a relatively resource-int= ensive process (disk access, CPU time, ...). This is where Janino comes int= o play... a light-weight, "embedded" JavaTM compiler t= hat compiles simple programs in memory into JavaTM byte= code which executes within the JVM of the running program.
OK, now you are curious... this is how you use the ExpressionEvaluator:
Notice: If you pass a string literal as the expression,= be sure to escape all JavaTM special characters, especially bac= kslashes.
Compilation of the expression takes 670 microseconds on my machine (2 GH= z P4), evaluation 0.35 microseconds (approx. 2000 times faster than compila= tion).
There is a sample program "ExpressionDemo" that you can use to=
play around with the
ExpressionEvaluator, or you can study ExpressionDemo's source code to learn about
Analogously to the expression evaluator, a ScriptEvaluator API exists that compiles and processes = a JavaTM "block", i.e. the body of a method. If a retu= rn value other than "void" is defined, then the block must return= a value of that type. Example:
As for the expression compiler, there is a demo program "ScriptDemo=
" for you to play with the
Check the source code of ScriptDemo to learn mor=
e about the
Analogously to the expression evaluator and the script evaluator, a ClassBodyEvaluator exists t= hat compiles and processes the body of a JavaTM class, i.e. a se= ries of method and variable declarations. If you define a contract that the= class body should define a method named "main()", then your scri= pt will look almost like a "C" program:
The "ClassBodyDemo" program (source cod= e) demonstrates this:
The SimpleCompiler compi= les a single "compilation unit" (a.k.a. ".java" file). = Opposed to to normal JavaTM compilation, that compilation unit m= ay define more than one public class. Example:
It returns a
ClassLoader from which you can retrieve the cl=
asses that were compiled.
To run this, type:
See Advanced for other ways of = using JANINO.