Kom niet naar deze sessie!

We hadden het kunnen weten, want JVMCON-spreker Jan Ouwens had ons van tevoren al gewaarschuwd. De abstract voor zijn praatje “Don’t hack the platform? ☠💣💥” loog er namelijk niet om: “Don’t go to this talk! Your coworkers will not be happy when you come back to work tomorrow and start applying the things you’ll learn here. You’ll do a lot of damage.”

Desondanks kwamen er meer dan honderd geïnteresseerden naar de ‘Grote Zaal’ van het Cinemec in Ede om Jans sessie tijdens de eerste JVMCON van Info Support bij te wonen. Jan sloeg de opkomst met groeiend ongeloof gade en begon de sessie met de (terechte) vraag: “Wat dóén jullie eigenlijk hier?” Dit zorgde voor de nodige interactie met het publiek. Jan vervolgde met: “Door hier te komen, hebben jullie het over jezelf afgeroepen”. De toon was gezet.

Fijne ongelukjes

Jan is de bedenker van EqualsVerifier, een tool die Java-ontwikkelaars helpt om 100% test coverage te bereiken in equals()– en hashCode()-methoden door het toevoegen van slechts één regel testcode. En door zijn werk aan EqualsVerifier ontdekte Jan – onbedoeld – een aantal bijzondere constructies in Java die tot onverwachte, maar desondanks interessante resultaten konden leiden. Of om het in Jans eigen woorden te zeggen: “Ik had een aantal fijne ongelukjes, met wat slechte gevolgen.”

Emoji-scores

Maar hoe slecht zijn die gevolgen dan precies? Dat wilde Jan ons gerust vertellen; elk codevoorbeeld dat hij liet zien ging gepaard met een score die de ‘slechtheid’ weer moest geven. Een Java-klasse die twee Strings kan genereren die altijd dezelfde hashCode hebben kreeg als score ‘☠’. En een klasse met een stuk code in een commentaarregel dat door een line feed-karakter in Unicode tóch kan worden uitgevoerd kreeg een ‘☠💣’. Dat alles dus vrolijk uitgedrukt in een ‘emoji-score’. En waarom ook niet? Zo’n ín en ín slecht onderwerp kan wel wat vrolijkheid gebruiken.

Loopy

De getoonde voorbeelden zijn echter kinderspel vergeleken met het onderdeel ‘Reflectie’, waar Jan ons vervolgens op trakteerde. In het voorbeeld ‘Loopy’ liet Jan ons zien wat er mis kan gaan als je via reflectie de interne representatie van de klasse Integer een vastgestelde waarde geeft:

public class Loopy {
    public static void main(String... args) throws Exception {
        Integer five = 5;

        Reflector.setPrivateFieldValue(Integer.class, "value", five, 4);

        for (Integer i = 0; i < 10; i++) {
            System.out.println(i);
        }
    }
}

De uitvoer van bovenstaande code is het volgende:

				
0
1
2
3
4
4
4
4
4
4
4
4	
(...)		
				

De for-loop eindigt nooit omdat de waarde niet boven de ‘4’ uitkomt. En dat komt doordat de variabele five een constante is tussen -128 en 127, waardoor Java de code optimaliseert door de Constant Pool te gebruiken. Door het gebruik van reflectie is de waarde van de constante die hoort bij ‘5’ in de Constant Pool gewijzigd naar ‘4’. Daardoor wordt in latere iteraties van de loop steeds opnieuw de rekensom ‘4 + 1’ gedaan, waarmee we steeds weer uitkomen op de constante ‘5’ in de Constant Pool (die een waarde van ‘4’ blijft houden). Wat mij betreft méér dan terecht dat dit smerige truukje namens Jan een score van ‘☠💣💥’ om de oren krijgt.

Tikkeltje slechter

Net zoals in Hollywoord-films, kunnen de slechterikken natuurlijk altijd een nog tikkeltje slechter, al hebben ze daar vaak wel wat hulpmiddelen voor nodig. Als je de library ByteBuddy toevoegt aan je toolset, is het zelfs mogelijk om de implementatie van native methodes te beïnvloeden. Jan demonstreerde dit tijdens zijn praatje met een klasse die ‘door de tijd kan reizen’ door de implementatie van System.currentTimeMillis() at runtime te veranderen. Evil indeed.

Dark Side of the Force

Het absolute hoogtepunt van de sessie was het codevoorbeeld ‘Remote Time Traveling’. Ook hierbij liet Jan zien dat de implementatie van native methodes te beïnvloeden is, maar dan in een al draaiende (!) JVM. Het enige dat je daarvoor nodig had, was Java 9, ByteBuddy en het proces-id van het draaiende Java-proces. Welcome to the dark side of the force. Dat vond Jan overigens ook, gezien de door hem genoemde score van ‘😱😱😱😱😱😱’.

Abstract

Als ik erop terugkijk, moet ik constateren dat ik niet eerder een sessie heb bijgewoond met zo’n slecht onderwerp, dat tegelijkertijd gepaard ging met zo’n goede uitvoering. En juist de ‘donkere’ aard zorgde ervoor dat de uitstekende codevoorbeelden, de kennis én de gortdroge humor van Jan zo goed uit de verf kwamen. Eigenlijk was er maar één onderdeel van de sessie voor verbetering vatbaar, namelijk de abstract. “Kom niet naar deze sessie!”

Meer weten over JVMCON?

Wil je meer weten over JVMCON? Lees dan ook de blog van mijn collega Marten!