Creating a Simple Runtime
I received a question about creating a runtime image via my chatback widget this morning - I've done screencasts on that, but those use BottomFeeder as an example. While that's a real example, it's also fairly large, and somewhat complex. So - I thought a very simple example might be useful.
First, I created a new package, and then a new class (subclassed from Object) with no instance variables.
Smalltalk defineClass: #Sample superclass: #{Core.Object} indexedType: #none private: false instanceVariableNames: '' classInstanceVariableNames: '' imports: '' category: ''
I gave this class one method:
doMyThing Transcript show: 'This is from the Sample App'; cr. ObjectMemory quit.
So that the results are clear, I ran the application in headless mode - the Transcript write drops to a file called 'headless-transcript.log' (that's configurable, but never mind). Next, I need a way to have this application startup. I created a new class:
Smalltalk defineClass: #SampleUserApp superclass: #{Core.UserApplication} indexedType: #none private: false instanceVariableNames: '' classInstanceVariableNames: '' imports: '' category: ''
That's a class that exists to define a startup procedure. You create a new method called #main, and put your startup code there:
main Sample new doMyThing.
Next, I need a script that creates a new image, and puts it into "runtime" mode - the #main method will not fire unless the image is in that state. Here's the script:
"build a simple app" "load all my needed parcels (Non-Windows)" [#('SampleApp.pcl') do: [:each | Parcel loadParcelFrom: each]] on: MissingParcelSource do: [:ex | ex resume: true]. "turn change log off, so that we can ship patches reasonably" 'ChangeSet.BroadcastChanges' asQualifiedReference ifDefinedDo: [:flag | 'ChangeSet.BroadcastChanges' asQualifiedReference value: false]. "Set herald string" ObjectMemory setHeraldString: 'This is an Example Application in VisualWorks'. "reset parcel path" Parcel searchPathModel value removeAll. "set up runtime state" DeploymentOptionsSystem current startInRuntime: true. "set up runtime state" UI.WindowManager noWindowBlock: [:windowManager | ]. stream := WriteStream on: String new. stream nextPutAll: 'changeRequest'; cr; cr; tab. stream nextPutAll: '^true'. VisualLauncher compile: stream contents. VisualLauncher allInstances do: [:each | each closeAndUnschedule. each release]. ObjectMemory garbageCollect. Workbook allInstances do: [:each | each closeRequest]. (Delay forSeconds: 20) wait. Parcel searchPathModel value: (List with: (PortableFilename named: '.')). SourceFileManager default discardSources. "Now save the image such that this file does not get looked for at startup" [ObjectMemory permSaveAs: 'sample' thenQuit: false] fork. [(Delay forSeconds: 45) wait. RuntimeSystem isRuntime ifFalse: [ObjectMemory quit]] fork
I saved the code I created to a parcel, so that I could do a clean load. On my Mac, the command line looked like this (I have a symlink from visual to where the VM actually resides):
./visual visual.im -filein sampleDeploy.st
Where 'sampleDeploy.st' is the script above. Running that drops a single line to 'headless-transcript.log' and quits, just as you would expect. You can copy the script from above, and download the example parcel here.
Technorati Tags: smalltalk, deployment, build script
Comments
Re: Creating a Simple Runtime
[Gnter Fahrnberger] June 22, 2010 5:00:07.754
Hi James!
Thanks for this small example. Do you also have suggestions or videos for redirections of errors into the file headless-transcript.log?
Best regards,
nter