The Fnordistan Department of Software Engineering

How to Package a VisualWorks Application

The Problem:

You have written a Smalltalk application using Cincom's VisualWorks. You want to package it as a runtime executable, rather than a development image.

The Solution:

This is actually not hard to do, but it requires several steps, the instructions for which are distributed among several sources.

First of all, realize that runtime images will run on any platform that has VisualWorks installed. So you can distribute the runtime image you developed in Windows, and it will run on Linux or Macs, as long as those machines have Cincom's Smalltalk Virtual Machine installed. If you want an executable that runs without the user needing VisualWorks installed on his machine, you can do this with a few more steps, but only for Windows.

Part 1:

Creating the Runtime Image

First, very important: close all VisualWorks windows except the main (transcript) window! Close any system browsers, workspaces, dialog boxes, and of course, the application itself if you had it open. This seems obvious in retrospect, but the first few times I packaged my application, I left a workspace open during the packaging process, and was mystified when after creating the runtime, it always crashed. The error.log contained several sections like this:

[1] ToolbarIconLibrary class(Object)>>doesNotUnderstand:
Receiver: (id=10838) ToolbarIconLibrary
Arg1: (id=8515) a Message with selector: #fileNew20x20 and arguments: #()

There were workarounds for this, which I obtained from the ever-helpful vwnc mailing list, but the reason I needed the work-arounds in the first place was that by leaving the workspace open, I was requiring that all its toolbar icons be included in the runtime image! So close anything you don't need open before you begin packaging your application.

Now, from your development image, unload the UIPainter parcel, and load the RuntimePackager parcel.

RuntimePackager 7

Now RuntimePackager will appear in your Tools menu. Select it.

RuntimePackager in the Tools menu

RuntimePackager is a tool that turns a development image into a stripped-down runtime image containing only what is required for the application to run. In general, you will proceed through each step (by clicking "Next >>" followed by "Do this step").

RuntimePackager Overview

Clean Up Image

Do this. You will get the following dialog box:

RuntimePackager: Clean Up

Choose Yes. You will then probably see one or two "DependentsFields" windows pop up. Just close them and proceed.

RuntimePackager Clean Up: DependentsFields

Set Common Options

Do this. You will see a dialog box like this:

RuntimePackager: Set common options

Note that I have filled in the values using my SmallRoller application as an example. The Startup Class is the Class of your main application. (Note that I am assuming here that you are packaging a GUI application. Non-GUI, or "headless" applications, are outside the scope of this tutorial.) Startup Method is the method of that Class that actually opens the main window for the application. This is the message you want sent as soon as the image is opened. For SmallRoller, I wrapped the open message in the initialize message, like so:

initialize
"Opens the GUI automatically on initialization"

self open.
^self

However, you could just as easily use open as your Startup Method.

The Runtime Image Path Name is the runtime image that will be saved by RuntimePackager. I didn't change the default name here, because you can always rename it once you're done.

The other tabs ("Details", "Platforms", etc.) are advanced options we won't cover in this tutorial.

Specify classes and methods to keep

RuntimePackager finds most of the classes and methods your application needs automatically. However, it might miss some. You can use this step to specify classes and/or methods you know you will need and that RuntimePackager tends to leave out. For now, I am going to skip this step, because we're going to come back to it after testing (below). So click "Next >>".

Scan for unreferenced items

Do this.

RuntimePackager: Scan for unreferenced itmes

Review kept classes and methods

This is another opportunity to review classes and methods to be included in your final runtime image.

Save runtime loadable parcels

I won't be covering this here -- you won't need to do this unless you specified some parcels used in your application as loadable at runtime, which usually won't be the case for a simple stand-alone application.

Test Application

You can skip this test if you have done it previously and are confident that your runtime image has everything it needs. However, you should normally do this. It will help us find classes and methods that weren't included automatically by RuntimePackager.

RuntimePackager: loading tester

Once all the wrappers are installed, your application should appear. Make sure it works. (If it doesn't appear or something doesn't work, obviously, something is wrong.) What is of more interest to us is what happens after you close the application and click "End Test."

RuntimePackager: Dynamic references found after testing

If the "Dynamic References" box is empty after you finish testing, you are fine. However, here we can see that some classes used in my application were not packaged by RuntimePackager. I do not want to accept the dynamic references. When you click OK, you will get another dialog box asking if you want to accept the dynamic references. Choose No. Instead, we are going to go back and specify those classes and methods for inclusion.

I click "<< Previous" until I get back to Specify Kept/Deleted, and then choose "Do this step" again.

Here, we are going to browse the classes and make sure to include those that were found as dynamic references.

RuntimePackager: Specifying classes for inclusion

I could choose only the specific methods mentioned under VWHelp.ArborTextAttributes, but I will include the entire class to make it simple. (This class was dynamically referenced in my application because I used some fonts specified in the VWHelp parcel.) Then I add the UI.ControllerWithSelectMenu class.

Now we must repeat our earlier steps, particularly Scan for unreferenced items. When we reach testing, we run the test again. This time, the Dynamic References box should be empty when we're finished. If it is, we can move on.

Set runtime memory parameters

These are advanced options which we are going to skip.

Strip and save image

This is the final step. It creates the stripped runtime image.

When you see the dialog box below, choose Yes.

RuntimePackager: Strip image and close windows

Then you get this final dialog box. Choose Yes.

RuntimePackager: Final step in stripping the image

The Runtime Image

If all goes well, RuntimePackager will proceed to close all your VisualWorks windows, strip the image, open and close another dialog box, and finally, close everything.

RuntimePackager: Stripping the image

When it's done, you should find in the same directory as your development image a new runtime image with the name you specified in Set common options. In this example, it should be called runtime.im.

Open your runtime image, and rather than a VisualWorks window, you should see your GUI application start. You now have a runtime image!

In Part 2....

I will describe how to compress your runtime image and package it.