2. Hello World!

A quick tutorial for the impatient

In this we'll provide a quick tour showing how to develop a simple "Hello World!" application using Smalltalk/X and Java. You will need to properly install following:

2.1. Implementing the "Hello World!"

This simple application will consist of two classes:

  • A Java class jv.demos.helloworld_1.core.HelloWorld that will actually print a greeting to standard output (when run as standalone application from console) or to Transcript (when executed within a Smalltalk/X IDE, i.e., from workspace).

  • A Smalltalk class HelloWorldStartup that will serve as an entry point when application is run standalone. This one will initialize STX:LIBJAVA (as it's not initialized by default) and fire the Java code.

We'll package both classes together into a single Smalltalk/X package named jv:demos/helloworld_1.

Before we start, we have to initialize STX:LIBJAVA. For details, refer to Section 1.3, “Initializing Java”, for now, just execute in workspace:

JavaVM boot.

Once the STX:LIBJAVA is booted, create a Java class. In a class browser, select ClassNewJava Class. In the browser's code pane, a template of Java class definition appears. In our case, the new class's source code may look like:

  • Line 1: A Java package to which the class belongs. It's name could have any value, but we strongly recommend to use a Smalltalk/X package name as prefix for Java package. It makes the code easier to understand.

  • Line 7: An annotation which actually tells the Smalltalk/X IDE to which Smalltalk/X package the class belongs to. WIthout this annotation, Smalltalk/X IDE would not know so when later on you commit the package from the browser, the Java class will not be commited - which is not what you want!

Once you accept the code, the Java class is compiled and loaded into a running system. Now you should be able to use it from a workspace. Open one and evaluate:

helloworld := JAVA jv demos helloworld_1 core HelloWorld new.
helloworld greet.

The first line instantiates the HelloWorld class from Smalltalk. You may alternatively instantiate it as follows:

helloworld := (Java classForName:'jv. demos.helloworld_1.core.HelloWorld') new.

The second line invokes the greet() method. You may also invoke the greet(String) method as simply as:

helloworld greet: 'Haya'.

Now let's define an application startup class:

StandaloneStartup subclass:#HelloWorldStartup
        category:'Hello World'

And it's #main: method - this is the application entry point:

    | helloworld |
    JavaVM booted ifFalse:[
        JavaVM boot.
    helloworld := JAVA jv demos helloworld_1 core HelloWorld new.
    helloworld greet.
    Smalltalk isStandAloneApp ifTrue:[
        Smalltalk exit: 0
  • First, the STX:LIBJAVA has to be initialized. We do it conditionally only if it's not already. Strictly speaking, this is not necessary as when a standalone application starts., STX:LIBJAVA is not initialized, however, doing so allows to test the #main: method from running IDE.

  • Second, load the Java class jv.demos.helloworld_1.core.HelloWorld and invoke its greet() method.

  • Third, exit the application. We do it conditionally for the very same reason - you don't want your Smalltalk IDE to terminate when testing the #main: method.

Don't forget to move class HelloWorldStartup to package jv:demos/helloworld_1 (menu ClassMoveTo Package).

2.2. Commiting project

The initialal code has been developed so now it's time to commit it to Mercurial repository. If you're not familiar with Mercurial under Smalltalk/X, you may want to read stx:libscm User Guide. In the following text, let's assume the Mercurial repository for the package is located at /home/user/SmalltalkXProjects/jv/demos/helloworld_1 (or C:\Users\user\SmalltalkXProjects\jv\demos\helloworld_1 on Windows)

To commit the package, switch browser to package mode (menu ViewPackage) and commit (menu PackageMercurial+Checkin...).

Commiting package from Smalltalk/x class browser

If the menu item Mercurial+ does not show the text "(default)" then something is wrong with the Mercurial setup - check stx:libscm User Guide.

Once the commit dialog appears, fill in the commit message and click to Commit button.

Commit dialog to commit a package

Now the code has been commited to the repository. Let's check it from command line:

$ cd /home/user/SmalltalkXProjects/jv/demos/helloworld_1
$ hg log
changeset:   0:2fc9b3286e10
tag:         tip
user:        Jan Vrany <jan.vrany@fit.cvut.cz>
date:        Sun Jun 14 08:14:54 2015 +0100
summary:     First shot on a cool "Hello World!" app


2.3. Loading Hello World package

Before loading the package into freshly started Smalltalk/X IDE you have to manually update Mercurial working copy to desired revision. When a package is commited from Smalltalk/X, the working copy in Smalltalk/X package path is not updated to the commited revision[2]. So you have to update the working copy by hand:

$ cd /home/user/SmalltalkXProjects/jv/demos/helloworld_1
$ hg up
17 files updated, 0 files merged, 0 files removed, 0 files unresolved

Now the working copy should be updated to just-commited revision. To load the package back into freshly started Smalltalk/X IDE, load the package as usual:

Smalltalk loadPackage: 'jv:demos/helloworld_1'.

If there's no error while loading (there should not be), you may want to try whether it works as expected. Evaluate:

HelloWorldStartup main

You should see text "Hello world!" in Transcript window. You should be able to see jv.demos.helloworld_1.core.HelloWorld class in a system browser window. Now you can change classes further and once done with it, commit and load it back using the same process.

2.4. Topics not covered

[2] The main reason is that for binary-compiled classes the sources are not loaded in the memory but loaded from the .st files found in package path on demand. A method contains only offset into this file. Of the file is changed the offset changes and therefore the source shown in the browser will be wrong. To take safe side, stx:libscm (Mercurial) never updates the working copy. This may change in a future.