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?

 

How a DDOS attack makes me a better DevOp ;-)

Frequent readers of my blog may know that I like to learn new things. And meandering from being a developer to becoming a DevOp gives you lots of opportunities for learning.

Today I learnt a lot about the things you usually shy away from as a developer. I woke up to the bad news that our server (www.kontolino.de) and application are  practically useless. No responses, neither from the wordpress site nor from the application. Whatever you do, you’d never see anything happen. Sometimes, a request would be answered after minutes. Most requests, however, would just get nowhere.

So I decided to skip morning coffee, fire up my Mac and ssh to the server to see what’s going on. Most of the times when things seem to stand still, it is time to either restart the application (about once a month if there is no update). To my surprise, ssh didn’t get any response. I couldn’t log onto the machine. Ping and trace route were fine, the server was there. The monitor application of our ISP also said all monitored services are available – nothing unusual.

So I thought I’d best start by rebooting the machine.

The bad news: I couldn’t. Our ISP’s admin interface would send a request to the server to reboot, but the machine wouldn’t go down, even after 20 minutes or so.

Then I had to learn another lesson: if your ISP offers a remote console, make sure you can use it before anything goes wrong. Just to be prepared. The remote console, as it turns out, is a java application. Until this morning, my Mac was Java-free. Which I liked and was proud of. Until today.

Continue reading

Smalltalk Inspect Episode 27: Gemstone/S 3.2 and the new Web edition licenses

Over on our Smalltalk Inspect Podcast, Marten just released Episode 27, which was recorded late last week. Once again I didn’t make it to be online due to a family vacation that was very welcome and enjoyable.

Dale and James from Gemtalk Systems answered Marten’s and Sebastian’s questions on the news about the soon to be released version 3.2 of Gemstone/S. This release will be available “within the next few weeks” and will be packed with lots of new features and bugfixes. The most important from my perspective are:

  • Significantly improved support of Unicode Strings (this is an area where most Smalltalk vendors are hard at work on currently)
  • Better support for large Shared Page Caches (which is relevant for the really big customers)
  • More Multithreading support for Gemstone’s housekeeping procedures like Garbage Collection, Reclaiming etc.
  • Deprecation Exceptions to make phasing out of methods easier
  • Support (and shipping) of a new version of the OpenSSL library to address the famous Heartbleed problem

But what even more people might be interested in is that James and Dale also introduce the new licensing model for what was once called GLASS and will now be called the Web Edition. There will be two licenses of Gemstone/S web edition that are free for commercial use, one of which will be available just with the download files. The second one will require you to register by email and will still be free. The even more exciting news in this area is that supported licenses of the Web edition will be starting at 1500 USD per year, including a limited number of support request per year and very generous limits on CPUs and Storage space. But you’ll have to listen for yourself to learn about the details.

So if you are interested in Gemstone/S, this episode once again will be a great stop for information on what’s going to happen in the next few months.

Special thanks goes to Marten, who, after there was some mysterious problem with the recording (his moderation didn’t get recorded), had to do extensive editing and re-recording of his questions. He’s done a great job here – you hardly realize, and the sound quality is really good.

If you are in the Smalltalk scene, you sure have heard about the passing of James Robertson just before easter. James was THE Smalltalk advocate for decades. Marten starts the episode with a short tribute to James, mentioning how much he was an inspiration and idol for us.

 

Buchtipp: Flexible Boxes von Peter Müller


Flexible Boxes von Peter Müller
Das Web ist eine Bauruine. Einst geplant als hübsches Gartenhäuschen, nutzen wir es heute als 24-stöckigen Einkaufstempel mit 12000 Parkplätzen, 8 Kinosälen und 36 Restaurationsbetrieben. Der Polier des ersten Bautrupps hat wohlweislich gleich mal die Pläne beiseite gelegt, denn er wusste, es kommt eh ganz anders, als der Architekt sich das in seinem Büro vorgestellt hat. Was der Polier nicht ahnte, war, welche Ausmaße das ganze annehmen würde. Nachfolgende Generationen von Bauspezialisten haben nach und nach ein paar Stockwerke aufgesetzt, die eine oder andere Wand versetzt oder eingerissen, Balkone und Fluchttreppen angenietet und so manches mehr verschönert.
Die Bauleitung wanderte von einer Hand in die nächste, und kurz bevor alles zusammenzubrechen drohte, wollte keiner Schuld sein, und man nannte das ganze HTML 5.

Das Ergebnis ist oftmals deprimierend: Selten lässt sich etwas einfach so umsetzen, wie man sich das als Entwickler vorstellt. Dieses div soll auf gleicher Höhe mit jenem sein, sie sollen gleich hoch sein, und im zweiten möge bei Überlauf einfach ein Scrollbalken erscheinen, anstatt dass alle beide plötzlich höher werden. Und klappt es dann in Firefox, kommen schon die ersten Tickets von Safari-Usern. Nicht besser sieht es mit JavaScript aus: meist schert irgendein Browser aus, wenn es um die Unterstützung eines bestimmten Events oder einer Eigenschaft geht.

Nicht umsonst haben sich Toolboxen wie jQuery oder Twitter Bootstrap in Windeseile verbreitet. Sie kleistern die schlimmsten Lücken zu und bewerfen die launischsten Browser mit massenhaft Sonder-CSS und JavaScript, um dem Entwickler das Leben ein bisschen zu erleichtern. Leider haben diese Toolboxen auch einen entscheidenden Nachteil: Schnell wird das eigene Projekt zur Stangenware, sieht – abgesehen von den Button-Farben und dem Logo – genauso aus wie alle anderen Nachbarn auf dem VServer nebenan.

Peter Müller gibt dem Entwickler mehr als nur funktionierende Snippets an die Hand, die eben einfach diesen oder jenen Effekt erzeugen. Er erklärt anhand konkreter Beispiele, wie und warum manche Dinge auf manchmal haarsträubend unerwarteten wegen erreichbar sind. Damit liefert er einen Basissatz an Kniffen und Techniken, die man selbst erweitern und an die eigenen Wünsche anpassen kann. Codebeispiele im Buch sind einerseits ausführlich genug, um zu sie zu verstehen, und dennoch schafft Peter Müller es, nicht mit seitenlangen CSS-Schnipseln wertvolle Buchseiten zu füllen. Die Beispiele animieren zum Ausprobieren und Erweitern.

Ergänzt wird das ganze durch viele Links auf interessante, tiefergehende Ressourcen im Web: Artikel derer, die einen bestimmten CSS-Trick eingeführt haben, Diskussionsbeiträge und Gegenentwürfe, die die Schwächen der Ursprungsidee erweitern oder widerlegen und bessere Vorschläge machen.

Mit Peter Müllers Hilfe kann man sich nicht nur Code-Snippets unreflektiert zusammenkopieren, wie das in der Web-Entwicklung leider ziemlich verbreitet ist, sondern sich eingehend mit den Hintergründen befassen, und dadurch eigene Konzepte und Ideen umsetzen lernen.

Flexible Boxes ist derzeit fester Bestandteil meiner Schreibtischkruste, liegt dabei aber fast immer obenauf. Das wird sicher noch eine ganze Weile so bleiben, denn das Buch ist nicht nur ein Einführungs- sondern auch ein Nachschlagewerk, das immer wieder zur Kurzlektüre einlädt und wertvolle Tipps und Ausgangspunkte für tiefergehende Recherchen bietet. Auch hier wieder: 5 Sterne, und auch da bin ich mit den Bewertungen bei Amazon ziemlich einig.

(Bestellen bei Amazon)