Interfacing Java and JavaScript Using LiveConnect

Sandeep Panda
Share

LiveConnect is a technique that allows Java and JavaScript to communicate with each other. It allows your Java class to call JavaScript methods and access the JavaScript environment. JavaScript can also access Java objects and invoke methods on them. LiveConnect was first implemented in the Netscape browser, and currently Mozilla Firefox fully supports this feature. In this tutorial you will learn how to write code that makes the communication between Java and JavaScript possible.

There are two main aspects of LiveConnect:

  • Calling Java methods from JavaScript
  • Using JavaScript objects in Java

Accessing Java From JavaScript:

Whenever you need to access a Java object, class, array, or package just use one of the following four LiveConnect objects.

  • JavaObject – Used to access a Java object from JavaScript.
  • JavaClass – Used as a reference to a Java class.
  • JavaArray – Used to access Java arrays.
  • JavaPackage – Used as a reference to a Java package.

Using JavaObject

You can create a Java object and assign it to a variable in JavaScript with the help of the new keyword. When you create an instance of a Java class, JavaScript automatically creates a JavaObject object. For example, you can instantiate a Java String from JavaScript and assign it to a variable. Then you can use the dot operator to access the object’s length() method, as shown below.

var myString=new java.lang.String("Test String");
alert(myString.length()); //prints 11

Using JavaClass

Whenever you refer to a Java class in your code and assign it to a variable, the JavaScript runtime automatically creates a JavaClass object. For example, the following code creates a JavaClass object.

var myInteger=java.lang.Integer;
alert(myInteger.MIN_VALUE);

Using JavaPackage

Similarly, whenever your JavaScript code refers to a Java package, the JavaScript runtime automatically creates a JavaPackage object. In this case, we are creating an instance of class MyClass which is inside the mypackage package.

var myVar=new Packages.mypackage.MyClass();

If your class is not a part of any package it’s possible to directly instantiate it as shown in the following example.

var myVar=new Packages.MyClass();

Commonly used classes such as those in the java, sun, and netscape packages can be instantiated in the following way.

var myVar=new java.lang.String();

The above code is equivalent to the following:

var myVar=new Packages.java.lang.String();

Using JavaArray

JavaArray objects are created automatically whenever you create a Java array inside of JavaScript code. For example, the following code creates a Java array containing five Strings.

var myArray=java.lang.reflect.Array.newInstance(java.lang.String,5);

Later you can print the length of the array using the length property.

var myArray=java.lang.reflect.Array.newInstance(java.lang.String,5);
alert(myArray.length);  //outputs 5

Accessing JavaScript Objects Inside Java Code

We mainly use the following two classes for accessing the JavaScript environment from Java.

  • netscape.javascript.JSObject – Used for accessing JavaScript methods and properties.
  • netscape.javascript.JSException – Used for exception handling inside Java code.

These classes are not accessible to your code by default. To make these accessible you need to add a jar containing these classes to your CLASSPATH. Open up your JRE installation directory and go to the lib folder. You will find a jar file called plugin.jar. Add this jar to your class path so that the above two classes are made available to the JRE while running your application.

Using JSObject

All the JavaScript objects that appear in Java are of type JSObject. Remember we talked about calling Java methods from JavaScript? Well, you can call any Java method from JavaScript code and pass JavaScript objects to the method as parameter. These objects are then converted to the type JSObject on the Java side. In order for these methods to work you need to define formal parameters of type JSObject in the Java method signature. The following example shows how a Java class, Player, gets JSObject through its constructor and uses it to get members of a JavaScript object.

public class Player{
  public String name,age;
  public Player(JSObject js){
    this.name=(String)js.getMember("name");
    this.age=(String)js.getMember("age");
  }
}

Next, we will create an object called Player in JavaScript.

function Player(name,age){
  this.name=name;
  this.age=age;
}

Now it’s possible to create a JavaScript object Player, and pass it to the constructor of the Java Player class while instantiating it.

var player=new Packages.Player(new player("John Doe","20"));
// instantiates Java class Player and passes the JavaScript Player object as argument.

Using JSException for Handling JavaScript Errors in Java

Things can go wrong in your Java code while accessing the JavaScript environment. In this case the JSException class comes to the rescue. The following example demonstrates the use of JSException.

public class TestException{
  public Object process(JSObject js, String method){
    try{
      js.eval(method);
      //tries to call a JavaScript method. If method is undefined it will throw an exception.
    }
    catch(JSException e){
      System.out.println(e);
    }
    return null;
  }
}

An Example Usage

Now that we know how to call Java methods from JavaScript and use JavaScript objects inside Java, it’s time to create a small application so that the overall concept will be clear. We will create a very simple application that asks the user to input his/her name, age, and programming language of choice. Based on the language selected, the application will display a message indicating the best framework to learn. As we are using LiveConnect to build the application, we have a Programmer class in both Java and JavaScript.

There is also an applet present in the page. This is done because the very first object accessible to LiveConnect is the public applet instance. From the applet we can get our desired object. In our program the LauncherApplet has a method that returns a Programmer object. First, we need to invoke this method to get a Programmer instance in our JavaScript code. The basic idea is to pre populate the Programmer object. Then, after the HTML page is loaded, show a message displaying various properties of the object. Then, take user input from an HTML form and construct a JavaScript Programmer object.

The next step is passing the newly constructed JavaScript object to the Java method setData. The Java method reads the properties of the object and updates its properties. Make sure that the Programmer class is declared public, otherwise you can’t access it from JavaScript. As the last step, we call another method getAdvice() on the Java object that returns personalized advice about which framework the user should use.

The source code for the Java Programmer class is shown below.

import netscape.javascript.*;
public class Programmer {
  public String name="Sandeep";
  public String age="20";
  public String language="Java";
  public void setData(JSObject js){
    try{
      this.name=((String)js.getMember("name")).toLowerCase();
      this.age=((String)js.getMember("age")).toLowerCase();
      this.language=((String)js.getMember("language")).toLowerCase();
      System.out.println("Name= "+name+",Age= "+age+",language= "+language);
    }
    catch(JSException e){System.out.println(e);}
  }
  public String getAdvice(){
    String advice="";
    switch(language){
      case "php":
        advice=name+", you should definitely try out CodeIgniter.";
        break;
      case "java":
        advice=name+", you should definitely try out JavaServer Faces.";
        break;
      case "python":
        advice=name+", you should definitely try out Django.";
        break;
      default:
        advice="You language of choice is not any one of PHP, Java or Python";
    }
    return advice;
  }
}

Our LauncherApplet class looks like following:

import java.applet.*;
import java.awt.*;
public class LauncherApplet extends Applet{
  public Programmer getProgrammer(){
    return new Programmer();
  }
}

The structure of our HTML page is the following:

<html>
  <head>
    <title>Applet Test</title>
    <script type="text/javascript" src="liveconnect.js"/>
  </head>
  <body onload="showProgrammer()">
    <applet id="app" code="LauncherApplet" height="1" width="1" MAYSCRIPT></applet>
    <table>
      <tr>
        <td>Name</td>
        <td>:</td>
        <td><input type="text" id="name"/></td>
      </tr>
        <td>Age</td>
        <td>:</td>
        <td><input type="text" id="age"/></td>
      </tr>
        <td>Programming Language(PHP,Java or Python)</td>
        <td>:</td>
        <td><input type="text" id="language"/></td>
      </tr>
    </table>
    <input type="button" onclick="processProgrammer()" value="click"/>
  </body>
</html>

In liveconnect.js we define two functions and one Programmer class. The Programmer class is defined below.

function Programmer(name,age,language){
  this.name=name;
  this.age=age;
  this.language=language;
}

Next, we define a function, showProgrammer(), which shows the properties of the Java object Programmer when the page is loaded. The code for the function is given below:

function showProgrammer(){
  try{
    var programmer=app.getProgrammer(); //app is the id of applet tag which refers to the applet instance.
    var data="Name= "+programmer.name+",Age= "+programmer.age+",Language= "+programmer.language;
    alert(data);
  }
  catch(e){
    alert(e);
  }
}

Finally, we define the processProgrammer() function which reads the name, age, and programming language choice inputs. Then, it uses these values to create a JavaScript Programmer object, and calls setData() on the Java side. The JavaScript Programmer object is an argument to setData(). In the next step, we use the properties of the Java Programmer object to prepare advice. Finally, the advice is returned to the JavaScript side.

function processProgrammer(){
  try{
    var name=document.getElementById("name").value;
    var age=document.getElementById("age").value;
    var language=document.getElementById("language").value;
    var programmer=app.getProgrammer();
    var myprog=new Programmer(name,age,language);
    programmer.setData(myprog);
    var advice=programmer.getAdvice();
    alert(advice);
  }
  catch(e){
    alert(e);
  }
}

Conclusion

By connecting JavaScript to Java you can create very powerful applications. However, LiveConnect is not fully supported by all browsers. The above application is tested in Firefox 11.0, and the Java code is compiled using JDK 7. So, if you want to test the code samples make sure you have JDK 7 installed on your system. To learn more about LiveConnect check out LiveConnect on the Mozilla Developers Network.