Camp Smalltalk on Vancouver Island (Canada)

Sometimes, you have the feeling you just live on the wrong side of the globe. If you are a Smalltalker or would like to learn more about this dynamic programing language and get in touch with a bunch of enthusiasts, you better be in North America the first weekend of October:

This particular Camp has grown like Topsy from a simple attempt to get the small number of Smalltalkers on the island together for a weekend of social programming into a gathering of nearly two dozen experts from all across Canada and the US west coast. If you’re a newcomer to Smalltalk this might be a good chance to meet some experienced people that can help you.

The Camp was ignited by Tim Rowledge of Squeak fame (you can learn more about his work on Squeak on the Raspberry Pi in episode 24 of Smalltalk Inspect) and Sebastian Heidbrink, who has been a co-host on our Smalltalk Inspect podcast for years now. I hear there are a number of very interesting people coming and the list of topics and projects is a like first class menu.

To attend, visit their registration page.

I only hope somebody will take a few photos and blog about the camp, because this will sure be a lot of fun!

Beautiful little tutorial on how to build a complete Seaside Application with an RDB Backend

Sven just announced the availability of a new tutorial named “Reddit.st — In 10 Cool Pharo Classes“.

I am fascinated by how short and clear this piece is. It really explains all you need to know to get started building a Seaside Application using Glorp and Postgres as a database. It is nice to read and really covers all there is to it without leaving you out in the cold. 

Skimming through the code I’d say that the code can be used in any Smalltalk dialect, not only Pharo. Just the Captcha class needs a bit of tweaking for other dialects than Pharo.

I must say I not only like Sven’s coding style but also his writing very much. I recommend taking a look on his other articles on medium.com.

How to see who tried logging into your Ubuntu machine

Putting a piece of software onto a publicly reachable machine on the open (bad, dangerous, dirty and unbelievably complex) web presents you with all kinds of neat problems.
One of them is that as soon as you have a public address, a certain kind of people will sure try to knock on your door, push and pull a little here and there in order to see if they can open a door or a window and look what’s inside for them.

The last few days, we’ve seen an interesting increase in visits from China (well, as far as you can tell from IP address lookup. Maybe someone just uses a chinese access point or whatnot), who all try to log in as root on our Linux server.

Here is what you can do to first find out if someone was on your machine (and left traces):

lastlog
This will show you a list of all your users on the machine and when and from which address they logged in. As long as there are no users in the list that you don’t know, and as long as there are no addresses from where they logged in that sound suspicious to you, there is a chance there was no breach into your system – at least you have a first idea if there is a problem here. Of course, you can assume that real professionals will be clever enough to remove their traces anyways. Not to mention those bad guys we hear so much about these days…

Here’s what the output of lastlog looks like:

Username         Port     From             Latest
root             pts/2    IPADDRESS     Thu Aug 28 15:38:05 +0200 2014
daemon                                     **Never logged in**
bin                                        **Never logged in**

/var/log/auth.log (on Ubuntu)
This is the log file in which you see all authentication attempts. By searching through this file, you can see all login attempts that failed by looking for entries like:

Aug 24 07:21:22 yourhostname sshd[20151]: Failed password for root from 116.10.191.206 port 45168 ssh2

Based on what you learn from the logs you can decide to block certain IPs or subnets in your firewall. It’s hard to give good general advice on the topic…

VA Smalltalk on Linux with German Umlauts – how to set up the environment properly

For kontolino.de, our accounting application for small and medium businesses, the deployment platform is Linux. Our prime development platform is Windows, because some of the nicer and newer features of VA Smalltalk (like the Scintilla editor) are not (yet) available on Linux. Also, the fact that VAST uses MOTIF, makes it a bit of a beast when you want to click on a menu item. And, let’s face it, MOTIF just looks strange and old on today’s Linux distros.

Like it or not, testing and bug fixing sometimes is needed on Linux, so we have to fire up VAST on Linux from time to time, not only for packaging (which could be done on Windows as well, but you need to test the runtime on Linux anyways, so cross packaging is not a good option for practical reasons).

For quite a while now, we’ve had a major problem with VAST on Linux, which I regarded as a given:

You could either use Keyboard shortcuts like Ctrl-X/C/V or Ctrl-S with the default Locale (en_US or C), or you could edit Umlauts in the Browsers, but then neither of the Ctrl-shortcuts would work, sometimes VAST would even crash. This was less than ideal, but for just fixing small bugs, we could handle it.

Frequent readers of my blog know that I am not to vain to publicly write about my fails in professional life. This one falls into this category. Because it turns out this whole problem goes away once you configure your system properly. In our case the system is Ubuntu 13.10 and 14.04 32 bits.

So here are the steps it takes to make the combination of German Umlauts AND Ctrl-Shortcuts work on one image at the same time (tadaa!):

First, you need to install and generate the German Locale in Linux:

  1. edit the file /var/lob/locales/supported.d/de as root or using sudo (you need to edit another one for your country, of course)
  2. Append the line
    de_DE@euro ISO-8859-15
    and save the file
  3. generate the locales: sudo locale-gen

Ubuntu now not only supports UTF-8, but you can also use ISO-8859-15 for your applications

The second step is to start VA Smalltalk with this new Locale. For this, you simply edit the executable abt shell script in your image directory and add the following line to it:

export LANG=de_DE.ISO-8859-15@euro

Next time you start the image, it will support Umlauts .

If you still have trouble entering the Euro-Symbol, you may have to change the Browser or Code font within VA Smalltalk. We’ve chosen misc-fixed.ISO8859-15 for now, and so far we haven’t found any problems.

This may be old hats to you if you develop on Linux, but for us, this has helped a lot for working on our system in Linux. Fixing a bug is now also possible if the method we’re editing contains Strings with Umlauts.

Before that fix, pressing Ctrl-S would delete the contents of the code pane and replace its contents with a Strange character. So fixing bugs on Linux felt like walking through a mine field: you always had to be very careful about which key to press,

Glorp: How to create Foreign Keys with ON DELETE SET NULL

In Glorp, you can create foreign keys between tables. By default, such a foreign key will result in problems when you delete an entry in the table with the key attribute.

So if you need to create a foreign key that does not restrict deletion of a parent row, you want to add a foreign key that defines a constraint of ON DELETE SET NULL. Or maybe you want to forward deletion with ON DELETE CASCADE.

It took me a few minutes to figure out how to define such a key, so I write it down here for all to see and for me to remember.

It turns out all you have to do is to define a suffixExpression for the foreign key in your tableFor… method like this:

fkeyId := aTable createFieldNamed: 'other_id' type: platform int4.
aTable
	addForeignKeyFrom: fkeyId
	to: ((self tableNamed: 'THEOTHER') fieldNamed: 'id')
	suffixExpression: 'ON DELETE SET NULL'

Teo Torriatte

I am sitting here at my home office desk struggling with a delicate implantation of some new Announcements into our web application where we have to take very special care of transaction handling between Seaside Components.

In such situations I like to pick one of my good old vinyl LPs out of the shelf and listen to some good ole stuff. Today I somehow picked Queen’s Day At The Races (1976) and right now I heard something long forgotten: Teo Torriatte. This one (well, the whole album) reminds me of the days when I was working on wires, signals and stuff on my model railway, back in the early 80’s. I could lock myself into my room and work on the model for days, as long as I had some good music on my turntable, like Queen, Pink Floyd, Kansas, Kraftwerk, Heart or Marillion.

The remainders of the model railway are now packed in a few boxes in the basement, waiting to be kissed awake again. Nowadays, it is Smalltalk code I am working on and forgetting the world around me. The little boy is just 30 years older now ;-)

 

 

OS X Mavericks and Safari / Firefox drive me crazy

As I wrote in my last post, the latest version of Safari and Firefox on OS X Mavericks go nuts about finger gestures. This really drives me crazy, so much that I’d like to take my iMac and throw it out of the window from time to time.

I’ve seen there is a workaround by enabling scrollbars to be visible all the time, but it doesn’t work for me.

Every time I accidentally wipe to the left or right on my Mouse, Safari moves the current page a few pixels and the complete tab freezes. Even entering a new URL into the address field doesn’t work any more.

What’s interesting is that Firefox has almost the same issue: I wipe downwards on the mouse, FF will show the vertical scrollbar but it won’t scroll.

After a while, neither Safari nor Firefox will respond to wiping into any direction. At the same time, other Applications like Thunderbird, the Finder, Terminals etc. all work like they should. ARRRRGGGGGHHH!

Today, I decided to hate my Mac. Like I did last Friday. And I am afraid I will continue to do so until there is some update that heals this stupid bug.

The latest Mavericks update and/or Safari are broken…

is it only my or do others also see the effect that since the last OS X Mavericks update, using the single finger gesture in Safari to move back and forth in the Browser history freezes Safari? That’s especially funny when you’re in the middle of editing a long blog post :(

I also can’t scroll vertically in Safari any more with one finger on the MagicMouse. The gesture is working in other programs, however.

Today’s Apple is not what it used to be. I don’t care if they present the latest home automation gadget or a new iWatchagotchi ath the WWDC keynote today. I’d rather have them do their homework on their bread and butter software. If Cook wants to create something innovative, he could try and set up a software quality assurance strategy that actually works.

 

Javascript Associative Arrays are fun! Aren’t they?

…sometimes. Sometimes they also just make your body shake in fever and give you a hard time figuring what is going on with this world around us.

I guess everybody who learns javascript has to go through these things and therefor this is common sense. On the other hand, being a Smalltalk developer for around two decades, I have learned that people regard Smalltalk as a strange language. Which is not something it holds exclusive rights on, obviously.

So here comes my little anecddote. For our Kontolino.de application, I needed to nail together an ajax request that sends a Seaside callback id together with soem String back to the server. Not that I haven’t done this before. Actually I have done that quite a few times already, using both Smalltalk/Seaside and Javascript.

To make a long story short, I needed to create an Associative Array that looks like this: {“5″:”search text”} – easy, right?

No.

First of all, the “5” is the content of a String variable that was rendered on the server side. And the fact that it is a numeric String seems to make things complicated for Javascript.

Because if you do something like this:

var key="5";
var value=someInputTag.val();
var myArray = new Array();
myArray[key]=value;

you will end up with a very strange looking an array: it will have 5 entries, the first four of which are undefined. In the end, it is not an Associative Array at all. It will contain a fifth entry which is the String you just put there. For javascript, a String containing only digits is the same as a number, because, obviously, I must have meant 5 when I said “5”, right?

Since the code looks so easy and straightforward, I was under the assumption that the fact that my Ajax call didn’t work and my server side Breakpoint was never hit has to do with some strange thing going on with Ajax or my server side Seaside code. So I once again started a lengthy journey to neverwhere, which led nowhere, of course. Only took a few hours and some increasing state of desperation ;-)

A few DuckDuckGo searches later, I found a few places where people suggest using this:

var key="5";
var value=someInputTag.val();
var myArray = new Object();
myArray[key]=value;

And what can I say? The website now works like I always wanted it to. (Please make sure you look at the two snippets very carefully to find the difference ;-) ).

Now I am sure I have to be careful to say anything offending about this, because the moment I hit “Post” here on my blog server, somebody will walk around the corner and tell me this is for a (good?) reason. I hate when I have to, but this is one of the things I just have to accept without asking too many questions.

When hardcore errors with double Glorp INSERTs turn out to be ancient web problems

I’ve been hunting for some strange problem which I thought was related to Glorp or (less likely) our business code for months.

Every once in a while, our production server would log strange NOT NULL problems on inserts of records that do not erectly resolve their foreign keys, even though the objects these records usually refer to can only be persistent objects that have been in the database long before the current Glorp session was started.

Needless to say that I couldn’t ever reproduce the problem on one of our test or development machines. The business code was absolutely safe and there was no way you could produce these objects in the application.

There was, however, one little hint: This problem only occurred on our production server and it would always be the very same action in the application. We never get these errors anywhere else than in one particular form callback.

Suspect…

We still had Glorp under suspicion when we introduced loads of logging and other output to our production machine, just to understand what was going on. The good news: Glorp would raise an exception, the server would correctly roll back and inform the users of a strange NOT NULL problem on inserts. So no harm was ever done to production data (jeez, am I glad we’re using an SQL DB with ACID compliance!).

The bad news: we still couldn’t see what is going on. Glorp would do two inserts in very short time: one where all the id instvars of the newly to be inserted objects are nil, and one with these IDs being numbers.

Wait: the same objects would be inserted twice? Once without an id on the Smalltalk side, and then with IDs? The normal behavior would be that there is only the INSERT with ids all being nil, because DB2 would assign the ids during the insert (well, it’s more complicated than that, but this is irrelevant for our story at hand).

So there it was: the clear proof that Glorp, for some reason, once in a few hundred or thousand cases would decide to INSERT objects twice in one transaction and fail miserably.

But why would it do that? If the mappings were wrong, this would happen each and every time the new objects are created (and these objects are being created lots of times a day on our server, because these are accounting entries, and that is what the whole point of the system is about…).

It was Alan Knight again who came up with the correct hint, but I didn’t understand it first: There might be a race condition hidden somewhere. But how on earth would that ever be possible?

…and how it was completely wrong

To make a long story a bit shorter: One day, when I angrily hammered on the dialog using IE (which is a seldom coincidence, because I usually use Mozilla for development and testing), I could reproduce the problem. It took me a while to understand how I did, but I did manage to make the error pop up right in my VA Smalltalk debugger: ExGlorpWriteFail!

After another 30 minutes of trying to reproduce the error once again, I finally found it: And you won’t believe it.

It’s a double submit problem that has to do with the way IE handles for submits. If the submit of a form takes longer than you can click the submit button twice or press the Enter Key twice, IE (and Safari, I found) submits the form twice.

So what happens is that users submit a form, Glorp inserts objects, and immediately in the same session inserts the same objects again because it hasn’t updated its caches yet, but now these objects – even though they are still new from Glorp’s perspective, have IDs, but not all references and stuff have been updated to reflect the new foreign keys and such. So before Glorp is done inserting objects and committing a transaction and updating its session cache, the double submit from the Browser added these objects again to the objects to be inserted and tried to add them to the list of operations to perform in the same transaction.

The funny thing here is that this does not happen in all Browsers, and maybe nobody ever had the idea to press Enter twice in our form, but our customers obviously did.

So I ducked the web for possible solutions to the problem and here is what we did to solve this: We added a little jQuery Plugin that gets bound to the form. It avoids re-submits within one second (which seems to be enough) (I found this on stack overflow)

$.fn.preventDoubleSubmit = function() {
  var last_clicked, time_since_clicked;
  $(this).bind("submit", function(event) {
  if(last_clicked) {
    time_since_clicked = jQuery.now() - last_clicked;
   }
  last_clicked = jQuery.now();
  if(time_since_clicked < 1000) {
    // Blocking form submit because it was too soon after the last submit.
    event.preventDefault();
    }
  return true;
  });
};

 

So far, the fix seems to work with current versions of Firefox, Internet Explorer,  Safari, Opera on both Mac and Windows.

Isn’t it funny how some problems turn out to be caused by very unexpected things? And how much time and energy it can take to follow completely wrong paths to find the cause of a problem?