Java has early released
JWS technology (Java Web Start). Its original intention is quite good: wish to establish a seamless bridge between desktop apps and Web page. Although Applet technology has been in existence for more than ten years, it has declined and meantime
JWS came into existence.
But
JWS does not realize its original intention successfully. From several great revisions of Java we can see that
JWS has many bugs and flaws, so Sun and Oracle have to frequently put patches to fix them. You can see that how many big or small upgrades in Java 5 and 6 are related to
Java Web Start. No wonder so many people sighed: “I will not use Java Web Start any longer!”In fact, this is not always the case. With improvement in Java, we are able to eliminate some potential problems in
JWS and to apply it successfully to enterprise applications as long as we have the knowledge of more skills.
Taking
2BizBox ERP project as an example, this article will introduce how to use the technology of dynamically generating
JNLP file to realize rapid deployment in enterprise applications.
We all know that as a free-charged and quality
ERP software,
2BizBox ERP has thousands of users. There are nearly one thousand servers our development team have the responsibility to maintain, not to mention the over a hundred client-sides each enterprises has. There is no doubt that it will be a huge workload if we apply the method to download client-sides to install the program and maintain all of these client-sides. In this way, neither the users nor us development team will feel relaxed and convenient. To solve it, the application of
JWS is a must.
In order to let the client-sides automatically download and install programs, we have deployed the following
JNLP files on enterprises’
2BizBox ERP servers.
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://**.**.**.**/webstart/">
<information>
<title>2BizBox</title>
<vendor>Serva Software</vendor>
<homepage href="http://www.2bizbox.com"/>
<description>2BizBox ERP 3</description>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<update check="always" policy="always"/>
<resources>
<j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" initial-heap-size="128m" max-heap-size="512m"/>
<jar href="2bizbox.jar />
<jar href="lib1.jar />
<jar href="lib2.jar />
<jar href="lib3.jar />
<jar href="lib4.jar />
<!-- more jar.... -->
</resources>
<application-desc main-class="com.serva.bb2.gui.Main">
<argument>**.**.**.**</argument>
</application-desc>
</jnlp>
The following
JNLP file has defined the jar package needed for starting a 2BixBox ERP client-side and the download location and the jre edition.
It looks good in actual application. However, because of
JNLP and the bugs in
JWS itself, in some circumstances, users cannot obtain updates by starting
JNLP after renewing and updating background jar programs. They have to clear up
JWS cache by force, which, in general, users have not any idea. In another case, when changes have taken place in the jar package of
ERP itself (such as addition or deletion of classes in it) which is equivalent to changes in the content in
JNLP file, user-sides are asked to be aware of the changes in
JNLP and to update
JNLP first. In many java editions (for example, early jre6 editions and editions before ure6 update20),
JNLP at user-sides cannot be updated successfully because of reasons like potential bugs, hence the failure in starting program.
How to solve this problem? An effective way is to apply the dynamic
JNLP.
How to solve this problem? An effective way is to apply the dynamic
JNLP.The way of dynamic
JNLP: at the background of server, a
JNLP file is dynamically generated by jsp or servlet instead of placing a static and unchanging
JNLP file. Therefore, through the logic of background application we can dynamically generate or create the content of a
JNLP file like what kind of jar archive and which jre edition is needed.
Take jsp as an example. In this jsp, the several key points you need to pay attention to are: first, set this page not to be buffered by the browser in order to avoid jnlp content’s not being able to be updated in time. Second, set mime class and let the browser consider it as a jnlp file in order to be downloaded instead of showing it directly in the browser. These can be realized by setting
response.
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
response.setHeader("Content-Disposition", "filename=\"bb.jnlp\";");
response.setContentType("application/x-java-jnlp-file");
Meanwhile, the browser and webstart can be set as not allowed to cache content in jnlp by setting response.setHeader(“Pragma”, “no-cache”); and
response.setHeader(“Expires”, “0″);. You can also set the type of files and give a dynamic file name through response.setHeader(“Content-Disposition”, “filename=\”bb.jnlp\”;”);response.setContentType(“application/x-java-jnlp-file”);
You need to pay attention to a problem that when dynamically generating jnlp file you must be careful not to set the href tag in jnlp file. Why? You can see the words in jnlp format document:
http://lopica.sourceforge.net/ref.html#jnlp
The jnlp file's one and only root.
Attributes
spec=version , optional
Specifies what versions of the jnlp spec a jnlp file works with. The default value is 1.0+. Thus, you can typically leave it out.
version=version , optional
Specifies the version of the application as well as the version of the jnlp file itself.
codebase=url , optional
Specifies the codebase for the application. Codebase is also used as base URL for all relative URLs in href attributes.
href=url , optional
Contains the location of the jnlp file as a URL. If you leave out the href attribute, Web Start will disable the update check on your JNLP file, and Web Start will not treat each new JNLP file as an application update - only updated jar files will. Leaving out href usually makes only sense if your jnlp file is created dynamically (that is, throug a cgi-script, for example) and if your jnlp file's arguments or properties change from request to request (user to user).
Note, that Java Web Start needs href to list your app in the Web Start Application Manager.
So, when dynamically generating
JNLP, don’t set href. In this way the browser will download
JNLP file anew at every turn.
Another point is that the jar archive in JNLP file can dynamically check the jar archive in the file and dynamically generate it. Therefore, if there is addition or deletion in the jar files in the program, there will be no need to modify jnlp files. The method is also quite simple: check the absolute path of the current web in the server and list all jar files, then output them when generating jnlp.
<%
String urlString=request.getRequestURL().toString();
URL url=new URL(urlString);
String host=url.getHost();
String path = request.getSession().getServletContext().getRealPath("/");
path=path.replace("\\.\\", "\\");
File file=new File(path);
String[] files = file.list();
ArrayList jarNames=new ArrayList();
for(int i=0;i<files.length;i++){
String fileName=files[i];
if(fileName.toLowerCase().endsWith(".jar")){
jarNames.add(fileName);
}
}
%>
Then list them as described in the following code in jar’s part:
<resources>
<j2se href="http://java.sun.com/products/autodl/j2se" version="1.6+" initial-heap-size="128m" max-heap-size="512m"/>
<%
for(int i=0;i<jarNames.size();i++){
out.write("\n");
out.write("<jar href=\""+jarNames.get(i).toString()+"\"/>");
}
%>
</resources>
At last, if it is necessary to specify the ip address or the host address of the current server in jnlp, it can also be done by dynamic generation, such as the codebase in jnlp file. In addition, the ip address of the current server must also be given in the main function in
2BizBox ERP. However, it is out of our imagination, if every jnlp in over a thousand 2BizBox servers needs to be maintained manually. Now this problem can be perfectly solved by means of dynamic generation.
String urlString=request.getRequestURL().toString();
URL url=new URL(urlString);
String host=url.getHost();
Then in jnlp:
<jnlp spec="1.0+" codebase="http://<%=host%>/webstart/">
...
<application-desc main-class="com.serva.bb2.gui.Main">
<argument><%=host%></argument>
</application-desc>
The method to dynamically generate jnlp through jsp is thus completed. It goes well in
2BizBox ERP and let over a thousand
2BizBox ERP cloud-host users quickly get their programs updated and simplify the maintaining of programs.