Deployment of JARs with the Java Launcher.

The Java launchers can simplify complicated Java JAR deployments by leveraging the Multiple JRE feature of the launchers.

Background

Enterprise wide Java intranet applications may be deployed as JAR file(s) containing classes and resources needed by an application. These JARs are installed on a filesystem within an intranet. Typically these applications are launched using Unix shell scripts or Windows batch files, using very simple commands such as "java -jar SomeApp.jar arg1 arg2 ......"

Not all Java applications are the same and some of these could require a specific version of the JRE. The Multiple JRE (MJRE) mechanism in the java launcher (as of 1.5) can be leveraged, so that different versions of  JREs and JARs requiring them can peacefully co-exist on a system.

So what is this feature ?

The Java Launcher is a binary file "java" found in the "bin" directory of the JRE distribution. On Windows platform the launchers are "java.exe" and "javaw.exe", the former displays a Console window, during the execution of the application and the latter does not, however both are Java launchers.

Note that "javaws"(.exe) is Java Webstart, a Java application primarily used to launch Java applications over the network. The MJRE, in fact borrows several version-contraint semantics from Java Webstart, however these constraints in Java Webstart are specified in a different form, and not discussed here.

If applied correctly, the MJRE feature of the launcher can be extremely useful,  consider the use case:

Suppose we have a user who has several applications ex: NotePad, PhotoEdit etc. The NotePad has been certified to work with JRE 1.5 by the application vendor. The PhotoEdit application began to malfunction with JRE 1.5 due to a graphics issue, and JRE 1.6 fixes the problem. So one can solve the problem of ensuring that the JREs co-exist, by doing the following:

Manifest for PhotoEdit:

Main-Class: PhotoEdit
JRE-version: 1.6+

Manifest for NotePad:

Main-Class: NotePad
JRE-version: 1.5\*

The launcher uses 1.5.0_06 version of the JRE....

% java -jar NotePad.jar
NotePad-application
running with JRE-version 1.5.0_06

The same launcher as above uses 1.6.0 version of the JRE...

% java -jar PhotoEdit.jar
PhotoEdit-application
running with JRE-version 1.6.0

On Solaris 2.6 and newer one can execute the JAR file directly,

% chmod +x \*.jar 
% ./PhotoEdit.jar
PhotoEdit-application
running with JRE-version 1.6.0
% ./NotePad.jar
NotePad-application
running with JRE-version 1.5.0_06

The above works on Windows too, by double clicking the JAR file in Windows Explorer. See JAR Guide for more details.

Supposing the JARs are sealed and one can acheive the same end result by using command line syntax of the launcher as follows:

java -version:1.5\* -jar NotePad.jar ..........
java -version:1.6+ -jar PhotoEdit.jar.......

Note: Its a very bad idea to tie to a specific release of the JRE insteand select a range ex: 1.5\* to stay within the 1.5 and its updated releases or 1.5+ to simply select a newer version of the JRE than 1.5 if available.


So how does this all work ?

In order for the MJRE to reliably find other installed instances of J2SE it performs lookups, and the lookup varies depending on the platform, described as follows:

On Windows: The Windows installer will update the Windows registry hive at "HKLM\\SOFTWARE\\JavaSoft\\Java Runtime Environment". The JRE installer will also copy the launchers to "C:\\Windows\\system32\\", which is on the %PATH%, therefore invoking the command "java" will execute the latest launcher, which in turn will invoke a JRE matching the version constraint, specified in the Manifest or on the command line.

On Solaris: The launcher behaves much like Windows, meaning,  the launchers selects a suitable JRE satisfying the constraint. The launcher typically searches the /usr/jdk (installed by the Solaris pkgadd facility, typically by a Systems Administrator or persons having "root" access) and $HOME/jdk (a users private stash) for instances of the JRE.

On Linux: Similar to the Solaris launcher and will search the  /usr/java repository, instead of /usr/jdk for any system wide instances of the JRE.

Summary: 

The MJRE feature is extremely useful to constrain or select a suitable JRE for an application, provided the JREs are laid out in the filesystem correctly as described above. Noting that, its not at all a good idea to "over-constrain" the selection process, such that the selection is tied to a specific release. Over constraining will not allow the application to use updated versions of JREs, containing critical fixes.

References:

 

An Ant example script to test all of the above.

 <project name="launcher_example" default="all" basedir="./">
  <!-- Requires ant 1.7.0 and JDK 1.5 or better-->
  <!-- set global properties for this build -->
  <property name="src" value="src"/>
  <property name="build" value="build"/>
  <property name="dist"  value="dist"/>

  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <!-- Create the build directory structure used by compile -->

    <mkdir dir="${src}"/>
    <mkdir dir="${src}/NotePad"/>
    <mkdir dir="${src}/PhotoEdit"/>
    <mkdir dir="${build}"/>
    <mkdir dir="${build}/NotePad"/>
    <mkdir dir="${build}/PhotoEdit"/>
    <mkdir dir="${dist}"/>
  </target>

  <target name="createNotePad">
     <echo file="${src}/NotePad/NotePad.java">
public class NotePad {  
   public static void main(String[] args) {
        System.out.println("NotePad-application");
        System.out.print("    running with JRE-version ");
        System.out.println(System.getProperty("java.version"));
        System.exit(0);
    }
} </echo>
  </target>
  <target name="createPhotoEdit">
     <echo file="${src}/PhotoEdit/PhotoEdit.java">
public class PhotoEdit {
   public static void main(String[] args) {
     System.out.println("PhotoEdit-application");
     System.out.print("    running with JRE-version ");
     System.out.println(System.getProperty("java.version"));
     System.exit(0);
   }
}</echo>
  </target>
    <target name="notepad" depends="init, createNotePad">
    <!-- Compile the java code from ${src} into ${build} -->
    <javac
        target="1.5"
        srcdir="${src}/NotePad"
        destdir="${build}/NotePad"
        excludes="\*\*/SCCS/\*"
        classpath=""
        verbose="no"
    />
    <jar destfile="${dist}/NotePad.jar">
        <manifest>
        <attribute name="Main-Class" value="NotePad"/>
        <attribute name="JRE-version" value="1.5\*"/>
        </manifest>
    <fileset dir="${build}/NotePad"/>
    </jar>
  </target>

  <target name="photoedit" depends="init, createPhotoEdit">
    <!-- Compile the java code from ${src} into ${build} -->
    <javac
        target="1.6"
        srcdir="${src}/PhotoEdit"
        destdir="${build}/PhotoEdit"
        excludes="\*\*/SCCS/\*"
        classpath=""
        verbose="no"
    />
    <jar destfile="${dist}/PhotoEdit.jar">
        <manifest>
        <attribute name="Main-Class" value="PhotoEdit"/>
        <attribute name="JRE-version" value="1.5+"/>
        </manifest>
    <fileset dir="${build}/PhotoEdit"/>
    </jar>
  </target>

  <target name="all" depends="photoedit, notepad">
    <chmod perm="ugo+x">
        <fileset dir="${dist}">
         <include name="\*\*/\*.jar"/>
        </fileset>
    </chmod>
    <exec executable="${dist}/PhotoEdit.jar"/>
    <exec executable="${dist}/NotePad.jar"/>
  </target>

  <target name="clean">
    <!-- Delete the ${build} and ${dist} directory trees -->
    <delete dir="${src}"/>
    <delete dir="${build}"/>
    <delete dir="${dist}"/>
  </target>
</project>

 

 

 

 

Comments:

How is this going to accommodate the use of other JRE? What algorithm do you use to detect which JRE has been installed on the machine? How are you going to work with JDK from different vendors? In an enterprise settings people would like to have a fixed version of Java to be used, even down to the service release level. The syntax for that in JNLP is a bit difficult to use and has caused a lot of problems for us.

Posted by Sunny Chan on May 30, 2007 at 07:07 AM PDT #

Post a Comment:
Comments are closed for this entry.
About

ksrini

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today