|
software | articles | professional |
| Articles index | |||
Deploying Swing Applications on the DesktopLast updated: 2007-09-05The old addage says that the three most important things in real estate are location, location, and location. Those of us who develop Java Swing applications might agree that the same can be said of GUI applications. You can have the best application on the planet, but if users can't run it on their computers, then it's essentially useless. Unfortunately, when it comes to distributing their desktop applications, Swing developers can be at a disadvantage. Applet developers can distribute their applications easily enough; simply embed them in a publicly-available Web page. Java Web Start has made Web-based distribution of desktop-like applications a bit easier. But both of those models have their limitations. Sometimes, you just want to package your Swing app like a normal application! Oh, and if you're a small-time shareware developer like me, you want to do it at as low a cost as possible... preferably free. In this article, I'll show you how to distribute Swing applications that behave just like native applications. I focus on Mac OS X and Windows in this article. I don't include Linux here, because I've found that the average Linux user is a bit more tech savvy than the average Mac or Windows user, and simply distributing a JAR file tends to suffice there. The ol' double-clickable JAR approachBy now, every Swing developer knows that they can create a double-clickable JAR out of their Swing applications. This approach involves little more than packaging your application into a JAR file ,and including a manifest file, named
Of course, by now every Swing developer knows the downsides of such an approach. First of all, it's ugly. There is no way to include a custom icon, for example, with your JAR file. So your users will always see the standard Java icon... hardly a professional look for your application. Similarly, when the user launches the application, they won't see a custom application icon in the taskbar (on Window) or dock (on the Mac). An additional problem is that you can't be sure your user will even be able to launch the application. While most Mac OSX users will have Java installed, many Windows users may not. And even if they do, the path to a java.exe or javaw.exe executable must be present in the user's path. If any of those criteria aren't met, then users can double-click on your JAR file until their mortgages are paid off, but they won't launch your application.
The Mac OS X SolutionFortunately, a better solution exists... at least for our Max OS X users. OS X was designed to be one of the best platforms for running Java applications. Okay, so they may have lagged behind a release cycle or two in terms of updating their Java runtime. But they still offer developers a good—and more importantly, free—way to make Java applications behave like native applications. Users can not only double-click on your application to launch it, but you can also provide a custom icon for your application. Apple's developer site has a good article on packaging a native-like Java application using Apple's JAR Bundler application. Follow the easy steps in that article, and you'll have a native-looking application bundle to give to your users. Actually distributing your application requires an additional step. Your application will actually be bundled into a series of folders and subfolders. The Creating a disk image is easy enough. First, launch the Disk Utility application (it's normally found under Applications -> Utilities. Then create a new disk image via File -> New -> Blank Disk Image.... In the dialog that should appear, choose a location to save your disk image to, and a suitable name (e.g. MyApplication.dmg). Be sure to select a size into which will fit your application, along with any other documentation you might want to include. I've found that Encryption is not necessary, and the Format I've tended to use is read/write disk image. Click the Create button, and OS X will create the disk image for you. Now, find your disk image in the location you'd chosen in the previous step. Double-click to mount the disk image (if OS X doesn't automatically open the mounted disk image, double-click to open it). Drag your application bundle, and any other documentation you want to distribute, into the mounted disk image's window. Then drag the mounted disk image (but not the .dmg file you'd created) to the trash to unmount it. Finally, you'll want to GZIP your disk image. To do this, open a Terminal window and What about Windows?That's fine for your OS X users, but what about the other 90ish% of your users? Again, you'll need to perform two steps here: 1. create a native-looking, double-clickable executable and 2. put that executable in an easily-distributable form. Regarding that latter point, while many OS X applications do not ship with installers these days, most Windows applications still do. So for that reason, we're going to create an installer for our app. Double-clickableBut first, let's create that double-clickable application. We'll create a native wrapper around our Swing application which, when double-clicked, will launch our Swing application but behave just like a native application. There are a few good tools out there for creating such a wrapper. I tried two: Launch4J and JSmooth. Both are freely-available on SourceForge. I found that I had the best luck with JSmooth, so that's what I'll focus on here. First, a word on how JSmooth works. Depending on how you configure it, it will create a .exe file that contains both a small Windows application, as well as your JARred Swing app. What it does not include is a JRE. That's up to you to distribute with the .exe file; or, if you're confident that your users will already have a JRE installed and in their PATH environment variable, you can choose not to include a JRE at all. Me, I'm not that confident, so I usually distribute a JRE alongside my .exe file. Go ahead and download and install JSmooth. Then create a directory structure to manage your files. I created the following structure: C:\ InstallPackages\ Application1\ jsmooth-config\ output\That structure assumes that you'll be distributing and application called Application1.
JSmooth allows you to create an executable wrapper around your Swing app, and provide an application icon. Once you've done that, launch JSmooth. Then go ahead create the JSmooth config file by choosing System -> Save As... and choosing the jsmooth-config directory created above. Turning back to JSmooth, notice that the column on the left-hand side provides navigation through the various steps. Start by clicking on the Skeleton link. Your first option is the Message box; this defines a message to provide to users if JSmooth cannot find a valid JRE. Note that this option will likely only be an issue if you choose not to ship a JRE. But it's probably a good idea to ensure that this message is to your liking even if you do ship your own JRE, just in case something unexpected happens. Note that the message will be presented within a Yes/No dialog, so the crux of the message should be a question to the as to whether they want to download a current JRE. Underneath is the URL line; this is the URL that users who answer Yes to the above message will be taken to. The next option, Launch java app in the exe process, should be checked. That way, the user won't see two separate processes—the exe and the Java process—when they launch the application. Select the Single instance checkbox if only one instance of your application should be running at one time. JSmooth offers what it calls JNISmooth, which is a simple API offering a few native Windows hooks. If you decide to make use of the API, then of course select the Use JNISmooth classes checkbox. Finally, for your final distribution package, leave the Debug console checkbox unchecked. Next, we'll define the output file in the Executable section. In the Executable Binary field, define the output file that JSmooth will create. Use the file-browse button and navigate to the output directory you should've created above; use that as your final output directory (and be sure the name of the final output file ends with .exe). In the Executable Icon, you point JSmooth to the image file you want to use as your application's icon. Note that if you use the filesystem-browse buttons in the above two fields, JSmooth (somewhat unusually) stores the file locations as paths that are relative to the directory in which your config settings are stored (e.g. the jsmooth-config directory). Finally, select the Sets the executable folder as current directory of the application checkbox. Now click on the Application button to define your Java-specific settings. Start with the field called Embedded jar. Select the Use an embedded jar checkbox (this will cause JSmooth to embed your JAR within the final /exe file, so that you don't need to distribute it separately.) Then in the textfield, tell JSmooth where your application's JAR file is located. Note that, as with the Executable section, JSmooth prefers file paths relative to the config directory, and will store the path as such if you use the provided file-browse button. Once you've defined your JAR file, go back up to the Main class field. Click the provided class-browse button next to the textfield; JSmooth will list all classes with a Click on the JVM Selection button. This is where you will define the JVM that your application is to use. If you're like me, you don't want to assume that your Windows users will have a JVM installed and accessible, so you'll want to bundle your own JVM. This requires a quick detour to your file system. Navigate to the output directory you'd created in the directory structure above. Open another window and navigate to your preferred JRE installation (I assume, of course, that you have a JRE—as opposed to a JDK—installed on your system. If not, grab one from java.com.) Copy the entire JRE folder into the output directory. Now return to JSmooth. Select the checkbox named Use a JVM bundled with your application. In the textbox below, enter ..\jre. This path is supposed to tell the executable where to find the bundled JRE, relative to the executable itself. Remember from above that you've told JSmooth to save the final .exe file to the output directory, alongside the jre/ directory. So why do you need to enter ..\jre instead of just jre? It's hard to say, but it appears that JSmooth treats the executable as its own directory, rather than as merely a file. At any rate, I learned after much trial and error that it's required. If you're embedding a JRE, that's all you need to do in the JVM Selection section. If you're not bundling a JRE, then you'll need to pay attention to the other fields. The purposes of the Minimum JVM Version and Maximum JVM Version fields should be self-explanatory. However, you'll want to be sure you don't accidentally limit the range of acceptable JVM versions unnecessarily. While setting a proper value for Minimum JVM Version is easy enough (as long as you provide a decimal number; e.g. 5.0 instead of 5), pay attention to the tooltip advice for Maximum JVM Version. Usually, it's just best to leave that field empty, indicating that there is no maximum version number. Finally, the JVM Search Sequency defines where, and in what order, the executable will search for a valid JRE. Finally, go to the JVM Configuration section. If you have no properties to set and you're fine with the default Java memory allocation settings, then you can safely ignore this screen. Otherwise, enter your own values for Maximum Memory (which is the equivalent of the -Xmx switch) and/or Initial Memory Allocation which is equivalent to the -Xms switch. You can also use the buttons next to the Java Properties field to enter any name/value pairs of system properties you want set. At this point, you're done configuring your executable. So, let's build it! Simply go to the Project -> Compile... menu item. JSmooth will build your executable, providing the progress in a popup dialog. Once it completes, go back to your filesystem and navigate to the output folder. Double-click the .exe file that should now be there. You now have a pure Java Swing application that behaves like a native Windows app! A Windows InstallerNow, we want to create an installer for our application. Most installer applications are unfortunately on the expensive side. But a few offer free—and severly limited—versions. One such installer is Advanced Installer by Caphyon. While their for-pay installer options can be cost-prohibitive for many small-time developers (although, to be honest, even their for-pay fees are much more reasonable than many other out there), they do offer free functionality. To get at this free functionality, download and install their Advanced Installer product. When you launch it, you will be presented with a number of product types to choose from. However, if you haven't paid to register your copy, Simple is the only option you can work with. That's fine really; it provides enough functionality to install a basic application.
With Advanced Installer, you simply define the files and folders that will appear in your user's installation directory. Once you've selected Simple and clicked OK, you can configure your application. Like JSmooth, Advanced Installer provides navigation between screens in the left-hand column. Select Product Details. Most of the fields here are self-explanatory; they simply server to provide information about your product to your users. Once you've filled out these fields, go to the Install Parameters screen. Most of the defaults should suffice here, although you might want to tweak some. Similarly, I've found that, given that we're installing a Java application, the Prerequisites screen can be mostly ignored. Now go to the Files and Folders screen. It is here that you define the files and folders that will be installed. In our case, the consists of the contents of the output folder we'd created. Notice that Advanced Installer provides a filesystem view of the Target Computer. The directory entitled Application Folder depicts the directory into which we'll install the contents of our output directory. Click to select Application Folder, then click the Add Folder button at the top (the folder with a + symbol on it). Browse to the jre/ directory in output, and click OK. Then click the Add Files button (the files with a + symbol on them), browse to the .exe file in the output directory, and click OK. Now, you're ready to build your installer! First, let's save the settings by selecting File -> Save As.... Tell Advanced Installer to save the settings in the Application1 folder created earlier. This is also where the installer will be built. Once you've done that, click the build button at the top (the icon that looks like a brick wall being built.) Advanced Installer will build your installer, providing a progress dialog along the way. Once it's done, you'll have a .msi Windows installer for you application. Try it out by going to the Application1 directory and double-clicking. You should be able to install your application, the same way you would any other Windows application! ConclusionSo you can see that, despite conventional wisdom, it's neither difficult nor expensive to get your Swing application onto user's computers. Rather, there are good tools out there to help you package up your app for various platforms out there, without requiring you to take out a second mortgage to do so. Privacy Policy: Any information collected, whether from online help, registration, or any other means, will be used only for support purposes. Such uses are: to send customers registration information, to verify that a user is registered in order to provide support, and to notify the user if an important or useful bug fix or upgrade has been made. Under no circumstances will customer information be sold or otherwise given to any other party, person, or organization. We're in the business to develop software, not sell people's information. |
|||
| Articles | blog | index |