You are currently browsing the category archive for the ‘Smalltalk’ category.

A screencast of this blog post is here.

Because Smalltalk was the origin of much of today’s GUI (mouse, overlapping windows, drop-down menus), Smalltalk developers are understandably accustomed to a nice GUI IDE. GemStone/S is an excellent database and Smalltalk execution environment and includes a built-in command-line tool, Topaz, where you can execute Smalltalk code, but has no native GUI. In this blog post we continue a demonstration of GemStone.app on the Macintosh (started here) and show Jade, a GUI-based IDE available on Microsoft Windows.

We launch GemStone.app on the Macintosh, update the version list, download 3.1.0.4, then install and start a GLASS extent (image) that includes Monticello/Metacello tools. When the database is running we start a Topaz session and install Seaside 3.0 and Magritte 3 with the following script:

run
"based on https://code.google.com/p/glassdb/wiki/Seaside30Configuration"
MCPlatformSupport commitOnAlmostOutOfMemoryDuring: [
  ConfigurationOfMetacello project updateProject.
  ConfigurationOfMetacello loadLatestVersion.
  Gofer project load: 'Seaside30' group: 'Seaside-Adaptors-Swazoo'.
].
%
errorCount
! 
commit
run
"based on http://www.iam.unibe.ch/pipermail/smallwiki/2012-February/007188.html"
Gofer it
  squeaksource: 'MetacelloRepository';
  package: 'ConfigurationOfMagritte3';
  load.
%
errorCount
!
commit
run
MCPlatformSupport commitOnAlmostOutOfMemoryDuring: [
  ConfigurationOfMagritte3 project stableVersion load.
].
%
errorCount
!
commit
run
WAGsSwazooAdaptor new start.
%

When Swazoo is running, we can go to http://localhost:8080 and see Seaside running locally. This demonstrates running Smalltalk code in Topaz, the command-line tool. Next we look at a GUI-based IDE that runs on a Microsoft Windows client platform.

Jade is available as a 14 MB zip download from http://seaside.gemtalksystems.com/jade/. It includes an executable, client libraries (DLLs) for various GemStone/S versions (ranging from 32-bit version 6.1 to the latest 64-bit version), and related files (including source code). Like most GemStone/S client GUI tools, it is built in another Smalltalk (in this case, Dolphin Smalltalk from Object Arts), but unlike these other tools, you can’t see the client Smalltalk (unless your load Jade source code into your own Dolphin development environment), so we avoid the the two-object-space confusion. Jade is intended to take you directly to GemStone/S, without going through Pharo, Squeak, VA, or VW Smalltalk.

Jade is also designed to work with the no-cost version of GemStone/S (unlike the VA/VW-based GBS tools), and performs well on a slow network (unlike GemTools).

When you unzip the download, you have a folder with various items. Jade.exe is the primary executable (containing the Dolphin VM and the image) and it relies on Microsoft’s C Runtime Library. There is a copy of the executable in Jade.jpg for sites where executables are stripped from zip files during the download process (simply rename the suffix and it will become executable). Contacts.exe is used sometimes in a training class. The bin directory contains the GCI client libraries and a DLL with various images used in the IDE. You can also see a directory containing source code for Jade.

Screen Shot 2013-10-01 at 10.56.18 AM

When you launch Jade, you get a login window that gives you a place to select the GemStone/S version (which GCI library we will use), and other information needed for a login. The Stone box contains two fields, one for the host/IP of the Stone machine (from the perspective of the Gem machine, so localhost is almost always sufficient), and the name of the Stone. In the screencast mentioned above our stone was named gs64stone1. The Gem box contains a number of fields. Most logins will use an RPC Gem (a Linked Gem is available only on 32-bit Windows) with a Guest-authenticated Gem (if your NetLDI was not started in guest mode (-g), then you will need to provide an OS user and password). An RPC Gem will be started by a NetLDI, so we need to identify the Gem machine (in my example the host is vienna and the NetLDI is listening on port 54120) and the command used to start the Gem (except in rare cases the command will be ‘gemnetobject’). You provide a GemStone User ID and Password (by default, ‘DataCurator’ and ‘swordfish’), and if you are going to use any Monticello features it would be good to identify the developer’s name (one word with CamelCase).

Screen Shot 2013-10-01 at 11.01.49 AM

If you get an error on login, we attempt to give as much explanation as possible. Typically, (1) there is no NetLDI on the host/port (see following example), (2) there is no stone with that name, (3) there is a version mismatch, or (4) you have given an unrecognized user ID or password.

Screen Shot 2013-10-01 at 11.13.38 AM

When you have a successful login, you will get a launcher that consists of several tabs. The Transcript serves the traditional (ANSI) Transcript function of showing output sent to the Transcript stream. The second tab shows information about your current session.

Screen Shot 2013-10-01 at 11.19.59 AM

The third tab shows information about the current logged-in sessions, including where the Gem is located, where the client GCI is located, and whether a Gem is holding the oldest commit record. If you have appropriate security, you can send a SigAbort to a session or even terminate it!

Screen Shot 2013-10-01 at 11.21.07 AM

The final tab is a Workspace. In this tab you can execute, print, and inspect Smalltalk code. You can also use the toolbar or menus to abort or commit and open other tools.

Screen Shot 2013-10-01 at 11.17.23 AM

 

One of the tools is a User Profile Browser that shows the various users defined in the database.

 

Screen Shot 2013-10-01 at 11.31.42 AM

Next is a Monticello Repository Browser that shows various repositories, packages, and versions.

 

Screen Shot 2013-10-01 at 11.32.47 AM

The Monticello Browser includes a tool to browse differences between packages.

Screen Shot 2013-10-01 at 11.33.36 AM

 

Much of your work will be done in a System Browser. This view shows the four SymbolDictionary instances in my SymbolList. UserGlobals is bold, indicating that it is the ‘home’ or default SymbolDictionary, but I have selected Globals and see a list of class categories, a partial list of classes, and in the lower section of the screen is a list of the non-class objects in Globals (note things like AllGroups and AllUsers).

Screen Shot 2013-10-01 at 11.41.42 AM

 

This screen shot shows us an example of the Packages view (which requires Monticello), and a method with a breakpoint (the red rectangle around a method).

Screen Shot 2013-10-01 at 11.43.54 AM

There are other tools, including a debugger, but I’ll leave that for your exploration (and/or another post/screencast).

Have fun and let me know if you have questions or feature requests.

 

 

 

 

 

Advertisements

Video of ESUG 2013 Presentation

My presentation “Smalltalk in the Cloud” was recorded and can be found at the link. Unfortunately, the audio was not very strong.

Update: Slides are here.

One of the challenges of providing Smalltalk on Cloud Foundry (or any cloud hosting system) is that the applications are typically given an ephemeral file system and isolated from read/write access to any persistent disk. This is, of course, for good reasons, but makes it difficult to use Smalltalk applications (like Pier on Pharo) that rely on image-based persistence. We recently described getting a Pharo application (in that case AIDAweb) running on Cloud Foundry 2, but each time you stop and start an application instance you would lose all the saved data.

This post describes a way to modify a private Cloud Foundry system to provide access to a persistent file system from an application instance. Note that this is a proof-of-concept and demonstrates that it is possible to work around the carefully-designed isolation in Cloud Foundry. We do so by providing every Pharo application the same shared space that is completely replaced whenever you upload a new application. We also give all files and directories read/write/execute permission so that subsequent launches of the application (which Cloud Foundry does with a new user and group) will have access.

Create a Virtual Disk

The first step is to create a fixed-size (~500 MB) virtual disk (based on ideas here) that can be used by the application instance for persistent file storage. The following steps, done as root on the Cloud Foundry server, give us what the needed disk:

cd /var
touch st_virtual_disk.ext3
dd if=/dev/zero of=/var/st_virtual_disk.ext3 bs=550000000 count=1
mkfs.ext3 /var/st_virtual_disk.ext3
mkdir /var/smalltalk
mount -o loop,rw,usrquota,grpquota /var/st_virtual_disk.ext3 /var/smalltalk/
mkdir /var/smalltalk/pharo/
chmod 777 /var/smalltalk/pharo/

Making the Disk Visible in the Warden Container

Cloud Foundry’s architecture includes a Warden that manages a container for each application instance that includes a private root file system. On Ubuntu 10.04 LTS this is implemented using aufs, and the mount action is (at the moment) found in /var/vcap/data/packages/warden/29/warden/root/linux/skeleton/lib/common.sh line 60 (with :/var/smalltalk=rw added):

mount -n -t aufs \
 -o br:tmp/rootfs=rw:$rootfs_path=ro+wh:/var/smalltalk=rw none mnt

This means that the container’s private root file system has a /pharo top-level directory that maps to a persistent 500 MB virtual disk. The remaining portion of the external file system (from /var/vcap/data/packages/rootfs_lucid64/1) is read-only and the internal file system (from /var/vcap/data/warden/depot/*/tmp/rootfs/) is read/write.

New Pharo Buildpack

Now rather than simply creating a startup script, the buildpack needs to copy things to the persistent file system and use that when running the application. Following is the new compile script:

#!/usr/bin/env bash
#
BUILD_DIR=$1
CACHE_DIR=$2
BUILD_PACK_DIR=$(dirname $(dirname $0))
#
cd $BUILD_DIR
rm -rf /pharo/* 2>&1
cp `ls *.image` /pharo/pharo.image
cp `ls *.changes` /pharo/pharo.changes 2>&1
rm *.image *.changes 2>&1
if [ ! -e startup.st ]; then
 touch startup.st
fi
cp -r * /pharo
chmod -R 777 /pharo/*
rm -rf *
#
cat > startup.sh << EOF
#!/usr/bin/env bash
#
umask 0000
ln -s /pharo ./pharo
cd pharo
/opt/pharo/pharo -vm-display-null -vm-sound-null pharo.image startup.st \$PORT
EOF
chmod +x startup.sh

Client Changes

On the client (before pushing the application to the cloud), there are some changes needed. I started with the Pier 3.0 download (from on this page). The pre-build image is in Pharo 1.3 and does not include Smalltalk code for accessing the OS environment variables (at least not that I found easily). Thus, you can see above that the startup script is modified to add $PORT to the command line when starting Pharo. With that change, Pier can be started on the supplied port with this startup.st script (that might work for any Seaside application):

| manager adaptor port |
port := (SmalltalkImage current argumentAt: 1) asNumber.
manager := WAServerManager default.
adaptor := manager adaptors first.
adaptor port == port ifFalse: [
 manager stopAll.
 adaptor port: port.
 manager startAll.
].

This runs Pier on Cloud Foundry on a persistent file system but Pier needs to save the image regularly. It would also be desirable to save the image when sent a SIGTERM (perhaps with something like Chaff). One can save the image from the /status page, though since one can also quit the image from that page it probably should have some security!

In any case, we have demonstrated that it is possible to provide a persistent file store for a Pharo application on a private Cloud Foundry server.

We have previously demonstrated adding Pharo to Cloud Foundry. Since that time Cloud Foundry has been substantially revised and the process for adding a runtime/framework has changed to be based on a buildpack model. In general, this makes things easier but there are some complications.

On the Server

To deploy a Pharo application to Cloud Foundry we log in to the private Cloud Foundry instance created earlier. So that I can set the shell title and not have it replaced I typically change the prompt:

export PS1='\[\e[0;35m\]\h\[\e[0;34m\] \w\[\e[00m\]$ '

By default, Cloud Foundry is set up to run 64-bit applications. In order to run the 32-bit version of Pharo we need to add some libraries:

sudo apt-get install -y ia32-libs

As discussed in the architecture documentation, each application runs in a container with a private root filesystem. Thus, the 32-bit libraries need to be added to the shared read-only portion. This should be done using the general Cloud Foundry install scripts, but as a first attempt I’m just doing it manually:

cd /var/vcap/data/packages/rootfs_lucid64/0.1-dev
sudo rsync -r -l -D -g -o -p -t /lib32 . # 12 MB
sudo rsync -r -l -D -g -o -p -t /usr/lib32 ./usr/ # 153 MB
sudo cp /lib32/ld-linux.so.2 ./lib/
cd usr/lib
sudo rsync -r -l -D -g -o -p -t /usr/lib/libv4l* .
sudo rsync -r -l -D -g -o -p -t /usr/lib/gio .
cd gtk-2.0/
sudo rsync -r -l -D -g -o -p -t /usr/lib/gtk-2.0/i* .
cd 2.10.0/
sudo ln -s ../../../lib32/gtk-2.0/2.10.0 i486-pc-linux-gnu
sudo ln -s ../../../lib32/gtk-2.0/2.10.0 i686-pc-linux-gnu

I’m not sure that all of the above is necessary, but it seems to be sufficient to run Pharo as a runtime in a container. Next, we install Pharo and make it visible (with the same recognition that this could be done better using the install scripts):

sudo mkdir /opt/pharo
cd /opt/pharo
sudo chmod 777 .
curl http://files.pharo.org/vm/pharo/linux/Pharo-VM-linux-stable.zip > pharo.zip
sudo unzip pharo.zip; rm pharo.zip
sudo chmod 755 .
cd /var/vcap/data/packages/rootfs_lucid64/0.1-dev/opt
sudo rsync -r -l -D -g -o -p -t /opt/pharo .

Now we get to the part of making a Pharo buildpack. Eventually this should be in a Git repository but for now I’ll just add it directly to my private Cloud Foundry instance so that it looks like a built-in buildpack.

cd /var/vcap/packages/dea_next/buildpacks/vendor
mkdir pharo pharo/bin; cd pharo; git init
cat > README.md << EOF
Cloud Foundry Buildpack for Pharo Smalltalk
==============
EOF

The actual buildpack consists of three files that are called by Cloud Foundry, all in the bin directory. First is bin/detect (use an editor to create these files):

#!/usr/bin/env bash
#
if [ -f $1/*.image ]; then
 echo "pharo" && exit 0
else
 echo "no" && exit 1
fi

This will confirm that the Pharo buildpack can handle an application that contains a .image file. Next we create bin/compile to add a startup script to the application:

#!/usr/bin/env bash
#
BUILD_DIR=$1
CACHE_DIR=$2
BUILD_PACK_DIR=$(dirname $(dirname $0))
#
if [ ! -d "$BUILD_DIR" ]; then
 mkdir -p "$BUILD_DIR"
fi
#
if [ ! -d "$CACHE_DIR" ]; then
 mkdir -p "$CACHE_DIR"
fi
#
cat > "$BUILD_DIR/startup.sh" << EOF
#!/usr/bin/env bash
IMAGE=\`ls *.image\`
STARTUP=\`ls | grep startup.st\`
/opt/pharo/pharo -vm-display-null -vm-sound-null \$IMAGE \$STARTUP
EOF
chmod +x "$BUILD_DIR/startup.sh"

Third, we create bin/release to return a YML file with startup information:

#!/usr/bin/env bash
#
cat <<EOF
---
default_process_types:
 web: ./startup.sh
EOF

Finally, we set these three files to be executable:

chmod +x bin/*

Now that we have modified our private Cloud Foundry instance support Pharo we start it up:

cd ~/cf_nise_installer/; ./local/start_processes.sh

It seems that the startup might need a bit of extra time. To check on the status do the following:

sudo /var/vcap/bosh/bin/monit summary

On the Client

In our previous approach to adding Pharo to Cloud Foundry, we went to some effort to avoid copying the image, changes, and sources files over the network from the client to the server (because they are typically quite large). That earlier approach, while elegant, is a bit less obvious to application developers who just want to deploy their application. In this iteration I’ve taken the approach of doing the simplest thing and waiting till it causes a problem to “improve” things. Thus, we expect you to provide the image file and we will just run it. The primary thing that you have to do is modify your code to provide a web server on the port defined in the $PORT environment variable (which can be different each time the application is launched). To facilitate this you can include a ‘startup.st’ script in your directory that will be run each time the application starts. This allows you to change the listening port each time. Following is a sample ‘startup.st‘ script that we use with an AIDAweb one-click image:

| methodSource port |
methodSource := 'introductionElement
 | element |
 element := WebElement new.
 element addText: self observee introduction.
 element addText: ''<p>Listening on port: '' , 
 session parent site port printString , ''</p>''.
 ^element'.
Author fullName: 'CloudFoundry'. "Developer's name"
WebDemoApp compile: methodSource.
port := OSProcess thisOSProcess environment at: #'PORT' ifAbsent: ['8888'].
AIDASite default
 stop;
 port: port asNumber;
 start.

At this point we can connect to our private cloud and push the application:

cf target api.172.16.217.185.xip.io # use the IP address of your private cloud
cf login --password micr0@micr0 micro@vcap.me
cf create-space development 
cf target --space development
cf map-domain mycloud.local
cf push
# Name> myapp
# [accept defaults]
# Save configuration?> y

Now, make sure that ‘myapp.mycloud.local’ is in your /etc/hosts file and points to your private cloud. Then you can open a web browser on http://myapp.mycloud.local and you should see your application running!

As you think about running a Pharo application in the cloud, remember that the file system is ephemeral. That is, your application can be restarted any time and changes made to the image will not be saved. See http://docs.cloudfoundry.com/docs/using/app-arch/ for a good discussion of some architectural issues.

If you are following this blog you are aware that I’ve been investigating options for hosting Smalltalk in the cloud. One very successful hosting solution for a number of languages is Heroku. Not only do they support a number of languages built-in, but they also allow anyone to create a buildpack to support another language or framework. So, what would it take to add Smalltalk to Heroku? First, we need to acknowledge that Will Leinweber has a buildpack for Redline Smalltalk. Since Redline Smalltalk is based on the Java VM, this is more about running Java on Heroku than Smalltalk (which is not to minimize the accomplishment, just to note that getting a Smalltalk VM running is not quite the same).

The next thing to note is that running an application in the cloud might be different from running it on your own server. The model most hosting providers follow is that they package your application into a stand-alone directory tree that is saved on their server. When you ask for one or more instance(s) to run they copy the directory tree onto an available machine, set some environment variables (including a port on which to listen for HTTP requests), execute an application launch command, and then route requests to the port. Horizontal scaling is accomplished by starting additional instances and routing requests to them in some fashion. If an application dies then the hosting provider cleanup the directory and repeat the process with a new directory. Thus, each instance is isolated from other instances (even of the same application), and the file system is “ephemeral” and exists only while the instance is running. From a Smalltalk perspective, this means that typical image-based persistence is not trivial. I have some ideas on how this might be addressed, but need to get Smalltalk into the environment first.

As mentioned above, you can create a third-party buildpack that packages and starts your application. The buildpack is essentially three bash scripts that (1) report whether it can handle a particular application (“Do I have everything here that I need?”), (2) transform the application into its runtime structure, and (3) tell the framework how to start instances of the application. This is all fairly straightforward and has been done for many languages and frameworks. Note, however, that a “buildpack is responsible for building a complete working runtime environment around the app. This may include language VMs and other runtime dependencies that are needed by the app.” So, to get something like Pharo running on Heroku we need a Cog VM that runs on the Heroku server.

To find out more about the Heroku environment I decided to try it out. First, I signed up for a free account at https://id.heroku.com/signup and then install the tools. At this point I followed the simple instructions to create a “Hello, world” application:

mkdir ~/cloud/heroku
cd ~/cloud/heroku
heroku login
git clone git://github.com/heroku/ruby-sample.git
cd ruby-sample
heroku create
git push heroku master
heroku apps:rename mygreatapp
heroku open

This opened a web browser on http://mygreatapp.herokuapp.com/ and the expected page was displayed. The next thing that is rather nice is that you can run a non-web application on the Heroku server and have stdin/stdout/stderr routed back to your client shell:

heroku run bash

This starts a bash shell on the server; just as if you used ssh! Now we can do some things to investigate the server environment (this script represents what came at the end after I tried various things described next):

uname -m -o # x86_64 GNU/Linux
ll /lib/libc.so* # 2.11.1
cat /proc/version # Linux version 3.8.11-ec2 (gcc version 4.4.3)
file /sbin/init # ELF 64-bit LSB, for GNU/Linux 2.6.15
cat /proc/cpuinfo # Intel(R) Xeon(R) 4 CPUs X5550 @ 2.67 GHz 
curl --version # 7.19.7
tar --version # 1.22
zip --version # command not found

The shows us that heroku is running 64-bit linux on Xeon processors. Since we have non-root access we can’t do much to changes these characteristics. We can, however try installing Pharo and see what happens. My first attempt was to download a one-click but that was a zip file that couldn’t be unzipped. Next, I got a recent Cog VM that came as a .tgz file. I uncompressed this with tar and tried to run it. This gave the error “/usr/bin/ldd didn’t produce any output and the system is 64 bit.  You may need to (re)install the 32-bit libraries.” So we can’t run the 32-bit application–at least not without some work. Next I tried a 64-bit Squeak VM and uncompressed that. With this we got further, but now have the error “squeakvm64: /lib/libc.so.6: version `GLIBC_2.14′ not found (required by squeakvm64).” Note above that the Heroku server has GCC 2.11 (from 2009), so executables compiled with later libraries will not run.

I guess that the correct thing to do is to build the needed binaries on the Heroku server (as described here). Presumably this would guarantee that everything works together. Before trying to build Cog I might look at GNU Smalltalk.

Before finishing up we need to stop our Heroku application so we don’t use up resources. Exit from the bash shell on the server (if it hasn’t timed you out!), and then destroy your app:

heroku apps:destroy mygreatapp

In any case, I’ve learned enough for today and will try some other things next week (probably non-Heroku things!).

In an earlier discussion about Smalltalk we observed that image-based persistence does not work very well with Cloud Foundry’s model where several application instances may be run at the same time to support scaling. With a Pharo-based Smalltalk, each instance has its own image so data stored in the image is not shared among instances. One way to solve that problem is to use an external database, and Cloud Foundry includes built-in support for MySQL 5.1. In this post we look at adding MySQL to the client and creating an AidaWeb application that uses the database. Deploying this application on Cloud Foundry will require a few modifications that we will discuss in the next post.

MySQL Setup

We start by adding MySQL to our client so we can develop and test our application locally. On this page, select the appropriate download for your machine; I used Mac OS X 10.6 (AMD64, installer format) (13 Feb 2011, 78.1M). Follow the instructions for installing and starting MySQL. For convenience, we will add an alias to the MySQL command-line interface:

alias mysql="/user/local/mysql/bin/mysql"

It is a good practice to secure the database, so from a command shell we connect to the database:

mysql -u root

Once connected, we add a password for the root user:

SELECT User, Host, Password from mysql.user;
UPDATE mysql.user 
  SET Password = PASSWORD('swordfish') 
  WHERE User = 'root';
FLUSH PRIVILEGES;
SELECT User, Host, Password from mysql.user;
EXIT

Now, from the command shell try various ways of connecting (note that there is no space after the -p option:

mysql -u root
mysql -u root -p
mysql -u root -pswordfish

You should find that the first one fails, the second one prompts for a password, and the third one logs in immediately. Once logged in we can perform various queries. Note that we need to specify a database as part of the query if it is not explicitly used. Try each of the following individually:

SELECT User FROM user;
SELECT User FROM mysql.user;
USE mysql; SELECT User FROM user;

The first should result in an error while the next two should succeed. You can avoid the USE command by specifying the database as a command-line argument (exit from MySQL and try the following):

mysql -u root -pswordfish mysql

Next we create a non-root administrative user:

CREATE USER 'jfoster'@'localhost' IDENTIFIED BY 'swordfish';
GRANT ALL PRIVILEGES ON *.* TO 'jfoster'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT

Now we can login as our new user and specify the test database:

mysql -u jfoster -pswordfish test

The MySQL driver that we will use has a couple hundred tests that expect a particular user to be defined. We enter the following to create a new user:

CREATE USER 'stdbtestuser'@'localhost' IDENTIFIED BY 'stdbtestpass';
GRANT ALL PRIVILEGES ON stdbtestschema.* TO 'stdtestuser'@'localhost';
FLUSH PRIVILEGES;

Creating a Smalltalk Application

Now that we have MySQL running on our client machine, we will create a Smalltalk application that uses MySQL. (In creating this AidaWeb application I got help from Janko Mivšek.) Open a web browser on http://ss3.gemstone.com/ss/CloudFoundryDemos.html and click on the ‘Latest’ tab. There should be several packages listed. For this demo we want the following:

  • JSON
  • Stdb-Core
  • Stdb-MysqlProtocol
  • Stdb-MysqlImpl
  • BalanceDemo

At the right end of each row is a “download” action; for each of the above packages click this link. Move the downloaded files from the Downloads directory to ~/cloud/aida/app (which we created earlier).

Now we edit ~/cloud/aida/app/aida.st to install the packages for our application and register two entry points with Aida:

Author fullName: 'CloudFoundry'. "Name for edits"
MczInstaller installFileNamed: 'app/JSON-ul.35.mcz'.
MczInstaller installFileNamed: 'app/Stdb-Core-ah.7.mcz'.
MczInstaller installFileNamed: 'app/Stdb-MysqlProtocol-ah.15.mcz'.
MczInstaller installFileNamed: 'app/Stdb-MysqlImpl-ah.9.mcz'.
MczInstaller installFileNamed: 'app/BalanceDemo-JamesFoster.1.mcz'.
MySqlBalanceApp register.
ImageBalanceApp register.

Recall that this script runs once, during the “staging” process, and then the image is saved and made read-only so it can be deployed in multiple instances. Now we edit ~/cloud/aida/start so that it defines environment variables that will be provided by Cloud Foundry:

#! /bin/bash 
export VCAP_SERVICES='{
  "mysql-5.1":[ { 
    "credentials":{ 
      "name":"test", 
      "host":"localhost", 
      "port":3306, 
      "user":"jfoster", 
      "password":"swordfish" 
    } 
  }
]}'
export VCAP_APP_PORT=8888
open -a /opt/smalltalk/cog/CogVM.app/ --args \ 
  ~/cloud/aida/Aida.image \ 
  ~/cloud/aida/app/aida.st \ 
  $VCAP_APP_PORT

Now, try launching the application locally:

~/cloud/aida/start

It should take some time loading the packages and then you should be able to open a Test Runner and run the JSON and Stdb-Mysql* tests. You should have 223 tests all pass. You can now open a System Browser and look at the BalanceDemo category (it should be the last one in the first column). You can see that there is a BalanceApp, an abstract superclass that provides the AidaWeb behavior, and two subclasses that implement image-based persistence and persistence using MySQL. Browse the code and then open a web browser on http://localhost:8888/ImageBalance and http://localhost:8888/MySqlBalance. (The first time you may need to login to AidaWeb using the user ‘admin’ and the password ‘password’.) With each of them you should be able to enter a value in the ‘Adjustment:’ field, then click the ‘Adjust’ button, and see a new balance. Try entering both positive and negative integers.

From a MySQL command-line interface try the following lines and look at the change in the application by refreshing the web page:

SHOW TABLES;
SELECT * FROM account;
UPDATE account SET balance = 42;

We can see that changes from the web are reflected in the database and changes in the database are reflected in the web.

Germán Leiva was accepted in Google Summer of Code 2010 and developed a Namespaces implementation for Pharo Smalltalk. This video is based on his presentation at ESUG in Barcelona, Spain in September 2010. You can get the code here.

As a way of welcoming Michael Lucas Smith to Portland, we asked him to present this month at the Portland Smalltalk User’s Group and he agreed to talk about WebVelocity. (Michael is the lead engineer for WebVelocity with Cincom Smalltalk.) These notes were taken during the presentation:

Michael started with a history of the various dialects that are part of Cincom Smalltalk. He showed us some code in VisualWorks that dates back to the original Smalltalk-80:
Cursor earth showWhile: [(Delay forSeconds: 5) wait].

WebVelocity is a server-based system that has all the tools in the web browser. This is the ultimate “eat-your-own-dogfood” situation where all the tools are themselves using Seaside. For persistence, WebVelocity uses “ActiveRecord” and ActiveRecord uses GLORP, so if ActiveRecord is not sufficient you can dive down to GLORP which has almost unlimited flexibility.

Much of the goal of WebVelocity is to reduce the barrier to entry by making Smalltalk more approachable. Thus, there are a number of things that will not be as familiar to those coming from other Smalltalk tools, including VW.

Given the prevalence of relational databases, the focus is on making back-end persistence easy. Creating an application starts with a default setup, including connection to the database of your choice. We could define the database, or use an existing database. From the web browser, we go in and use the database schema to create classes. The tools create up to seven classes for each table, including domain model, multiple testing classes, and user interface components.

The classes are created with appropriate instance variables (as selected through the web browser). Once the classes are defined, the web components are already there, and we can “run” the application “scafolding” (similar to the Rails term), except that instead of templates you get abstract superclasses that provide lists, editors, etc. If, instead of looking at an ‘html’ page, we request a ‘atom’ page, we get an XML object. We can also get XML and JSON directly from the scafolding.

The example had a customer and a product table joined. Michael showed an example of adding a #printOn: method. Going to the web browser for the class, there is a list of method categories and the #printOn: method was offered by default. Methods added and edited are saved automatically. You don’t need to save. In fact, you can edit multiple methods at a time. You can even walk away from methods with compile errors and the tools help you come back to them.

The tools provide undo and redo as a way to avoid any problems from automatic saving. There is extensive use of “tool tips” that show errors as you are typing. There is a built-in “help” system that has extensive documentation provided as part of the web user interface. The documentation drills down to the method descriptions.

Michael added a method with an error to demonstrate the debugger. While the point is to demonstrate the web-based debugger, it turns out that in his image he had been using a different debugger (the one in the Smalltalk image). He was able to quickly switch a preferences to use the web debugger and then go to the web browser. He was able to edit, save, and continue.

There is a “Console” that is available from most tool windows. In the console, you can type an expression in the text entry field at the bottom of the window and the result of the expression is added to a list in the main section of the window. The main section contains a list of tree views, so you can inspect the resulting object. This seems like an elegant alternative to the traditional Smalltalk workspace. It is more like a shell where you type an expression and the result is added above the line.

Source code is generally managed with Store, but the WebVelocity tools provide a new view on Store as well. Store is quite powerful and provides a distributed code repository environment.

What comes next? It still needs a lot of documentation. Also, since it is aimed at developers new to Smalltalk, it needs to be fairly complete and easy to use.

There has been a lot of UI design and learning, and yet most Smalltalk browsers look mostly the way the did 25 years ago–with added toolbars and coloring, but not a fundamental change in the approach. With WebVelocity the design started over from scratch, and asked how tools could be built to be useful to a developer.

Comparing ActiveRecord to GLORP: If you had a link table that you want to treat as a Dictionary (rather than a third table), GLORP can be configured to populate a dictionary. GLORP provides the way to create a database schema with multiple tables having pre-defined relationships. You can defined classes, and then define how the tables are mapped to the classes.

In many situations, rather than just a blank method, you get a method template with a number of commented-out lines that give examples of the sort of things you are likely to want. For example, the table definition gives examples of various types of columns that can be added.

Interestingly, in the code browser where you write Smalltalk methods, you can also create CSS and JavaScript. The system recognizes that the thing being typed looks like something other than Smalltalk.

In a way, Cincom has been a victim of its own success–particularly with regard to downloads of marketing and education material. Of course, this problem is being addressed, and it is a great problem to have!

If you want to get involved in the beta program, email jarober at gmail dot com.

After the WebVelocity discussion, Michael showed us some of his work on OpenGL. It seems that the API has changed significantly, and he is building some lessons that demonstrate usage of the new API. I think this would be a good subject of another meeting!

Categories