Voorwoord

Waar ben ik tegenaan gelopen en hoe heb ik het opgelost.

Ik heb een aardig geheugen, ik kan mij heel goed herinneren dat ik een probleem eerder ben tegengekomen. Ik weet zelfs nog dat ik het opgelost. Hoe ik het heb opgelost is een ander verhaal. Dat verhaal staat hier beschreven.

Privacy statement: deze site zet geen cookies. De standaard Apache logging staat aan, die logfiles blijven ongeveer twee weken bewaard. In die logfiles is je IP adres te vinden, de pagina die je opgevraagd hebt, welke browser je gebruikt en hoe laat je dat gedaan hebt. Deze gegevens worden aan niemand doorgegeven.

Veertien dagen, waarom eigenlijk? Als ik ooit de logfile van gisteren bekeken heb, houdt het wel op. Het is nu twee dagen geworden.

Deze site

Deze site is geschreven in AsciiDoc en naar HTML vertaald met AsciiDoctor. Asciidoc is een formaat wat gemakkelijk te gebruiken is en waar toch veel mee mogelijk is.

De huidige versie van de site gestaat uit enkel AsciiDoc bestanden. De oplettende lezer zal hebben gezien dat de stylesheet van fonts.googleapis.com komt en een aantal fonts van fonts.gstatic.com. Een volgende versie zal alles van mijn eigen server halen.

Linux

Ik gebruik Debian met Gnome. De beschrijvingen van de oplossingen gelden dus in ieder geval voor deze omgeving.

Gnome goed zetten

Het probleem

Bij een nieuwe gnome-installatie missen een aantal instelling:

  • Pictogrammen op het werkblad

  • Alt-Tab wisselt tussen wel bureaubladen en niet tussen applicaties met de zelfde naam

  • Het normale menu is niet meer zichtbaar

  • Je kunt niet iets wissen door op delete te drukken in nautilus

  • Gelocked scherm na resume of suspend

Pictogrammen op het werkblad

In het programma 'afstelhulp' is een linkerbalk, klik daar op 'Bureaublad'. Rechts staat een knop met "Pictogrammen op bureaublad', schuif die simpelweg naar 'AAN'

Alt-Tab

In het programma 'afstelhulp' is een linkerbalk, klik daar op 'Uitbreidingen' en zet 'Alternatetab' op 'AAN'. Nu zullen alleen programma’s van het huidige werkblad getoond worden.

Normale menu zichtbaar maken

In het programma 'afstelhulp' is een linkerbalk, klik daar op 'Uitbreidingen' en zet 'Applications menu' op 'AAN'. Eindelijk weer het menu terug.

Delete

De standdaard toets is Ctrl-Delete geworden. Maar je kunt het veranderen. Open het bestand ~/.config/nautilus/accels, zoek naar ; (gtk_accel_path "<Actions>/DirViewActions/Trash" "<Primary>Delete") en verwijder het <Primary> stukje en de ; aan het begin van de regel. Je zult nautilus wel even moeten herstarten (of je hele PC als je net van windows komt).

Gelocked scherm

Op m’n laptop wil ik geen gelocked scherm na een resume of suspend. Open dconf-editor, kies dan links: org/gnome/desktop/screensaver en zet lock-enabled uit.

Find files

Het zoeken van files en er iets mee doen is altijd weer zoeken, hier een voorbeeld.

Zoek files van 20 dagen of ouder en toon ze: find . -mtime +20 -exec ls -l {} \;

Certificaten om in te loggen

Wat is er mooier dan zelf certificaten maken om via https in te loggen in je eigen website. Deze beschrijving regelt het maken in installeren van die certificaten. De authenticatie gaat niet verder dan het controleren of het certificaat klopt.

Selfsigned server certificate maken

Maken een private key:

openssl genrsa -des3 -out server.key 2048

Maak een CSR

openssl req -new -key server.key -out server.csr

Verwijder het wachtwoord van de key

cp server.key server.key.org
openssl rsa -in server.key.org -out server.key

Maak een self signed certificate (dit zou je ook kunnen gebruiken voor je server key, maar daar gebruik je tegenwoordig let’s encrypt voor.

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

De client keys

Nu gaan we de keys maken waarmee je client via de browser kan inloggen.

Maak een client key aan

openssl genrsa -des3 -out jaap.key 2048

Maak een CSR voor de client

openssl req -new -key jaap.key -out jaap.csr

(vul hier de velden in. Common Name wordt belangrijk, hier kan je b.v. mee zoeken in de LDap)

ga nu de client key tekenen

openssl x509 -req -days 365 -in jaap.csr -CA server.crt -CAkey server.key -set_serial 01 -out jaap.crt

Maak er een pkcs van

openssl pkcs12 -export -clcerts -in jaap.crt -inkey jaap.key -out jaap.p12

Maak er een gecombineerde pem van

openssl pkcs12 -in jaap.p12 -out jaap.pem -clcerts

Maar wat we met dit laatste moeten, is mij niet duidelijk. Het stond zo aardig in het voorbeeld…​

De Server

Nu moet het geheel op de server worden geïnstalleerd. Om het goed te laten werken zal je de headers module moeten laden.

Een mooie beschrijving is te vinden op Apache site. Daar kan ik verder weinig aan toevoegen. Dat weinige zijn de headers. Het zou kunnen dat je client applicatie iets wil doen met de gegevens van de ingelogde gebruiker. Hieronder een voorbeeld:

<Directory /home/jaap/public_html>
SSLVerifyClient require
SSLVerifyDepth 1
Header set MyHeader "Hello Jaap, dit is een header voor de browser, op de terugweg."
RequestHeader set X-Client-Name "%{SSL_CLIENT_S_DN_CN}s"
RequestHeader set X-Client-Verify "%{SSL_CLIENT_VERIFY}s"
RequestHeader set X-Client-Serial "%{SSL_CLIENT_M_SERIAL}s"
RequestHeader set X-Client-DN "%{SSL_CLIENT_S_DN}s"
</Directory>

Exim4

Frozen messages

Verwijderen van frozen messages kan met de volgende opdracht:

exim -bpr | grep frozen | awk {'print $3'} | xargs exim -Mrm

Wil je het aantal verstuurpogingen verlagen, pas dan /etc/exim4/exim4.conf.template aan. Geef ignore_bounce_errors_after en/of timeout_frozen_after een lagere waarde. Vergeet dan vooral niet Exim te herstarten. Zie: exim site.

Java

JaxB marshalling

Het probleem

Bij het marshallen van een JAXB object komt de merkwaardige foutmelding "javax.xml.bind.JAXBException: package.Class is not known to this context". De class Class is wel te vinden, maar toch gaat het fout.

De oorzaak

Het bleek dat er meerdere WSDL’s waren waarmee code was gegenereerd. In de pom.xml waren de WSDL’s allemaal in een execution gemaakt. Die WSDL’s hadden in de zelfde namespace verschillende classes waardoor er een verkeerde ObjectFactory is gemaakt.

De oplossing

Voor elke WSDL een nieuwe packagename laten genereren, dit kan door meerdere executions te gebruiken. Zie http://stackoverflow.com/questions/17674456 En ja, de pom.xml wordt wel erg groot.

Lessons learned

Maak WSDL’s zorgvuldig: niet de zelfde namespace gebruiken voor verschillende dingen.

Date naar LocalDate conversie (en terug)

Probleem

LocalDate en Date moeten vaak van de een naar de ander omgezet worden, een heel makkelijke methode is er niet Oplossing

Zowel heen als terug in het volgende voorbeeld:

Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());

Dit levert een LocalDateTime op, maar die heeft gelukkig de method toLocalDate(). Andersom heeft LocalDate de method atStartOfDay().

Prachtige code

Exception throws Exception

Een beetje programmeur weet hoe hij een exception moet maken, maar niet de programmeur van dit stukje code:

public class FlutException extends Exception {
  public FlutException(String message) throws FlutException {
    super(message);
  }
}

Een exception die zichzelf throwed? == Oracle en Hibernate

Dubbele nummertjes

Het probleem

De applicatie draaide prima. Geen enkele klacht was ons ter ore gekomen. Plotseling kregen we vreemde foutmeldingen in onze ontwikkelomgeving: er was een DB constraint waar we tegenaan liepen. Al snel bleek het de primary key te zijn. Uit de code bleek dat we netjes een uniek getal uit een Oracle sequence haalden. Toch zagen we in de database records met een id dat een paar honderd hoger was dan de laatste sequence.

Het duurde even voor we het lek boven hadden. De sequence in Oracle was gedefinieerd met een increment van één, dus elke keer als iemand een nieuwe waarde opvroeg werd het getal met één verhoogd.

In de Hibernate configuratie stond een increment_size van 1000 en een optimzer die 'pooled-lo' was. Uit de documentatie bleek dat Hibernate in dat geval een getal uit de sequence haalt en daar intern door mee gaat tellen tot hij 1000 getallen had uitgegeven, daarna zou Hibernate pas een nieuw getal op vragen.

We hadden meerdere applicaties draaien in onze ontwikkelomgeving. Het is mij een raadsel hier niemand eerder tegenaan is gelopen. In alle andere omgevingen ging het wel goed, daar was de sequence in Oracle wel gedefinieerd met een increment van 1000.

Uitleg

Hibernate heeft een optimalizatie bedacht waardoor zij niet telkens aan de database om een sequencenummer moet vragen. Hibernate vraagt een nummer, en hoogt dat zelf een aantal keer op. Pas als er een 'increment' aantal keer een nieuw nummer is uitgegeven, vraagt Hibernate weer een nieuw nummer. Dit gaat natuurlijk alleen goed als de database een zelfde aantal nummers overslaat als de database.

Dit geldt voor Hibernate versie 3 en 4.

Lessons learned

Kijk naar de specs, wat bedoelen ze, snap je het.

Performance issues oplossen is leuk, maar bedenk dat dat altijd weer andere problemen oplevert. Dit is een mooi geval van optimalisatie die verkeerd uitpakt. Wellicht heb je iets minder communicatie met je database, maar de kans op fouten is een stuk groter.

Wildfly

Logging

Logging gaat standaard naar de algemene log. Dit is vrij eenvoudig om te zetten. Als er een bestand met (o.a.) de naam jboss-log4j.xml dan zal Wildfly dit bestand gebruiken.

Als er een fileappender wordt gebruikt, wil je hier geen hardcoded path in hebben. Dit kan door in Wildfly een system property aan te maken met b.v. de naam "LOGDIR" en de waarde "/var/log/wildfly". In je appender gebruik je dan:

<param name="file" value="${LOGDIR}/mijnlog.log">;