Weblog entries 2004

JFall 2004 proceedings

Na een lange periode van radiostilte is de Nederlandse Java User Group NL-JUG weer tot leven gebracht. Sinds vorig jaar vindt er in de lente en de herfst een event van een gehele dag plaats, genaamd JSpring en JFall. Om de events bij te wonen, moet je lid zijn, maar dat moet geen probleem zijn want de contributie bedraagt EUR. 25,- per jaar en dan zijn de events gratis.

Oktober de twaalfde vond de JFall van 2004 plaats in de Reehorst in Ede. In de centrale ruimte was ruimte gemaakt voor stands van de sponsors, waaronder Quest en Sun. In de aangrenzende ruimten vonden een aantal parallelsessies plaats. Hieronder worden drie presentaties samengevat.

Simon Phipps, Sun: "Massively Connected"

De eerste presentatie van de dag werd gegeven door Simon Phipps. Een interessante presentatie om bij wakker te worden, zoals Klaas Tukker (voorzitter van de NL-JUG) het uitdrukte. Hij vertoonde op zijn Apple Powerbook een grappig filmpje waarin drie kamergenoten met elkaar communiceren via instant messaging en mobiele telefoon terwijl ze alledrie aan de ontbijttafel zitten. Dezelfde ontbijttafel, wel te verstaan. De centrale boodschap was: we leven in een wereld waarin iedereen met iedereen is verbonden, "Massively Connected". Hierdoor zijn een aantal zaken verandert.

Phipps zag bijvoorbeeld een terugkeer naar het gilden-systeem. Deze organisaties van vaklieden waren honderden jaren lang de manier waarop professionals zich organiseerden, maar uiteindelijk verloren ze de strijd van de industrialisatie. Phipps trok parallellen tussen de gilden van weleer en de open source manier van ontwikkelen. Het verschil is echter, zo zei hij, dat gilden hun kennis binnenshuis hielden terwijl men nu juist geld verdient door die kennis te etaleren als open source en vervolgens te verkopen door middel van consulting.

Maar dat naar zijn mening was niet het belangrijkste kenmerk van open source. Hij sprak ook over het woord "free", dat in het Engels feitelijk twee betekenissen heeft: gratis en vrij. Open source is namelijk niet slechts gratis oftewel, kosteloos; het geeft ook een stukje vrijheid. De vrijheid om een andere leverancier te kiezen, of om de software zelf aan te passen. Verder brengt die vrijheid een hogere kwaliteit en veiligheid met zich mee.

Het publiek vroeg zich al af waar dit heen ging. De laatste tijd is Sun namelijk in het nieuws geweest omdat ze claimden dat ze de broncode van Java en zelfs hun eigen besturingssysteem Solaris gingen opensourcen. De controversie was de licentie: de broncode van Java is altijd beschikbaar geweest, maar mocht niet verder gedistribueerd worden. De community had gehoopt dat de bekende GPL of BSD licenties zouden gebruikt worden zodat Java met een Linux-distributie (zoals RedHat) meegeleverd kon worden. Maar dat was niet het geval: er kwam een nieuwe Sun-specifieke licentie die niet compatibel was. Echter, zo zei Phipps, dat maakte geen enkel verschil want er zijn meerdere soorten vrijheden. De GPL en BSD licenties geven de vrijheid om de code te distribueren. Daarentegen brengt de Sun-specifieke licentie compatibiliteit met zich mee! Hij gaf hiermee een interessante draai aan de discussie.

Sander Hoogendoorn, Ordina: "Project Anti-patterns"

Naast design patterns zijn er nu ook project patterns. De heer Hoogendoorn hield de aandacht van zijn publiek stevig vast door de zaak om te draaien: als er project patterns zijn, dan volgt automatisch daaruit dat er ook project anti-patterns zijn. Dus: hoe kun je een project op een uitstekende manier laten mislukken, saboteren, de grond in drijven, et cetera.

Eerst gaf hij enkele statistieken. Volgens de Standish Group sterft 32% van alle projecten een vroege dood, 53% gaat 190% over budget en dan houden we 16% over die slagen.

Hij toonde vervolgens slides met elk een anti-pattern; de eerste was getiteld "Titanic Projects". Zeer grote projecten waar diverse afdelingen betrokken zijn, complex probleemdomeinen en developers zonder ervaring. Zulk soort projecten waren net als de Titanic gedoemd om halverwege de reis ten onder te gaan. Ideaal! aldus Hoogendoorn, want we zoeken in deze presentatie projecten die mislukken.

Daarna werd elke rol in een project onder de loep genomen. Als je klant bent en je wilt dat je project faalt, zorg dan voor torenhoge ambities en zoveel mogelijk buzzwords. Als je accountmanager bent en je staan op de golfbaan met je prospect, kweek dan onrealistische verwachtingen, "fake it until you make it".

Ook projectmanagers kwamen aan de orde. Als je projectmanager bent, dan ben je in een bijzondere positie om het project te laten falen. Voor die manager is de heer Winston Royce een ongekende held, want hij is de uitvinder van de waterfall methodiek. Het mooie van deze methode is dat er voor elke stap een terugkoppeling zat naar de voorgaande stap; echter dit is in een standaardisatie-slag door het Amerikaanse Department of Defense weggelaten! De ambtenaar die dit op zijn geweten heeft, is inmiddels kluizenaar en woonzaam in de bossen van Wisconsin. Na deze simplificatie zijn de verantwoordelijkheden keurig gescheiden. Project- en accountmanagers kunnen dus de analisten bij een andere klant zetten, wanneer de ontwikkelaars binnenkomen.

Naast waterfall is een ander aardig anti-pattern "death by planning", wat volgens Hoogendoorn ook wel "management by Excel" wordt genoemd. De projectmanager maakt tot ver in het jaar een gedetailleerde planning en is vervolgens elke week een dag kwijt aan het bijwerken van die planning. Dan blijven er uiteraard vier dagen over om naar andere klanten te gaan! Ook, zo zei Hoogendoorn, kun je als projectmanager inkorten op testen en aan het eind van het project nog ontwikkelaars toevoegen om de deadline te halen. Na deze uitspraak toonde de volgende slide Charlie Chaplin als The Great Dictator, voorstellend: de projectmanager als dictator. Deze manager geeft niemand verantwoordelijkheid, laat iedereen overwerken, maar acht zich bijzonder sympathiek door drie maanden achter elkaar elke avond pizza te halen (want die zit op de hoek naast de klant). De volgende rol was de architect. Wat zo mooi is aan een architectenrol, is dat in Word en Powerpoint altijd alles werkt: het hoeft niet te compileren. Zo kun je onmogelijk complexe ontwerpen toch er goed laten uitzien. De architect doet er goed aan, om nooit en te nimmer een ontwikkelomgeving te installeren want technische details zijn triviaal.

De laatste rol was die van de developer. Op de slide werd Bob de Bouwer getoond. Bob heeft een aantal pratende machines die altijd 'ja' zeggen als Bob vraagt of ze iets kunnen bouwen. Dit pattern doet zich voor wanneer er developers op het project zijn die onnodige features voorstellen aan de klant, vervolgens nachten door moeten werken om het te realiseren en in de tussentijd de hele codebase overhoop gooien. Een goede zaak, aldus Hoogendoorn, want we willen tenslotte het project doen mislukken. Dit verhoogt ook de zogenaamde Truck Factor: de kans dat het project tot stilstand komt, als een bepaalde developer onder een pick-up truck terecht komt.

Over de rol van tester had Hoogendoorn in deze presentatie weinig te melden, behalve dan dat hij maar zo laat mogelijk op het project moest komen. Ook moest er vooral gewoon worden doorgeprogrammeerd terwijl de tester zijn werk doet.

In de laatste slides werden aanwijzigen gegeven hoe het wel moet. Projecten moeten bij voorkeur klein en overzichtelijk zijn, developers dienen ook de rol van architect op zich te nemen, betrek de klant, een planning is flexibel, enzovoort. Kortom, werk meer volgens de agile methoden (XP, Scrub, etc.) en je zult tijd en budget overhouden. Door de insteek was het een grappige en onderhoudende presentatie, maar jammer was wel dat er geen tijd was voor nadelen met betrekking tot agile methoden. In een schriftelijke reactie gaf Sander Hoogendoorn aan dat het doel van de presentatie was om om mensen na te laten denken over nieuwe manieren van ontwikkelen. Hij heeft een boek in de pijpleiding dat dieper ingaat op de voor- en nadelen hiervan. Zijn website is zeer interessant: www.sanderhoogendoorn.com/.

Ruud Steeghs, Sogeti: "Aspect Oriented Programming"

Deze presentatie was zeer praktisch ingericht. Er werd uitgelegd wat aspect oriented programming (AOP) is en hoe het werd toegepast op een project dat Sogeti deed bij een klant.

AOP is een aanvulling op object georienteerd programmeren (OOP). Vrijwel elke mainstream taal is tegenwoordig in mindere of meerdere mate objectgeorienteerd. Alhoewel een object een goede abstractie is voor zaken in de wereld om ons heen, is hij niet perfect. Allerlei infrastructurele zaken zoals logging, authentication, performance testing, bepaalde vormen van input validatie enzovoort raken vaak een groot aantal klassen die niets met elkaar te maken hebben. Het is dan lastig om dit objectgeorienteerd te modelleren.

De kern van aspect oriented programming is, zeer verrassend, het aspect. Dit is een apart stukje code waarvan je kan specificeren dat het op een bepaalde plaats in een method wordt aangeroepen. Het standaard AOP voorbeeld is logging. Het zou aardig zijn als elke method automatisch begon met

 logger.fine("begin raiseSalary");en eindigde met
logger.fine("end raiseSalary");

Dit is te realiseren met AOP. Er zijn meerdere implementaties: JBoss AOP, Nanning, Aspectwerkz en in mindere mate het Spring framework. In deze presentatie werd echter gebruik gemaakt van de oudste en meest uitgebreide implementatie AspectJ. Om met AspectJ het bovenstaande voorbeeld te realiseren, compileer je je project op de gebruikelijke manier. Vervolgens maak je je aspect met de volgende file:

 public aspect LoggingAspect {
   pointcut tracePoints() : execution(* *.* (..))
     && !within(LoggingAspect);
 
   before() : tracePoints() {
     System.out.println("Before: " + thisJoinPoint);
   }
 
   after() : tracePoints() {
     System.out.println("After:   + thisJoinPoint);
   }
 }
 

Zoals je ziet, heeft de code een Java syntax met wat extra keywords. Als bovenstaande file is gemaakt, run je de AspectJ compiler. Die past de .class files aan van je project in een proces dat 'weaving' wordt genoemd. De bytecode wordt aangepast en vervolgens kun je die code deployen.

Natuurlijk kun je nog veel verder gaan met AOP dan wat logging toevoegen, maar daar was binnen de presentatie geen ruimte voor. Het boek wat de heer Steeghs aanraadde, was AspectJ In Action van Ramnivas Laddad (ISBN 1-930110-93-6 (alternate, search)).

2004-12-12

Reading source code is one of those things that I feel that nobody likes, while the advantages are so clear. You can brush up language skills, find out how other people solve things, learn different architectures, find out what the quality of a code base is, play spot-the-pattern et cetera. One cause could be that you don't learn reading other people's code in college. On the contrary, they want you to create little pieces of code that can easily be kept in one head and where correctness is easily demonstrated.

The real world doesn't work like that. If your day job isn't maintaining other people's code in the first place, then you'll get to see your colleague's code at the end of the project when they move on and you get to stay for a little while. Either way, you'll just have to accept that you don't understand everything and get on. For those people who still have that barrier, I did a little writing on how to search through code and getting it to work the way you want it, without feeling lost. We're going to look at Adjusting Starfighter.

2004-10-15

How to remotely debug using jdb

First compile your java code with the '-g' option. Deploy the compiled code to your server. Then start the virtual machine on the server with debugging parameters:

 -Xdebug -Xrunjdwp:transport=dt_socket,address=6000,server=y,suspend=n

Then either use JDeveloper or the standard (implementation reference) debugger from Sun, which is called 'jdb'. In the first case, go to Tools, Project Properties, flip open Debugger, click Remote and check Remote Debugging. Select 'Attach to JPDA' which means we attach to a Sun JVM. Then click OK and click the debug icon. Fill in the hostname and the address which you specified in the debugging parameters, for example 'oxdaps20a' and '6000'.

To debug with jdb, open a shell or DOS box and type:

  jdb -attach your.development.box:6000

On the jdb> prompt, type the line

  use /path/to/sourcefiles

to tell the debugger where it can find the source files. Set some breakpoints with the 'stop' command and then wait for the breakpoints to hit. Type 'list' to see where the flow of control is when a breakpoint was encountered. Type 'next' to go to the next line. Type 'step' to step into a method.

Note: when either debugger acts funny, i.e. breakpoints are set but never hit, breakpoints cannot be set, or the code stops in places where it shouldn't stop (empty lines, comments), chances are that the code that's running is different from what you are looking at. Compile and deploy your code again and start debugging again. When the JDeveloper debugger acts funny, use jdb instead. The JDeveloper debugger is more tuned to work with the Oracle JVM (OJVM), which coincidentally is now also available on Linux.

Note: when you debug a virtual machine, all threads halt, affecting other people's work. With jdb it's possible to let other threads continue, see also 'help thread'. With JDeveloper this is not possible (and I've heard that there aren't any other commercial debuggers that can do this either).

Note 2: if you want the virtual machine to wait while you remotely connect with the debugger, change the VM option 'suspend' to 'n'.

2004-09-02

You'd like a nice way to order the output of (Oracle) SQL in an arbitrary way? For instance, if you query a table with filenames and the customer first wants the files with extension xml, then pdf and finally raw, you could use a query like done below:

      select ast.filename,
             decode(ast.extension,
                    'pdf', 1,
                    'raw', 2,
                    0)                 sort_order
      from   assets                    ast
      order  by sort_order
      

The syntax for decode is a bit confusing. Basically, it's a bit like a Java switch statement. First, name the column whose value you want to substitute. Then, you get the original-new value pairs. The final parameter is for the case where none of the original values match.

2004-08-06

This is for unredeemed hackers who must see the raw bits to be happy.
-- Solaris truss man page

They say that automatic garbage collection is one of the advantages of Java. That doesn't quite get you off the hook completely. True, it saves you from having to delete each new object you create, as one would in C++. However, besides memory there are other resources that are scarce (diskspace, network, database) but those aren't cleaned up automatically as opposed to the objects that represent them. For instance, below is a routine which reads a textfile into a string:

    private String readFile(File file) throws IOException {
        BufferedReader in = null;
        try {
            String line = null;
            StringBuffer contents = new StringBuffer();
            in = new BufferedReader(new FileReader(file));
    
            while ((line = in.readLine()) != null) {
                contents = contents.append(line + "\n");
            }
            return contents.toString();
        } catch (Exception e) {
            return null;
        }
    }

Have you spotted the error? I was in a hurry when I coded this method and I certainly didn't. The error is that the reader needs to be closed:

        finally {
            if (in != null) {
                in.close();
            }
        }

This method isn't heavily used but when there is a maximum of 1024 open files and the application runs a few hours, you'll get messages in your logs stating that you opened Too many files. (By the way, the maximum can be found with ulimit -n if you're using the Bash shell). What is nasty, is that that message doesn't really tell you exactly where you open too many files. Rather than pouring over all that code, I used truss on the Solaris box (on Linux, it's called strace). This command can tell you which system calls an application makes.

System calls are basically the commands that you can give to the kernel. Your favourite programming language may have nice libraries or even have some drag-and-drop widgets, but it all comes down tot asking the kernel whether you can open that file. The kernel will then do the work of checking permissions, checking whether the file is actually there, returning an error if necessary, et cetera. An example of a system call is open, or fork, or something else.

As said before, truss and strace can tell us which system calls an application makes. I was interested in the open and close calls. After I had done a ps to find the process ID (pid) of the running app, I typed

    truss -t open,close -p 7601 -f > trussoutput.txt 2>&1

When the application had run for some time, I interrupted truss, opened it in vi and threw away all pairs of open and close calls. What remained, were the open calls that had no counterpart. Since the arguments to the system calls are also shown, the filename shows up. And that definitely rang a bell; I knew immediately which piece of code opened that file.

2004-07-31

I'm currently reading The Pragmatic Programmer and although it contains a lot of those things that are pretty much common sense, there are some true gems in there as well. Especially the part about tracer bullets.

The project I'm currently working on, consists of a number of workflows. One of the flows I'm working on, has to support different production stages; it goes too far to explain, but it's enough to say that there are multiple stages of which the first is the simplest.

Some of those workflows contained steps that were unexpectedly large and had changing requirements, meaning they were difficult to plan. Estimates would change all the time, causing some *cough* friction here and there.

As a remedy, we would first get the full flow working for the first production stage and when the flow ran flawless from start to end, we would build uit each step in the flow to support the next stage.

Hunt and Thomas (the Pragmatic Programmers) call this tracer bullets, which contain a phosphor payload that flashes when it hits the target. In the dark, the gunman then knows that his aim is right.

The idea is good, but it's immensely difficult to resist the temptation when you're frantically coding! Because you're in the Flow and when you've done one part of the functionality, you can see those methods and data structures dangling in front of you. However, you still should break out of the flow at the correct time, synchronize with your team members and the QA people, and get that workflow to, well, flow.

It's amazing what this does to management, the customer and the developer. When the flow works partly, it gives a feeling of confidence to all the parties. This is definitely a good thing.

2004-07-13

Some cool bash/Linux stuff:

If you're using bash, put a line TMOUT=600 in /root/.bashrc. The user will automatically logout after 10 minutes.

If you're often cd'ing into a mounted directory, this might mean a lot of typing. For instance, at a client I always have to change to directory /mnt/es-groups/EWII for the project files. To shorten typing, I created the following line in my .bash_profile file:

export CDPATH=".:/mnt/es-groups/EWII"

When you type cd Documents, you'll find yourself immediately in the project's documentation directory; bash even tab-completes.

UNIX Commands No One Ever Heard Of ™...: Type script and press enter. A new shell will be started. Now do whatever you like. When you're done, press CTRL-D on an empty prompt. script will reply with something like Script done, file is typescript. The new file will contain whatever you've typed, including screen output! Fun to put in your friend his/her login scripts....