How Java Plays With Scripting Languages

By Carol Zhang, June 2008  

Articles Index

Trends in Programming Languages

In recent years, Google search trends show that searches for the word "Java" are declining slightly, and searches for scripting language names, like JavaScript, PHP, Ruby, Python, and Rails, are increasing. Some people are talking about the dismissal of Java and its replacement with these scripting languages. Though we can not predict the future of the Java programming language in this article, we have solid reason to believe that Java is still a mainstream programming language in the world, and it will exist for a long time. There is a very large and stable ecosystem around Java, which includes large vendor support, killer applications, wide deployment, development and deployment tools, lots of experienced programmers, mature communities, comprehensive training, and low entry costs. This is the huge momentum of a successful language.

The rise of the scripting languages is driven by agile development requirements in the Web 2.0 era. Scripting languages enable rapid and easy development with features:

  • Featured syntax allows simpler and faster application writing, and performance of specific tasks more easily. For example, Perl is a well-known great way to process text and to generate reports.
  • Most scripting languages are interpreted and deploy without compiling, though the code can be parsed and compiled to the intermediate result when first executed.
  • Most scripting languages are dynamic, which means they execute many common behaviors at runtime that other languages might perform during compilation. These behaviors could include extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system.

However, scripting languages fall short if they are used to build large-scale or mission-critical applications, due to potential scalability and performance issues. Also, most scripting languages are not designed for team collaboration.

Java and scripting languages are not mutually exclusive. On the contrary, they are complementary and can play together in many scenarios.

Why Integrate?

Combining scripting languages with the Java platform provides developers an opportunity to leverage the abilities of both environments. You can continue to use scripting languages for all the reasons you already have, and you can use the powerful Java class library to extend the abilities of those languages. If you are a Java language programmer, you now have the ability to ship applications that your customers can significantly and dynamically customize. The synergy between the Java platform and scripting languages produces an environment in which developers and end users can collaborate to create more useful, dynamic applications.

Let's take Project Phobos as an example, to see what magic can be produced with the integration of Java and scripting languages. The goal of Phobos is to build a lightweight web application framework that runs on the Java platform, but allows you to develop your entire application using a scripting language, such as JavaScript. As a result, you can take advantage of the many benefits that scripting languages offer, but still leverage the power of the Java platform.

When To Integrate

If you intend to use scripting to implement a portion of your Java applications, you will need to decide when to use which technologies, considering each language has its own strengths and weaknesses. Though normally it should be analyzed case by case:

Consider using scripting:

  • Simplified customization for the user
  • Quick operations work
  • Quick presentation layer build-up
  • Text processing

Consider using Java:

  • Complex enterprising applications with large number of back end systems
  • Response time is critical
  • Java libraries and capabilities like JMS, SOA framework are needed
  • Large scale system with many collaborators
Java Interoperability with Other Languages

A number of approaches also allow Java applications to interoperate with code written in other languages. For example:

  • A Java application may take advantage of Web Services to communicate with an external application in a language-independent way.
  • A Java application may communicate with a native application through the Socket API.
  • A Java application may connect to a legacy database through the Java Database Connectivity (JDBC) API.
  • A Java application may use the Java Native Interface (JNI) to talk to native applications written in C/C++.

Basically, the interaction will be of one of two types. Either the Java application and the separated processes, which communicate by using inter-process techniques, like Web Services, or the Java application and the other reside in the same process, as with JNI. The technology used depends on the system requirement and the existing architecture.

It is a similar story when Java interacts with scripting languages. The Web Services approaches can be chosen for the loosely-coupled applications written in script, and if it is both cumbersome and inefficient to manipulate scripting files through another process, then the in-process integration method between Java and scripting language may be considered. Since the inter-process integration technologies are well-known and mature, then in this article, we will mainly discuss how Java and scripting language interoperate within one process.

The Essentials for Interfacing Java with Script

Several common questions are asked when people are writing programs to interface Java applications with code written in other scripting languages:

  • How do you support multiple scripting languages within Java?
  • How is the scripting code parsed and executed in the JRE?
  • How do data types in the Java programming language map to the data types in other languages?
  • How do you interact with fields and methods for each other's objects?

JSR-223, Scripting for the Java Platform, defines a standard, portable, scripting language-independent way to allow Java programs to interact with scripting languages. Here's a brief introduction to how Java Scripting Framework solves the above questions.

Figure 1. Diagram: the internal of the Scripting Engine

The core of the Java Scripting Framework is the Scripting Engine, as shown in the above diagram. It is a pluggable software component that executes programs written in some scripting language. The execution is generally performed by an interpreter. You can implement the engine in Java or make a Java wrapper around a native language interpreter. Conceptually, an interpreter consists of two parts: a front-end which parses the source code and produces an internal representation of the program known as intermediate code, and a back-end which uses the intermediate code to execute the program.

The specification refers to a Script Engine Discovery Mechanism to automatically discover the Scripting Engines at runtime and query for attributes that an application can use to determine their capabilities and usability. It also means that you can add new Script Engines to your runtime environment as common JAR extensions.

Scripting Engines are allowed to store Java objects and class references and use them in scripts by the mechanism of Java Language Bindings. Bindings are created by a built-in scripting function to allow scripts to access public methods and fields of objects, and public static methods and fields of classes. Typically, the binding keeps the key/value mappings:

  • key – the script variable name
  • value – Java Object Proxy, which is a wrapper of the Java Object or class reference. The value may be stored in the script engine symbol tables.

The data types represented by script variables vary depending on the scripting language and the script engine implementation. In each invocation from Java code to script code, a data type conversion would be executed when passing the Java object as arguments and returning the value from the function call. You should check with the script-specific document about the data type conversion.

Now that we've covered the essentials of the integration and the standardized approaches in the Java specification, we will talk more about the methods of two-way integration: one is scripting within the Java application, the other is scripting the Java object. Let's look at them in detail.

Scripting Within Java

The Java Scripting Framework provides a set of scripting APIs, which allow Java Scripting Engines to be used in Java applications. The API is intended for use by application programmers who wish to execute programs written in scripting languages, in their Java applications. Let's go through a code sample to see how this can be achieved.

The simplest way to use the scripting API is as follows:

  1. Create a ScriptEngineManager object.
  2. Get a ScriptEngine object from the manager.
  3. Evaluate the script using the ScriptEngine's eval methods.
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");

        // create a Java object
        String name = "Tom";

        // create the binding
        engine.put("greetingname", name);

        // evaluate JavaScript code from String
        engine.eval("println('Hello, ' + greetingname)");
        engine.eval("println('The name length is ' +  greetingname.length)");

The output is:

Hello, Tom
The name length is 3

Let's go through the code sample:

  1. The Script Engine Discovery Mechanism identifies the Script Engine by the script name "JavaScript".
  2. Create the bindings with key/value pairs, the key is "greetingname" JavaScript variable name, the value is the Java object proxy, which wraps the Java String "name".
  3. The "eval()" method of Script Engine parses the JavaScript code and executes it by internally using a front-end compiler and back-end executor.
  4. During the execution, the method and attribute of the Java object can be accessed from the script.

You can use the Scripting API to achieve the following tasks:

  1. Evaluate and execute a script file.
  2. Expose a Java object to script using the JLB mechanism.
  3. Invoke script functions and methods.
  4. Implement Java interfaces by scripts.

You may refer to the Java Scripting Programmer's Guide for the programming details about how to implement the above functions.

Beside Java Scripting Framework as a standardization effort in this area, the Jakarta Bean Scripting Framework (BSF) is also worthy of mentioning. Running as an open source project, BSF consists of a set of Java classes which provides scripting language support within Java applications, and access to Java objects and methods from scripting languages. It provides an API that permits calling scripting language engines from within Java, as well as an object registry that exposes Java objects to these scripting language engines.

Scripting Java Objects

In this case, Java classes are used to extend the capabilities of scripting languages. They allow us to write powerful scripts quickly by making use of the many Java libraries available. The scripting languages are able to create Java objects and call public methods of the objects using the syntax of the scripting languages. In this way, functionality available in Java that does not exist in the scripting languages can be used in scripts.

As early examples of this technology, Netscape supports JavaScript interaction with Java applets through a technology known as LiveConnect. Microsoft's Java implementation treats every Java object (including applets) as an ActiveX control and uses its ActiveX scripting technology to allow JavaScript programs to interact with Java. Recently, the technologies are evolving in two directions:

  • Using pure Java to implement the scripting language to realize the Java Object scripting, like Rhino JavaScript, and Resin Quercus PHP
  • Using bridging technologies to connect native implementations of scripting languages and the Java runtime, like PHP/Java bridge, which is an optimized, XML-based network protocol, to be used to connect a native script engine, PHP, with a Java Virtual Machine (JVM).

Some of these technologies are prior to the introduction of the JSR-223 specification, and they also help in the evolution of JSR-223. Some scripting technologies are JSR-223 compatible; that is, they are used as Scripting Engines in the Java Script Framework.

There are quite a lot of scripting languages on top of Java and JVM:

  • Rhino is an open-source implementation of JavaScript written entirely in Java. Sun's implementation of JDK 6 is co-bundled with the Mozilla Rhino-based JavaScript script engine. Project Phobos uses Rhino as well.
  • Quercus is Caucho Technology's fast, open-source, 100% Java implementation of the PHP language.
  • Scala is a general purpose programming language, and smoothly integrates features of object-oriented and functional languages. It is also fully interoperable with Java.
  • JRuby is the Java implementation of the Ruby language.
  • JavaFX is a Java-based client technology for creating Rich Internet Applications (RIAs).
  • Groovy is an agile and dynamic language for the Java Virtual Machine.

Let's have a quick look at how Rhino, JRuby, and JavaFX implement the Java object scripting in their own syntax:

Rhino: Pure Java implementation of JavaScript

   importPackage (java.awt);
   var frame = new java.awt.Frame("hello");

JRuby: Pure Java implementation of Ruby

   require 'java'
   frame ="hello");
   puts frame.title;

JavaFX: Java-based scripting language for RIA

 import javafx.ui.*;
 Frame {
        Title: "hello"
    Width: 200
    Height: 50
    Visible: true

In this scripting sample code, a Java object is created and its instance method is invoked. The syntax of how the scripting languages enable the use of the Java object in the scripts varies, but they share the common characteristics that they are Java-based, which makes it natural to be interoperable with Java.

Performance Consideration

Compared to pure Java, the scripting performance should be an important consideration. There is no consistent data for the Java and Script performance comparison because scripting languages themselves vary a lot. Generally speaking, the scripting performance is slower than Java since scripting languages are interpreted. We may apply the following techniques to balance the flexibility and performance of the overall solutions:

  • Don't use scripting for the performance-critical part of the application.
  • If possible, always use the most-recent version of the Scripting Engine for certain scripting languages, because there are continuous efforts in performance improvement.
  • Use the intermediary result for execution to boost performance. As mentioned before, internally the script is compiled to the intermediate code, and then executed. Check with the script language specification to see if it is posssible to cach and run the compiled version for the script.

Though we don't think they would replace Java, the scripting languages are good supplements to the Java platform. The JSR-223 specification defines scripting in the Java platform, creating a flexible, extensible and consistent way to deal with scripting languages in Java. It is believed that more interaction will happen between Java and scripting languages, while both gain more popularity and developers explore their usages together in new and innovative ways.

For More Information

I am indebted to the following people for their help with this article:

  • Vasanth Bhat and Wang Yu for their review and valuable comments
  • Laureen Hudson and Jill Welch for their editorial assistance
About the Author

Carol Zhang is a member of the technical staff in the ISV Engineering department at Sun. With ten years of experience in software development and technical consulting, Carol provides technical consultation to Sun's partner software vendors in China.

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.