Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Packaging Java apps for the Windows/Linux desktop

I am writing an application in Java for the desktop using the Eclipse SWT library for GUI rendering. I think SWT helps Java get over the biggest hurdle for acceptance on the desktop: namely providing a Java application with a consistent, responsive interface that looks like that belonging to any other app on your desktop. However, I feel that packaging an application is still an issue.

OS X natively provides an easy mechanism for wrapping Java apps in native application bundles, but producing an app for Windows/Linux that doesn't require the user to run an ugly batch file or click on a .jar is still a hassle. Possibly that's not such an issue on Linux, where the user is likely to be a little more tech-savvy, but on Windows I'd like to have a regular .exe for him/her to run.

Has anyone had any experience with any of the .exe generation tools for Java that are out there? I've tried JSmooth but had various issues with it. Is there a better solution before I crack out Visual Studio and roll my own?

Edit: I should perhaps mention that I am unable to spend a lot of money on a commercial solution.

like image 435
alexmcchessers Avatar asked Aug 11 '08 12:08

alexmcchessers


People also ask

How do you package Java apps?

The recommended way to package Java applications is to use a collection of Ant tasks ( ant-javafx. jar ), which are provided with the JRE. NetBeans IDE uses these Ant tasks to package JavaFX and Java SE projects. Embedded packaging support in NetBeans IDE covers most of the typical use cases.

Can Java apps run on Linux?

Java is the world's popular software development platform that James Gosling develops. It is designed to support multiple platforms like Linux, macOS and Windows. Mobile and Desktop applications can also be developed using Java language.

Is Java still used for desktop applications?

Java is used to build robust and platform independent applications in many domains. This language is used for developing Android applications, web applications, desktop applications and many more. Also, it is the most preferred language to be learnt among students and professionals.


1 Answers

To follow up on pauxu's answer, I'm using launch4j and NSIS on a project of mine and thought it would be helpful to show just how I'm using them. Here's what I'm doing for Windows. BTW, I'm creating .app and .dmg for Mac, but haven't figured out what to do for Linux yet.

Project Copies of launch4j and NSIS

In my project I have a "vendor" directory and underneath it I have a directory for "launch4j" and "nsis". Within each is a copy of the install for each application. I find it easier to have a copy local to the project rather than forcing others to install both products and set up some kind of environment variable to point to each.

Script Files

I also have a "scripts" directory in my project that holds various configuration/script files for my project. First there is the launch4j.xml file:

<launch4jConfig>   <dontWrapJar>true</dontWrapJar>   <headerType>gui</headerType>   <jar>rpgam.jar</jar>   <outfile>rpgam.exe</outfile>   <errTitle></errTitle>   <cmdLine></cmdLine>   <chdir>.</chdir>   <priority>normal</priority>   <downloadUrl>http://www.rpgaudiomixer.com/</downloadUrl>   <supportUrl></supportUrl>   <customProcName>false</customProcName>   <stayAlive>false</stayAlive>   <manifest></manifest>   <icon></icon>   <jre>     <path></path>     <minVersion>1.5.0</minVersion>     <maxVersion></maxVersion>     <jdkPreference>preferJre</jdkPreference>   </jre>   <splash>     <file>..\images\splash.bmp</file>     <waitForWindow>true</waitForWindow>     <timeout>60</timeout>     <timeoutErr>true</timeoutErr>   </splash> </launch4jConfig> 

And then there's the NSIS script rpgam-setup.nsis. It can take a VERSION argument to help name the file.

; The name of the installer Name "RPG Audio Mixer"  !ifndef VERSION     !define VERSION A.B.C !endif  ; The file to write outfile "..\dist\installers\windows\rpgam-${VERSION}.exe"  ; The default installation directory InstallDir "$PROGRAMFILES\RPG Audio Mixer"  ; Registry key to check for directory (so if you install again, it will  ; overwrite the old one automatically) InstallDirRegKey HKLM "Software\RPG_Audio_Mixer" "Install_Dir"  # create a default section. section "RPG Audio Mixer"      SectionIn RO      ; Set output path to the installation directory.     SetOutPath $INSTDIR     File /r "..\dist\layout\windows\"      ; Write the installation path into the registry     WriteRegStr HKLM SOFTWARE\RPG_Audio_Mixer "Install_Dir" "$INSTDIR"      ; Write the uninstall keys for Windows     WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RPGAudioMixer" "DisplayName" "RPG Audio Mixer"     WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RPGAudioMixer" "UninstallString" '"$INSTDIR\uninstall.exe"'     WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RPGAudioMixer" "NoModify" 1     WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RPGAudioMixer" "NoRepair" 1     WriteUninstaller "uninstall.exe"      ; read the value from the registry into the $0 register     ;readRegStr $0 HKLM "SOFTWARE\JavaSoft\Java Runtime Environment" CurrentVersion      ; print the results in a popup message box     ;messageBox MB_OK "version: $0"  sectionEnd  Section "Start Menu Shortcuts"   CreateDirectory "$SMPROGRAMS\RPG Audio Mixer"   CreateShortCut "$SMPROGRAMS\RPG Audio Mixer\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0   CreateShortCut "$SMPROGRAMS\RPG AUdio Mixer\RPG Audio Mixer.lnk" "$INSTDIR\rpgam.exe" "" "$INSTDIR\rpgam.exe" 0 SectionEnd  Section "Uninstall"      ; Remove registry keys     DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\RPGAudioMixer"     DeleteRegKey HKLM SOFTWARE\RPG_Audio_Mixer      ; Remove files and uninstaller     Delete $INSTDIR\rpgam.exe     Delete $INSTDIR\uninstall.exe      ; Remove shortcuts, if any     Delete "$SMPROGRAMS\RPG Audio Mixer\*.*"      ; Remove directories used     RMDir "$SMPROGRAMS\RPG Audio Mixer"     RMDir "$INSTDIR"  SectionEnd 

Ant Integration

I have some targets in my Ant buildfile (build.xml) to handle the above. First I tel Ant to import launch4j's Ant tasks:

<property name="launch4j.dir" location="vendor/launch4j" /> <taskdef name="launch4j"      classname="net.sf.launch4j.ant.Launch4jTask"     classpath="${launch4j.dir}/launch4j.jar:${launch4j.dir}/lib/xstream.jar" /> 

I then have a simple target for creating the wrapper executable:

<target name="executable-windows" depends="jar" description="Create Windows executable (EXE)">     <launch4j configFile="scripts/launch4j.xml" outfile="${exeFile}" /> </target> 

And another target for making the installer:

<target name="installer-windows" depends="executable-windows" description="Create the installer for Windows (EXE)">     <!-- Lay out files needed for building the installer -->     <mkdir dir="${windowsLayoutDirectory}" />     <copy file="${jarFile}" todir="${windowsLayoutDirectory}" />     <copy todir="${windowsLayoutDirectory}/lib">         <fileset dir="${libraryDirectory}" />         <fileset dir="${windowsLibraryDirectory}" />     </copy>     <copy todir="${windowsLayoutDirectory}/icons">          <fileset dir="${iconsDirectory}" />     </copy>     <copy todir="${windowsLayoutDirectory}" file="${exeFile}" />      <mkdir dir="${windowsInstallerDirectory}" />      <!-- Build the installer using NSIS -->     <exec executable="vendor/nsis/makensis.exe">         <arg value="/DVERSION=${version}" />         <arg value="scripts/rpgam-setup.nsi" />     </exec> </target> 

The top portion of that just copies the necessary files for the installer to a temporary location and the second half executes the script that uses all of it to make the installer.

like image 77
Brian Kelly Avatar answered Sep 22 '22 03:09

Brian Kelly