JNLP and JAVA WEB START
Posted On September 1, 2008 by Priyadarshan Roy filed under
These days, we hear so much about RIA ( Rich Internet Applications) and WEB 2.0.
All these technologies are focused on thin clients with rich gui and user-interaction as if the user is working in a desktop stand-alone program. Another assumption is that the user has a browser only and does not have JDK installed in his system.
If the user does not have JDK in his system, it is not possible to save specific data to his hard-disk. He can only save the entire page displayed in the browser. This may not be the best solution for many corporate desktops. In Intranet environments, each user may be provided with a browser only and be asked to get/store data only in the server side files. But, that much of trust is certainly impossible in Internet. After all, we cannot ask a corporate customer to store all his data in a public server, not his own!
Many corporate customers fear the insecurity inherent in the web, especially browser-based applications. While it is true that ubiquitous access requires that the application is entirely browser-based, it cannot be the best solution. Many companies do not use the web-based email system at all fearing breach of security, loss of data and loss of transcripts for future reference. Also, a typical requirement is that the user needs to automate the task by supplying data from his own hard-disk and storing the result too in his hard-disk. Such things are not possible in the currently popular RIA technologies be it AJAX, FLEX2 or LASZLO.
If saving the data in user's hard disk is not required, a simple applet-servlet combination may be the best solution. It does not need JDK to be present in client's system. The applet is used only for the gui and the business logic is done by the servlet. We can use advanced Swing ( library as well as custom components ) for a powerful gui. The catch here is that it requires a plug-in for Swing and it takes time to get loaded. Though the delay is present in Flash-based solutions too, many users object to this.
Ajax and Ajax-like solutions are therefore being explored by the Java community, as an alternative.
However, there is another technology from SUN, known as JNLP(Java Network Launching Protocol). It has been around for nearly four years now( since JDK1.4). It is also known as Java Web Start. ( javaws).
Let us assume that a software development company has its website at 'www.abcxyz.com'.
They can develop a standalone swing application , much as they would, in the case of applet and deploy it as a jar file in their web server. They can then provide an html file with a link to a jnlp file, related to the jar file. The user, browsing the web, can click on this link to download the application. The application gets downloaded to the user's system and gets executed. It also gets cached in the user's machine, so that he does not need the browser anymore to execute the program.
Even if the server fails later, the user is able to execute the program! This is in contrast to a servlet which cannot run unless the server is running. This is a rather stunning revelation, though regrettably, not very widely-known!
All this assumes that the user is having JDK and so is meant for the serious corporate user who needs a powerful desktop application rather than a fancy browser-based application. It is in fact better than a frame-servlet combination ( by tunnel-method) as the program can work even if the server is down.
We will now develop a few lessons to illustrate the exact steps required. In our first example, we are having a very simple demo (written in jdk1.02 style(!), just to make it simplest. This will enable us to concentrate on the essentials. Here we have a button and text field and when the user clicks the button, a message appears in text1. We should remember to provide an 'exit' button also. (buttontext.java)
| --------------------------------------------------------------------------------------------------------------------------- // buttontext.java import java.awt.*; public class buttontext extends Frame { Button button1,button2; TextField text1; public static void main(String args[]) { buttontext app = new buttontext(); app.resize(600,400); app.show(); } buttontext() { setLayout(new FlowLayout()); button1 = new Button("click"); text1 = new TextField(20); button2 = new Button("exit"); add(button1); add(text1); add(button2); setBackground(Color.pink); button1.setBackground(Color.green); button2.setBackground(Color.red); } public boolean action(Event e, Object o) { if(e.target==button1) { text1.setText("welcome"); } if(e.target==button2) { System.exit(0); } return true; } } |
We are in c:\
>md jnlpdemos
>cd jnlpdemos
set path=c:\windows\command;d:\jdk1.6\bin
(jdk1.6 has been given in DevIQ CD last month).( JDK1.5 also is enough).
compile c:\jnlpdemos\buttontext.java
We should jar this class file.
>jar cf buttontext.jar buttontext.class
Let us copy this jar file to:
c:\tomcat5\webapps\root\jnlpdemos
Now, we have to create a jnlp file as given below.
--------------------------------------------
| --------------------------------------------------------------------------------------------------------------------------- // buttontext.jnlp <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="http://localhost:8080/jnlpdemos/" href="buttontext.jnlp"> <information> <title>buttontext</title> <vendor>rsr</vendor> <description>trial</description> <description kind="short"></description> <offline-allowed/> </information> <resources> <j2se version="1.6"/> <jar href="buttontext.jar"/> </resources> <application-desc main-class="buttontext"/> </jnlp> -------------------------------------------- |
After creating this jnlp file, we should place it in :
c:\tomcat5\webapps\root\jnlpdemos' folder.
The third step is creating a simple html file which provides a link to the jnlp file.
-----
| --------------------------------------------------------------------------------------------------------------------------- // buttontext.htm <html> <body> click here <br> <a href="buttontext.jnlp"> buttontext </a> </body> </html> ------------- |
We should place this file also in:
c:\tomcat5\webapps\root\jnlpdemos'folder.
--
We are now ready to test our sample.
Start tomcat5 as follows:
c:\tomcat5\bin>
set JAVA_HOME=D:\JDK1.6
>startup
---
The server gets started.
Now launch the browser and type the URL as:
'http://localhost:8080/jnlpdemos/
buttontext.htm'
---
We will get the html page with the single link. When we click on that link, we get the program getting downloaded. We will get a splash screen, 'JAVA STARTING'
(see splash.doc) and also a brief downlod progress bar and after that we get the program running. We can close the program, after testing.
--
Now comes the intersting part. We can shutdown Tomcat5. and then launch the program from command line from any window after giving path to jdk1.6\bin
>javaws "http://localhost:8080/
jnlpdemos/buttontext.jnlp"
The program gets launched quickly from the cache! Thus we are able to run the program locally without depending on browser or server!
---------
The really important task is saving the data from the program to the user's hard-disk file. So, to illustrate this aspect, let us write a very simple text editor program as given below.
----
| --------------------------------------------------------------------------------------------------------------------------- // editor.java import java.awt.*; import java.io.*; import java.awt.event.*; public class editor extends Frame implements ActionListener { MenuBar menubar; Menu menu1; MenuItem item1,item2,item3; TextArea area1; public static void main(String args[]) { editor app = new editor(); app.resize(600,400); app.show(); } editor() { setLayout(new FlowLayout()); setBackground(Color.pink); area1 = new TextArea(15,60); add(area1); //--- menubar = new MenuBar(); menu1 = new Menu("file"); item1 = new MenuItem("open"); item2 = new MenuItem("save"); item3 = new MenuItem("exit"); menu1.add(item1); menu1.add(item2); menu1.add(item3); menubar.add(menu1); setMenuBar(menubar); item1.addActionListener(this); item2.addActionListener(this); item3.addActionListener(this); } public void actionPerformed (ActionEvent e) { if(e.getSource()==item1) { try { FileDialog dlg =new FileDialog (this,"open",FileDialog.LOAD); dlg.show(); String s1 = dlg.getDirectory(); String s2 = dlg.getFile(); FileInputStream fis = new FileInputStream(s1+s2); DataInputStream dis = new DataInputStream(fis); String s = dis.readLine(); while(s != null) { area1.append(s+"\n"); s=dis.readLine(); } }catch(Exception e1) { area1.setText(""+e1);} } //------ if(e.getSource()==item2) { try { FileDialog dlg =new FileDialog (this,"save",FileDialog.SAVE); dlg.show(); String s1 = dlg.getDirectory(); String s2 = dlg.getFile(); FileOutputStream fos = new FileOutputStream(s1+s2); PrintStream ps = new PrintStream(fos); String s=area1.getText(); ps.println(s); }catch(Exception e1) {area1.setText(""+e1);} } if(e.getSource()==item3) { System.exit(0); } } } ------------------------------------------- |
As before, we compile this using JDK1.6 and then jar the editor.class as editor.jar
Next we create the jnlp file as given below.( editor.jnlp)
--
| --------------------------------------------------------------------------------------------------------------------------- <?xml version="1.0" encoding="utf-8"?> <jnlp codebase="http://localhost:8080/jnlpdemos/" href="editor.jnlp"> <information> <title>editor</title> <vendor>rsr</vendor> <description>trial</description> <description kind="short"></description> <offline-allowed/> </information> <security> <all-permissions/> </security> <resources> <j2se version="1.6"/> <jar href="editor.jar"/> </resources> <application-desc main-class="editor"/> </jnlp> -------------------------------------------- |
We need to give special attention to the entry regarding security.
JNLP programs execute within a security sandbox in the client's machine. So, while a program without this security entry in jnlp file is able to read a local file, it throws exception when we try to save the content to local file.
It is not enough if we provide this entry. The developer of the program should sign the jar file.
The exact steps have been given below.
--
C:\jnlp>keytool -genkey -keystore mystore -alias rsr
Enter keystore password: rsrkey
Re-enter new password: rsrkey
What is your first and last name?
[Unknown]: ram sam
What is the name of your organizational unit?
[Unknown]: freelance
What is the name of your organization?
[Unknown]: freelance
What is the name of your City or Locality?
[Unknown]: mds
What is the name of your State or Province?
[Unknown]: tn
What is the two-letter country code for this unit?
[Unknown]: in
Is CN=ram sam, OU=freelance, O=freelance, L=mds, ST=tn, C=in correct?
[no]: yes
Enter key password for <rsr> rsrkey
(RETURN if same as keystore password):
Re-enter new password: rsrkey
-------------------------------------------
C:\jnlp>jarsigner -keystore mystore editor.jar rsr
Enter Passphrase for keystore:
rsrkey
Warning:
The signer certificate will expire within six months.
C:\jnlp>
========================================
The above steps result in our editor.jar being signed.
As before we copy the editor.jar, editor.jnlp and editor.htm to :
'c:\tomcat5\webapps\root\jnlpdemos' folder.
--
Start the tomcat server.
In the browser, navigate to :
http://localhost:8080/jnlpdemos/editor.htm'
--
Click on the link in that html file.
We get the 'JAVA STARTING' splash screen.
and also a fleeting download progress bar.
This time a dialog appears, as shown below.
(see security)
The user has to trust and click the 'run' button. (This indeed is objectionable to many users. But, normally, we will get it certified by a certificate authority.) . This problem is there for all the companies, after all!
After confirmation, the editor program gets launched. Type something in area1 and save it. We are able to save to local file! We can also open any file in our local disk.
--
As before, shutdown the tomcat server and try to run the program without the server and browser, as you would in a normal standalone program. How?
We can give path to jdk1.6 in any convenient window and then at the command prompt, type
>javaws "http://localhost:8080/jnlpdemos/editor.jnlp"
As before, we get the splash screen , a bit quicker now and we are able to work with our program.
----
The JNLP method has some very enthusiastic fans among world-class java programmers.It means a lot for companies which develop desktop applications in Swing. They can now effortlessly distribute their desktop applications through the web!
In closing, a quote from James Hart, a renowned author on JDK is worth noting.
"Java as a GUI and client development platform just keeps better.The support of complex frameworks like drag-and-drop and Image I/O help us achieve things that were extremely hazardous before. The crowning achievement may well be JNLP. By offering a rich user experience, and a breadth of choice to developers, it could well become an extremely widespread networked deployment platform for the Internet."
again,
"I would like to see a really powerful application deploy across JNLP----something like StarOffice or NetBeans. That would demonstrate the power ".
( from page-75.
Early Adopter J2SE1.4
by
James Hart
(WROX PRESS).
==========================================
RS Ramaswamy can be reached on rs.ramaswamy@gmail.com
