Friday, May 3, 2013

Applet - Javascript communication


            Applet and JavaScript are both client side applications. These two can be combined to achieve a nice Rich Internet Application(RIA). So before diving into them in details lets have a brief introduction on each.

Applet - Applet is a java application which resides on server and linked to a server page, it gets downloaded to the client browser when the user visits that page. It generally runs inside the sandbox and has limited access to system resources. However with the new methodology where applets are deployed by JNLP they can run beyond the sandbox and can access any system resource. More on Java Applet development and deployment is available here .

JavaScript -  JavaScript also resides on server and linked to a server page, it gets loaded to the client browser when the user visits that page. It always runs inside the sandbox with no access to system and can only interact with the browser and HTML DOM.

Applet Deployment - There are different ways there for applet deployment, but for our purpose (as we need to interact with the system) we need it through JNLP and Deployment Toolkit functions to deploy the applet.
The javascript code should look something like this.
 
    <script src="http://www.java.com/js/deployJava.js"></script>
    <script> 
        var attributes = { 
                      id: testApplet,
                      code:'path to applet class', 
                      width:300, height:300} ; 
        var parameters = {jnlp_href: 'jnlp file'} ; 
        deployJava.runApplet(attributes, parameters, '1.6'); 
    </script>

JavaScript To Applet Communication - If we deploy the applet in the above mentioned way then it is always possible for us to call any of applets public method from JavaScript.  From any JavaScript method the applets public method can be called using the applet id which in our case is testApplet. So if the applet have a public method named setMsg(String msg), then we call it from JavaScript in this way testApplet.setMsg("Hello World").  
                       However there is a problem ... . An it is, JavaScript is designed to run only in browser Sandbox so if you are calling a Signed Applet will all permission then this will be called code mixing and the Applet's security will be reduced to Sandbox only.This might also prompt to block the execution, depending on your system security setting.  So if you are doing  some system related tasks in the Applet method that you are calling from JavaScript it may put your system at risk and even the code may not execute.

Applet To JavaScript Communication - This is my focus area.  We have different libraries available that using which the applet can read JavaScript fields, execute JS functions and traverse the HTML DOM. Such a library is provided by netscape and it is available to all browser java plugins, so to use this we have not to do any extra. In this library the class JSObject provides us the entry point to access the JS. The API for this class is available here  .
           Here is a sample code to access the JS . All this codes goes inside the Applet.
                JSObject win = JSObject.getWindow(this); //Provides the handle to the HTML window
                                                                                 //Using  this we can read html fields and JS 
               String jvar = (String) win.getMember("jsField"); //Reads a JS field value with name jsField
               win.setMember("jsField","some vale");//Sets the JS filed value to some value
              JSObject hvar = (JSObject ) win.getMember("hField"); //Reads a html field value with name hField
              String hval = (String) hvar .getMember("value"); //Reads the above html field value
           win.call("jsFunction",{arg1,arg2});//Calls the JS function with name jsFunction passing the arguments

A Case Study - I have a requirement, where the applet needs to do something on a html button click, and the task is related to system activity. As mentioned above I can not call the applet method  directly from JS on button click as it will restrict the applet to Sandbox only.
                         Solution - The solution is a hack. What I deed is in Applet init() method i.e on page load I started a new thread, the thread will loop indefinitely to check a JS field. If the JS field value is set then it will do something and after finishing reset the JS field value. If the JS value is not set then do nothig. And most important at the end of each loop sleep for one second.
                        To trigger the if case of the Applet method, in JS I set that field value on a specific button click event. This solves my problem.

Your Opinion -  Though the above solution solves my problem, still I am wondering whether there will be any side effect other than some delay in button click and the event.
                     You are most welcome to put your thoughts on the above point and the article as a whole. 
Please say your kind words, if you see some point that needs to be improved or correction.