Tuesday, February 14, 2012

Swing applications deployment on Windows

I thought I'd start another series of posts about deploying Java applications on different platforms. This is one of the commonly overlooked aspects of application development, so it would be useful to shed some light on it. This series will cover creating native distribution packages for Windows, Mac OS X and Linux (RPM and DEB packages).
These are the features that we want from  native packages:
  • using platform native installer system
  • automatic detection and installation of correct JRE
  • creating application shortcuts and registerign any required application information
  • creating uninstalation script

This post will cover building native Windows installers using NSIS. NSIS is Nullsoft's scriptable installer system which is widely used to build Windows application installers. It has a lot of plugins available that will help in building our native installer.  For this example, I will use NSIS Inetc, which will be used to download and install required JRE if it is not present on target machine. Informaion on how to install a plugin can be found here.
For this example, I will use a simple Swing application .jar file (which can be found in attached source code) and a .bat file that will be used to launch JRE. It would be better (from integration point of view) to use native code for launcher, but the script will do.
First , I will layout a directory structure. You can see it at the following image:
Project directory structure
  • setup.nsi - NSIS script that will be used by compiler to produce installer
  • JREDyna_Inetc.nsh - header file for JRE detection and installation (can be found here )
  • myapp - application directory structure as will deployed to target machine
Now's the time to start with installation script. Here, I will outline only the most important parts, but you can find entire source code attached with this post.

!include "MUI2.nsh"

;------------------------------------


;---------------------------------------------------
; General data

; The name of the installer
Name "MyApp"


; The default installation directory
InstallDir $PROGRAMFILES\myapp

; The text to prompt the user to enter a directory
DirText "This will install MyApp on your computer. Choose a directory"

; Output file name
OutFile "myapp-setup.exe"
In the first line, we include "modern UI", ie. enhanced user interface for the installer. The rest of the section is the general data:
  • Name - installer name
  • InstallDir - target installation directory
  • DirText - text string to be displayed for choosing installation directory
  • OutFile - file name of the final installer file
;Interface settings

 !define JRE_VERSION "1.7"
 !define JRE_URL "http://download.oracle.com/otn-pub/java/jdk/7/jre-7-windows-i586.exe"
 !include "JREDyna_Inetc.nsh"
 
 !define MUI_ABORTWARNING
 !define MUI_WELCOMEPAGE_TITLE "Welcome to Acapulco Framework installation"
 !define MUI_WELCOMEPAGE_TEXT "This will install MyApp on your computer."

 ; Start menu page configuration
 !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU" ; registry key for Start menu folder
 !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\MyApp" 
 !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "myapp"

 ;Finish page configuration
 !define MUI_FINISHPAGE_TEXT "Installation completed"

This section provides settings for user interface and required JRE detection and instalaltion (required versiona nd download URL), and also includes additional script for detection and installation.

The following section shows installer pages displayed during installation and uninstallation:
; Installer pages

 !insertmacro MUI_PAGE_WELCOME
 !insertmacro CUSTOM_PAGE_JREINFO
 !insertmacro MUI_PAGE_DIRECTORY
 !insertmacro MUI_PAGE_STARTMENU Application $StartMenuFolder
 !insertmacro MUI_PAGE_INSTFILES
 !insertmacro MUI_PAGE_FINISH
  

 ; Uninstaller pages
 !insertmacro MUI_UNPAGE_WELCOME
 !insertmacro MUI_UNPAGE_CONFIRM
 !insertmacro MUI_UNPAGE_INSTFILES
 !insertmacro MUI_UNPAGE_FINISH

Finally, this is the section that does actual file deployment and shortcuts creation:

; Installer section
Section "Install"

; Set output path to the installation directory.
SetOutPath $INSTDIR

 call DownloadAndInstallJREIfNecessary

; Put file there
File myapp\systray-test.jar
File myapp\run.bat
File myapp\launcher-small.ico
File myapp\launcher-big.ico


; Tell the compiler to write an uninstaller and to look for a "Uninstall" section
WriteUninstaller $INSTDIR\Uninstall.exe

; Create Start menu items
 !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
    
    ;Create shortcuts
    CreateDirectory "$SMPROGRAMS\$StartMenuFolder"
    CreateShortCut "$SMPROGRAMS\$StartMenuFolder\MyApp.lnk" "$INSTDIR\run.bat"
    CreateShortCut "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
  
  !insertmacro MUI_STARTMENU_WRITE_END

SectionEnd ; end the section

Section "DesktopShortcut"

 CreateShortcut "$DESKTOP\MyApp.lnk" "$INSTDIR\run.bat"
SectionEnd

; The uninstall section
Section "Uninstall"


Delete $INSTDIR\systray-test.jar
Delete $INSTDIR\run.bat
Delete $INSTDIR\launcher-big.ico
Delete $INSTDIR\launcher-small.ico
Delete $INSTDIR\Uninstall.exe
RMDir $INSTDIR

; Remove Start menu items
 !insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuFolder
    
  Delete "$SMPROGRAMS\$StartMenuFolder\Uninstall.lnk"
  RMDir "$SMPROGRAMS\$StartMenuFolder"

 ;Remove Desktop shortcut
 Delete "$DESKTOP\MyApp.lnk"
  
  DeleteRegKey /ifempty HKCU "Software\MyApp"

SectionEnd ; end the section

This section is mostly self-descriptive: first, we set output path. Then, define what files should be written. Following is the start menu and desktop shortcut creation section.
Final section is "Uninstaller", which removes all installed files and created shortcuts.

The last step is compiling the script with NSIS installer:

 makensis setup.nsi

This will produce myapp-setup.exe installer. When run, it will guide the user through all familiar steps of Windows app installation. In addition, if no required JRe version is found, it will download and install it as part of installation process. You can see the installer in action in the images bellow:

Installer welcome page

Target location selection
Start menu shortcut selection

Installtion complete

Start menu with MyApp shortcuts


Finally, here is the entire source code and some useful resource pages.
 

4 comments:

  1. We mostly deploy swing application using jnlp web start by hosting it on weblogic server. that gives user option to download and run it using webstart. By the way good start and thanks for sharing knowledge.

    Thanks
    Difference between InvokeAndWait and InvokeLater

    ReplyDelete
    Replies
    1. Yes, WebStart is definitely "Java way", ie. cross platforom. This is just an attempt to provide better desktop integration for end-users, giving them consistent installation options.

      Delete
  2. I am getting this error can u please help me
    Invalid command: Inetc::get
    !include: error in script: "JREDyna_Inetc.nsh" on line 96
    Error in script "C:\Users\Ambuja\Desktop\code\setup.nsi" on line 42 -- aborting creation process

    ReplyDelete
  3. really loved the screenshots in your post. keep it up.

    thanks
    Animations in Rich apps

    ReplyDelete