Send to Printer


Creating a Simple Runtime

June 21, 2010 11:54:31.107

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:

	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:

	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 -filein

Where '' 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: , ,

posted by James Robertson


Re: Creating a Simple Runtime

[G￿nter 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,


 Share Tweet This