Message-ID: <1947594132.2967.1369338054305.JavaMail.firstname.lastname@example.org> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_2966_312137958.1369338054305" ------=_Part_2966_312137958.1369338054305 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 lea=
Analogously to the expression evaluator, a ScriptEvaluator API exists that compiles = and processes a JavaTM "block", i.e. the body of a met= hod. If a return value other than "void" is defined, then the blo= ck 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 more about the
Analogously to the expression evaluator and the script evaluator, a ClassBodyEvaluato= r exists that compiles and processes the body of a JavaTM cl= ass, i.e. a series of method and variable declarations. If you define a con= tract that the class body should define a method named "main()", = then your script will look almost like a "C" program:
The "ClassBodyDemo" program (source code) demonstrates this:
The SimpleComp= iler compiles a single "compilation unit" (a.k.a. ".java= " file). Opposed to to normal JavaTM compilation, that comp= ilation unit may define more than one public class. Example:
It returns a
ClassLoader from which you can retrieve the cl=
asses that were compiled.