Janino 1.0.21

Janino, and embedded compiler for the JavaTM programming language.

See:
          Description

Packages
net.janino The classes in this package pose the core of the Janino JavaTM compiler.
net.janino.samples Sample applications for the Janino JavaTM compiler.
net.janino.tools Auxiliary command line tools related to JANINO.
net.janino.util Application-independent helper classes.
net.janino.util.resource Classes related to loading "resources".

 

Janino, and embedded compiler for the JavaTM programming language.

$Revision: 1.56 $

Contents

What is Janino?
Properties
Janino as an expression evaluator
Janino as a script evaluator
Janino as a simple compiler
Janino as a ClassLoader that loads JavaTM classes directly from source code
Janino as a class body evaluator
Janino as a command-line JavaTM compiler
Janino as an ANT compiler
Janino as a TOMCAT compiler
Who develops Janino?
Licensing
How is Janino developed?
Future directions
Examples
Download
Installation
Reporting bugs
Requesting support
Requesting new features
Subscribing to the "Janino users" newsletter
Links
Feedback
The name
Change Log
Trademark notice

What is Janino?

Janino is a compiler that reads a JavaTM expression, block, class body or source file, and generates JavaTM bytecode that is loaded and executed directly. Janino is not intended to be a development tool, but an embedded compiler for run-time compilation purposes, e.g. expression evaluators or "server pages" engines like JSP.

Properties

The major design goal was to keep the compiler small and simple, while partially sacrificing completeness. I don't like the idea of carrying around huge libraries for simple applications. See Parser for the list of implemented and missing language features.

Janino as an expression evaluator

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 implement a set of shipping cost models that come to mind (flat charge, by weight, 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 software.

Because this is so unflexible, the shipping cost expression should be specified at run-time, not at compile-time. This implies that 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 "syntax tree". The expression "a + b * c", for example, would 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 tree can evaluated relatively quickly. However, the run-time performance is about a factor of 100 worse than that of "native" Java code executed directly by the JVM. This limits the use of such an expression 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 Java programming language already, you may want to have a syntax that is similar to that of the Java programming language.

All these considerations lead to compilation of Java code at run-time, like some engines (e.g. JSP engines) already do. However, compiling Java programs with SUN's JDK is a relatively resource-intensive process (disk access, CPU time, ...).

This is where Janino comes into play... a leight-weight, "embedded" Java compiler that compiles simple programs in memory into Java bytecode which executes within the JVM of the running program. (See the source code of ExpressionEvaluator for an example.)

OK, now you are curious... this is how you use the ExpressionEvaluator:

      // Compile the expression once; relatively slow.
      ExpressionEvaluator ee = new ExpressionEvaluator(
          "c > d ? c : d",                           // expression
          Integer.TYPE,                              // expressionType
          new String[] { "c", "d" },                 // parameterNames
          new Class[] { Integer.TYPE, Integer.TYPE } // parameterTypes
      );

      // Evaluate it with varying parameter values; very fast.
      Integer res = (Integer) ee.evaluate(
          new Object[] {          // parameterValues
              new Integer(10),
              new Integer(11),
          }
      );
      System.out.println("res = " + res);

Compilation of the expression takes 670 microseconds on my machine (2 GHz P4), evaluation 0.35 microseconds (approx. 2000 times faster than compilation).

Janino as a script evaluator

Analogously to the expression evaluator, a script evaluator exists that compiles and processes a JavaTM "block", i.e. the body of a method. If a return value other than "void" is defined, then the block must return a value of that type. Example:

    System.out.println("Hello world");
    return true;
  

Janino as a class body evaluator

Analogously to the expression evaluator and the script evaluator, a class body evaluator exists that compiles and processes the body of a JavaTM class, i.e. a series of method an variable declarations. If you define a contract that the class body should define a method named "main()", then your script will look almost like a "C" program:

    import java.util.*;

    public static void main(String[] args) {
        Vector v = new Vector();
        for (int i = 0; i < args.length; ++i) {
            v.add(args[i]);
        }
        System.out.println("Command line args converted into vector!");
    }
  

Janino as a simple compiler

The SimpleCompiler compiles a single "compilation unit" (a.k.a. ".java" file). Opposed to to normal JavaTM compilation, that compilation unit may define more than one public class. Example:

    package my.pkg;

    import java.util.*;

    public class A {
        public static void main(String[] args) {
            B b = new B();
            b.meth1();
        }
    }

    public class B {
        void meth1() {
            System.out.println("Hello there.");
        }
    }
  

Janino as a ClassLoader that loads JavaTM classes directly from source code

The JavaSourceClassLoader extends JavaTM's java.lang.ClassLoader class with the ability to load classes directly from source code.

To be precise, it searches for a matching ".java" file in any of the directories specified by a given "source path", reads, scans, parses and compiles it and defines the resulting classes in the JVM. No intermediate files are created in the file system.

A BASH shell script named "bin/janino" is provided that wraps the JavaSourceClassLoader in a JAVAC-like command line interface:

    $ cat my/pkg/A.java
    package my.pkg;

    import java.util.*;

    public class A {
        public static void main(String[] args) {
            B b = new B();
            b.meth1();
        }
    }

    class B {
        void meth1() {
            System.out.println("Hello there.");
        }
    }
    $ type janino
    /usr/local/bin/janino
    $ janino my.pkg.A
    Hello there.
    $
  

Janino as a command-line JavaTM compiler

The Compiler class mimics the behavior of SUN's javac tool. It compiles a set of "compilation units" (i.e. JavaTM source files) into a set of class files.

The BASH script "bin/janinoc" implements a drop-in replacement for SUN's JAVAC utility:

    $ janinoc -sourcepath src -d classes src/com/acme/MyClass.java
    $ janinoc -help
    A drop-in replacement for the JAVAC compiler, see the documentation for JAVAC
    Usage:
      janinoc [ <option> ] ... <class-name> [ <argument> ] ...
    Options:
      -sourcepath <dir-list>    Where to look for source files
      -classpath <dir-list>     Where to look for class files
      -cp <dir-list>            Synonym for "-classpath"
      -extdirs <dir-list>       Where to look for extension class files
      -bootclasspath <dir-list> Where to look for boot class files
      -encoding <encoding>      Encoding of source files, default is platform-dependent
      -verbose                  Report about opening, parsing, compiling of files
      -n                        Print subcommands to STDOUT instead of running them
      (any valid command-line optipon for the JAVA tool, see "java -help")
    $

Janino as an ANT compiler

You can plug JANINO into the utility through the AntCompilerAdapter class. Just make sure that janino.jar is on the class path, then run ANT with the following command-line option:

    -Dbuild.compiler=net.janino.AntCompilerAdapter
  

Janino as a TOMCAT compiler

If you want to use JANINO with TOMCAT, just copy the "janino.jar" file into TOMCAT's "common/lib" directory, and add the follwing init parameter section to the JSP servlet definition in TOMCAT's "conf/web.xml" file:

    <init-param>
        <param-name>compiler</param-name>
        <param-value>net.janino.AntCompilerAdapter</param-value>
    </init-param>
  

Who develops Janino?

As of today, Janino is written and maintained entirely by myself, . I do this work without support of any company. I am independent from SUN Microsystems Inc.

Licensing

Janino is distributed under the terms of the LGPL. I chose this license so that Janino will (hopefully) be useful in both free and proprietary projects.

How is Janino developed?

Janino was initially developed with JDK 1.2.2 and CVS on Linux. Meanwhile, I switched to JDK 1.3.1 on Windows XP and dropped support for JDK 1.2.2. While the JavaTM platform is moving towards 1.5 and 1.6, I hope that all sane people have now upgraded to at least 1.3.1 ;-)

Janino should run on any operating system platform for which a JDK 1.3.1 or higher is available.

Future directions

Janino has become a more or less complete JavaTM compiler, lacking only inner classes. This now allows for its use in more complex applications, e.g. a light-weight JSP engine.

Examples

The source code of the ShippingCost class demonstrates how easy it is to use Janino as an expression evaluator.

The ExpressionDemo class implements a command line-based test environment for the expression evaluator (see also its source code).

The ScriptDemo class implements a command line-based test environment for the script evaluator (see also its source code).

The ClassBodyDemo class implements a command line-based test environment for the class body evaluator (see also its source code).

Download

Download either the runtime package (JAR file and JAVADOC) or the source package from www.janino.net.

Installation

Janino runtime package

Unzip the ZIP file you have downloaded:

    $ jar xvf janino-1.0.21.zip
Change to the Janino directory
    $ cd janino-1.0.21
You will find the Janino JAR file, the JAVADOC documentation, and the source code for the demo programs.

To compile the demo programs, run

    $ mkdir classes
    $ javac -classpath lib/janino.jar -sourcepath src -d classes src/net/janino/samples/ExpressionDemo.java src/net/janino/samples/ScriptDemo.java src/net/janino/samples/ClassBodyDemo.java
To learn how to use the demo programs, run:
    $ java -classpath lib/janino.jar:classes net.janino.samples.ExpressionDemo -help
    $ java -classpath lib/janino.jar:classes net.janino.samples.ScriptDemo -help
    $ java -classpath lib/janino.jar:classes net.janino.samples.ClassBodyDemo -help
Notice: On MS Windows, the classpath separator is ";", not ":".

Janino source package

Unzip the ZIP file you have downloaded:

    $ jar xvf janino-1.0.21-src.zip
Change to the Janino directory
    $ cd janino-1.0.21
and compile the source code:
    $ mkdir classes
    $ javac -sourcepath src -d classes src/net/janino/Compiler.java
You will find the Janino class file in the classes subdirectory.

To generate the JAR file, run:

    $ jar cf lib/janino.jar -C classes net/janino

To compile the demo programs, run:

    $ javac -sourcepath src -d classes -classpath lib/janino.jar src/net/janino/samples/ExpressionDemo.java src/net/janino/samples/ScriptDemo.java src/net/janino/samples/ClassBodyDemo.java
To learn how to use the demo programs, run:
    $ java -classpath lib/janino.jar:classes net.janino.samples.ExpressionDemo -help
    $ java -classpath lib/janino.jar:classes net.janino.samples.ScriptDemo -help
    $ java -classpath lib/janino.jar:classes net.janino.samples.ClassBodyDemo -help
Notice: On MS Windows, the classpath separator is ";", not ":".

To generate the JAVADOC documentation, run:

    $ mkdir javadoc
    $ javadoc -splitindex -package -doctitle "Janino 1.0.21" -windowtitle "Janino 1.0.21" -overview src/overview.html -sourcepath src -classpath classes -d javadoc net.janino net.janino.samples
You will find the JAVADOC documentation in the javadoc subdirectory.

Reporting bugs

If you think you have found a bug in Janino, proceed as follows:

Requesting support

If you experience problems with downloading, installing or using Janino, issue a support request on the .

Requesting new features

Please issue requests for new features on the .

Subscribing to the "Janino users" newsletter

This newsletter, as the name indicates, distributes information relevant for Janino users. It is very low traffic; mostly it announces the more important releases of Janino. You can subscribe and unsubscribe to this newsletter on the .

Links

Other JavaTM compiler projects and products that I know about:

A very good on JavaTM compilers.

Feedback

I appreciate your . Let me know how you want to utilize Janino, if you find it useful, or why you cannot use it for your project.

The name

There's no special story behind the name. It begins with a "J", "janino.net" was still available, and it sounds similar to the name of a close relative of mine ;-)

Change Log

Version 1.0.21, February 03, 2004
Version 1.0.20, January 27, 2004
Version 1.0.19, January 24, 2004
Version 1.0.18, January 24, 2004
Version 1.0.17, January 21, 2004
Version 1.0.16, January 17, 2004
Version 1.0.15, January 17, 2004
Version 1.0.14, January 12, 2004
Version 1.0.13, January 8, 2004
Version 1.0.12, January 7, 2004
Version 1.0.11, January 6, 2004
Version 1.0.10, January 4, 2004
Version 1.0.9, January 3, 2004
Version 1.0.8, January 2, 2004
Version 1.0.7, December 25, 2003
Version 1.0.6, December 15, 2003
Version 1.0.5, November 26, 2003
Version 1.0.4, November 18, 2003
Version 1.0.3, November 12, 2003
Version 1.0.2, October 30, 2003
Version 1.0.1, October 23, 2003
Version 1.0, October 20, 2003
Version 0.3.17, October 09, 2003 (not released)
Version 0.3.16, October 06, 2003 (not released)
Version 0.3.15, September 12, 2003
Version 0.3.14, July 27, 2003
Version 0.3.13, July 6, 2003
Version 0.3.12, June 4, 2003
Version 0.3.11, June 1, 2003
Version 0.3.10, April 22, 2003
Version 0.3.9, April 02, 2003
Version 0.3.8, March 05, 2003
Version 0.3.7, November 26, 2002
Version 0.3.6, November 22, 2002
Version 0.3.5, November 14, 2002
Version 0.3.4, November 9, 2002
Version 0.3.3, October 26, 2002
Version 0.3.2, October 21, 2002
Version 0.3.1, October 13, 2002
Version 0.3, May 25, 2002
Version 0.2, April 28, 2002
Version 0.1.1, November 09, 2001
Version 0.1, October 30, 2001

Trademark notice

Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Arno Unkrig is independent of Sun Microsystems, Inc.

See Also:
,