All posts by HJ

How to convert a physical hard drive to a virtual machine

This post is based on various notes from a project I did a while back. It all began when my laptop’s hard drive started making funny clicking noises. I took this as a sign it would stop working sooner or later, did a backup of the relevant things and replaced it. Since then, it had been lying on a shelf so I figured a fun project would be to turn it into a virtual machine. After all, a disk can be moved from one physical machine to another without any need for reinstalling or configuring with identical settings. Sounds easy enough to take whatever is on the disk, convert it to a virtual hard drive and boot it inside VirtualBox? That way, I could continue to use the existing installation even if the hardware failed. Turns out this wasn’t as straight forward as first expected.

Let’s start with the easy part, first we need to write the disk content to an image file. Not knowing the exact steps involved, it seemed like a good idea to have an exact copy. This makes it easier to experiment and go back if something fails or additional steps are needed. It also reduces the risk and issue of the disk suddenly dying if I have already grabbed all I need from it.

I plugged the old hard drive into my Ubuntu machine to make a copy of the content while the drive was still working. To create an image, I used dd which will create a byte for byte identical copy. As an example; dd if=/dev/sdb2 of=image.iso status=progress will create an exact copy of the sdb2 partition and store it in image.iso. Make sure a) that you read from the correct disk (check gparted or similar tools to be sure) and b) the target where you store the result has sufficient space. As we’ll get more into later, you want a copy of the whole disk not just individual partitions. Unfortunately this didn’t work in my case, attempting to copy the entire disk it would stop halfway through. Repeated attempts failed at the same exact number of bytes, presumably related to the disk problems. I therefore grabbed only the main Windows partition which I was able to without running into errors. That should be all I needed. Now that I had an exact copy of the disk (well, the parts I could get at least), I unplugged the physical one.

Next step was to convert the raw disk image to something the virtual machine can understand. In my case, I used VirtualBox’s tool for this conversion: vboxmanage convertfromraw image.iso virtualHd.vdi. Note that the raw image is a byte-for-byte exact copy and will need all the required space even to duplicate empty space, but the virtual hard drive only needs the actual space in use. My tip now would be to create a backup of the virtual hard drive, to ensure you can start over if (when) something goes wrong. You can possibly do this with snapshots in the VM, but I found it easier to know that I could always return to the original state and start over without any earlier changes spilling over.

Create a virtual machine in VirtualBox as normal and attach the virtualHd.vdi to the new VM. This is where the problems started, it refused to boot. The disk was there, it was connected, and if I booted with a live CD I could see all the files. So why didn’t it work?

I tried multiple things here, eventually took a look at it with a boot repair tool. The report told me the boot sector believed it should start reading from sector 200000 or so, while the disk in fact started at sector 0. This is where I should probably tell you that the original disk layout was a bit strange. The first partition was a rescue partition (for some reason), the second was Windows and the third a dual boot setup for Ubuntu. Since I had failed to copy the complete disk, I had settled for the Windows partition. However, it seemed that it had retained the offset caused by the first partition, so using only the second partition made it really confused.

Disk management overview of the partitions

Note that the boot repair tool was able to pin-point the issue, but despite the examples and documentation I was looking at it didn’t provide any solutions. I tried a couple of variations to re-create the MBR by overwriting it, but no matter how I tried it always messed up the partition so that no program knew exactly what partitions or file systems it contained anymore.

After banging my head against that wall for a while, it struck me that if it needed that partition layout, why not set it up that way? I had a recovery CD, created from when the laptop was new. (Seemed more like a clean install than a recovery, but that suited me even better). So the plan was: I do a recovery install in the VM, I get the same partition layout and then simply replace the second partition. This actually worked as expected. Replacing the content in the second partition was easy. I just booted the virtual machine with the newly installed hard drive, the copied hard drive and a Ubuntu live CD to move things from one to the other. As an experiment, it actually made a difference if you copy all the files or all bytes of the partition with dd. The former worked and booted, but strange dialogs popped up when logging in. It should have replaced and included all files, so I don’t really understand the issue here. However, going back and overwriting everything with raw bytes worked much better.

So I now had a clean install with a fresh partition 1 and a salvaged partition 2 copied over. The VM booted, everything was loading and I got to the login screen. A little detour here, before we get to the end: I was unable to remember my original password. I tried most likely variations and then some rather unlikely ones without any luck. While I had successfully moved the content of the disk, I was unable to access it.

I considered password cracking for a while, but that would require taking the time to brute-force it which I’d rather avoid. While looking around for how to extract the username and password hash I found that you don’t need to crack it, you can simply blank it out. This guide (while written for an older Ubuntu version) went through the details. In short terms, boot from an Ubuntu live CD, install chntpw, locate the SAM file and blank out the password for the account in question. After doing this and rebooting I was automatically logged in and shown my glorious desktop with all previously installed programs.

This is also when I discovered that if you convert a physical hard drive to a virtual one in a VM, Windows will count that as hardware change and require a license re-activation. This would be no different if I had done a clean install, but I had hoped it could be avoided by converting the existing install.

In conclusion:
Yes, this can be done: duplicate the disk content, convert it to a format the virtual machine program reads and you can plug it into a VM. Though apart from being a fun hobby project it seems easier and less time-consuming to create a fresh install and then setup the same programs and configuration. If you do decide to convert a physical disk, make sure you create an image from the whole disk instead of a single partition, as this will save you lots of hassle in the long run. You can always clean up or wipe superfluous partitions in the VM afterwards.

Fra arkivet (del 2)

Som vi husker fra forrige episode så ligger det mye spennende og variert ute av nostalgiske NRK-programmer. La oss gå rett på sak med hva jeg har funnet siden sist:

Topp 20

I motsetning til hva jeg trodde, viste det seg at HC Andersen ikke var opprinnelig programleder . Det var faktisk en hel sesong før han tok over. Spekket med musikkvideor, intervjuer og mer eksperimentelt enn jeg husker det. Musikkmessig varierer det utifra hvor mye du liker det glade 90tall, men noe er glemt og noe har kanskje holdt seg bedre enn forventet. På godt og vondt er Topp 20 et innblikk i hva-nå-enn som var populært på det tidspunktet.

Flukta frå Dyreskogen

Koselig animasjonsserie om dyrene som samlet må flykte fra skogen de bor i når menneskene ødelegger den. Heldigvis har padde besøkt Hjorteparken, en nasjonalpark der de kan være trygge og i fred. Dermed legger de ut på en reise til sitt nye hjem, og møter en rekke utfordringer og hindre på veien. Serien har fortsatt noe av den beste intromusikken som er laget. Tror ikke jeg fikk sett første episode (eller bare deler av den) når serien ble sendt opprinnelig så fikk endelig sett hele nå. Senere sesonger går under navnet Dyra i Hjorteparken, men det ser ut som alt ligger ute.

Bård og Harald++

I humor-hjørnet fant jeg Åpen Post, Team Antonsen og Uti vår hage! Bortsett fra enkeltklipp av sketsjer på Youtube ante jeg ikke at så mye av det lå ute. Gledelig overrasket, her er det time på time med klassiske sketsjer og karakterer. 🙂


Lettere relater så er også deler av (eller alt?) av egentlig tilgjengelig. Problemet her er at mye av humoren baseres på satire eller aktuelle saker så er det vanskelig å ta poengene uten å ha fulgt med på nyhetene den uken det ble sendt. Så en episode og enkelte av vitsene referte helt åpenbart til “noe”, men det var vanskelig å få tak på hva den opprinnelige saken egentlig var.

Sikker på at det fortsatt ligger mye gull i arkivene som jeg har glemt eller som jeg rett og slett ikke har sett før. Stay tuned…

Why do trolls regenerate?

For a while I’ve wondered why everyone agree that trolls can heal their wounds by regenerating. As a monster type trolls are recognizable by being big, strong and for the most part not particularly bright. Depending on the setting for a given book or game, the trolls may look or behave slightly differently, but they all agree on a single trait: regeneration. This spans different settings, whether it is Dungeons and Dragons, the Might and Magic-series or a dozen other examples. In fact D&D feels so strongly about this point that fire or acid damage is required to finish them off.

So where did this idea originate from and how come it is so widespread? It’s not mentioned in the old fairy tales, at least not any I can remember. The closest would be the one about the troll who hid his heart someplace else and thus couldn’t be killed. They’re tough? Yes. Hard to kill? Certainly. Often have multiple heads? Ok, most games have glossed over that aspect for some reason. The core attributes are the same, making trolls challenging opponents in whichever form they take. Adding the ability to close the wounds and restore it’s health over time, they’re also able to make a comeback even when you thought the fight was over.

I did some digging and part of the answer is probably that Dungeons and Dragons included it. Most, if not all, computer role playing game are influenced by what D&D created, so it only makes sense that it would spread to other settings. So where did they pick it up? Turns out there’s a book named Three Hearts and Three Lions by Poul Anderson which feature regenerating trolls. This seems to be where D&D got the inspiration. The same novel also contains the basis for the aligment system and the paladin class! I don’t know if the story explains why or how trolls gained this trait, and I didn’t find any more details. Still, looks like Three Hearts and Three Lions was the original source, and that after it got added to D&D it spread further from there.

Fra arkivet (del 1)

(alternativ tittel: Perledykk i arkivene) En av mine hobbyer er å se gamle TV-program på nytt. Selv om en del har holdt seg bra er det ikke fullstending overlapp med hva som fortsatt fungerer og programmene som brente seg fast i minnet. (Som et eksempel har jeg fra sikre kilder at BBC sine Narnia-serier som ble vist i forkant av jul og påske, de… bør man ikke se på nytt.)

Uansett, i kampen om alle streamingtjenestene er det lett å glemme at også NRK sitter på arkiver som går flere tiår tilbake. Siden de har laget mye av innholdet selv, sitter de også på rettighetene til å ha TV- og radioprogrammer tilgjengelig i nettspilleren sin. Her er et lite utvalg i alt som finnes der:

Lillehammer OL ’94

Hva er mer naturlig å starte med en åpningsseremonien fra Lillehammer OL? Hele seremonien inkludert tenning av den olympiske ild og dansene vetter. Selv om grafikk og utforming er gjenkjennbar er det også overraskende lenge siden. Avslutningsseremonien ligger også ute, der det onde vettene til slutt tar over.

Charleys Tante

Farse med Rolv Weselund som den titulære tanten. Der andre farser har blitt sendt gang på gang, tror jeg bare jeg rakk å se denne en gang på TV. Modent for gjensyn her.

Midt i smørøyet

Hele ni årganger med ukens og lørdagens høydepunkt. Midt i Smørøyet var et ungdomsprogram med ulike temaer, sketsjer og serier. I tillegg til en ung Bertine Zetlitz som programleder dukker det også opp et par andre kjente fjes som liveopptreden av Espen Lind mens han ennå kalte seg Sway. Jeg vet jeg har sett de siste sesongene, men det er varierende hva som har festet seg og ikke. Det er også gøy å se gjester og medvirkende som senere har blitt kjent for helt andre ting, f.eks. sketsjene med Aslak fra gatas parlament og Hege Skøyen!

Savner Go’ Elg som hadde fast sendetid på fredagene, selv om det er en viss fare for at det kanskje ikke har holdt seg like bra. Antar grunnen til at det ikke ligger ute er pga rettigheter, da de pleide å flette serier og tegnefilmer inn i resten av programmet.

Brødrene Dal

Flere av seriene ble vist som en del av nevnte Midt i Smørøyet, men tre av seriene ligger også ute separat: Professer Drøvels Hemmelighet, Spektralsteinene og Legenden om Atlant-Is. Har alltid likt Brødrene Dal, spesielt utforsking av det ukjente og mysteriene rundt ekspedisjonene. Enkelte av episodene er riktignok lengre enkelt-sketsjer uten at det skjer så mye, men fortsatt veldig mye bra.

KLMs Vorspiel

Bonus: en annen KLM-serie fra tidlig 90-tall, nemlig Vorspiel . Stort sett enkeltstående skjetser, men også parodier som metrologene og en sammenhengende historie om “atomkofferten”.

Og det er bare hvis vi skraper i overflaten. Det ligger mye annet der for den som leter, min største utfordring er å huske hvilke programmer som finnes og ikke minst hva de het. Til tross for dette gjenoppdager jeg stadig nye (les:gamle) ting med jevne mellomrom, så det er ikke usannsynlig at det dukker opp en del 2. Følg med i neste episode…

Ukens kommando: git clone –depth

I blant så trenger jeg å sjekke ut et repo for å gjøre mindre endringer. Hvis repoet er ganske stort (årlang historikk, utallige bildefiler og gudene vet hva) så vil mesteparten av tiden gå med til å laste ned og kverne all historikken for disse filene. Det er jo strengt tatt overflødig når jeg bare skal fikse en stavefeil, pushe fiksen og så neppe røre repoet igjen. I disse tilfellene er det kjekt å vite at du kan hoppe over mye av historikken når du kloner. F. eks. git clone --depth=10 <reponavn> vil sjekke ut repoet, men tar kun med de 10 nyeste commitene. Ved å justere på --depth-flagget kan du ta med så mye eller lite du ønsker.

Pluss: går raskt og lettvint.
Minus: hvis du skal jobbe med flere eller større endringer eller lete i historikken lønner det seg heller å klone alt. Med mesteparten av historikken kuttet vil verktøy og commit-log anta at prosjektet oppstod i den første commiten du har tilgjengelig, hvilket sannsynligvis er misvisende for hvem som har jobbet på de ulike delene av kodebasen.

Alt i alt kjekt hvis du skal pushe en rask engangs-fiks og ikke har repoet tilgjengelig fra tidligere.

PS. Bazaar har tilsvarende funksjonalitet, bzr branch --stacked <reponavn> som lager en lokal utsjekk med nyeste versjon uten lokal historikk.

OpenBSD, python og wxallowed

(Mest som notat for meg selv, slik at jeg har mulighet til å finne tilbake til hvilke endringer jeg har gjort)

Nyere versjoner av OpenBSD (muligens introdusert i 6.1?) håndhever W^X som standard for alle programmer. Dette er en sikkerhetsfunksjon som gjør at programmer kan skrive eller kjøre deler av minnet, men ikke gjøre begge deler på samme minneområdet. Forsåvidt nyttig siden det hindrer at programmet kan (bli lurt til å) skrive nye instruksjoner som så blir kjørt.

Som sagt, en god ide, men etter å ha oppgradert VMen min til OpenBSD 6.1, støtte jeg på et bittelite problem i at python nektet å kjøre. Av det jeg kunne se av feilmeldinger var det fordi python bryter mot W^X på et vis og dermed ble nektet å kjøre. Siden jeg trenger å kunne kjøre python på dette systemet, var den en litt hard blokker. Søkte litt rundt omkring og fant flere som hadde støtt på tilsvarende problem. Som en workaround er det mulig å legge til `wxallowed` for filsystemet der python kjører fra i `/etc/fstab`. (Se stackoverflow for litt mer info)

Så jeg la til `wxallowed` til `/usr/local`, startet VMen på nytt, og da kjørte python uten problemer. Det åpenbare problemet er at jeg har en nyttig sikkerhetsfunksjon som jeg har slått av for et sett binærfiler, da jeg fant noen bedre fiks. 🙁 For min del er det ikke noe stort problem da jeg hovedsaklig kjører OpenBSD for å sjekke at Widelands bygger på flere platformer, selv om jeg gjerne skulle gjort det “ut-av-boksen” uten slike endringer. Det er neppe en endring jeg ville gjort i produksjon uten å grave dypere.


For litt over en uke siden la NRK ut Takin Ova, en dokumentar i fire deler som skildrer hiphopens historie her i Norge. Tittelen er selvfølgelig tatt fra Tommy Tee og TP Allstars sin klassiker som slo igjennom med et brak mot slutten av nittitallet. Med intervjuer av de fleste sentrale aktørene og klipp følger vi veien fra sær subkultur til en markant og dominerende del av mainstreamen.

Jeg så gjennom alle fire episodene dagen de ble lagt ut og var veldig fornøyd med resultatet. Det skinner gjennom at dokumentarskaperne er engasjerte og har ønsket å vise både hvordan men også hvorfor kulturen har utviklet seg som den har. En ting jeg likte spesielt godt var at de hadde intervjuet artister fra alle tidsepokene, fra Leo fra A-team og B.O.L.T. Warhead til Cezinando. Det viser veldig godt spennet og ikke minst hvordan hiphop-scenen har forandret seg siden 80-tallet.

Til tross for at historikken er godt dekket fra den spede start, til bølgen med norskspråklig rap frem til i dag, skulle skulle jeg gjerne sett at de hadde lengre tid både til å dekke mer og til å gå i dybden på ting. Ellers synes jeg det trakk litt ned at selv om det er intervjuer og fokus på andre steder, ender deler opp med å være litt Oslo-sentriske. Nå er veldig naturlig når mye av det som skjer og har foregått har utspilt seg der, men merket at f.eks. Trondheim knapt nok var nevnt. Med aktører som Fremmed Rase, Trepan og ikke minst 2xH-festivalen (som riktignok ble vist klipp fra) så blir det en del som jeg vil tro har påvirket historien men som ikke alltid i like stor grad trekkes frem når den fortelles.

Alt i alt en veldig solid og god dokumentar, og kan anbefales til hiphop-hoder og musikkinteresserte generelt.

Dette er ikke første dokumentaren om norsk hiphop som har blitt laget eller sendt på NRK. Blant annet laget Lydverket en rundt 2002-2003(?), men ser ikke ut som den ligger på NRK sine sider nå. Husker jeg har opptak av denne på kassett som har blitt sett om og om igjen. Det var første gang jeg hørte om A-team og B.O.L.T. Warhead og i hele tatt første gang jeg ble introdusert for hva som hadde skjedd før Tee Productions kom inn i bildet.

Det finnes også en dokumenter eller program til, som NRK sendte en gang på tidlig nittitall med det passende navnet Vandaler Vrenger Plater. Det handlet om hiphop, de forskjellige elementene og hvordan kulturen spirte.

Programmet gir et tidsutsnitt av det norske hiphopmiljøet anno 1990 som står i ganske skarp kontrast til dagens situasjon. Jeg så det ganske nylig for første gang og det var ganske fascinerende å få et innblikk i en periode hvor miljøet var veldig lite og de så vidt hadde begynt å gi ut musikk. Programmet blir sånn sett et dypdykk inn i kulturen og miljøet med intervjuer av bla. A-Team, Mc Cey og Tommy Tee med tidenes hanekam.

Det er sannsynligvis et av de få opptakene som dokumenterer norsk hiphop på den tiden, og jeg er glad det ligger tilgjengelig. Veldig interessant å få et lite glimt inn i miljøet på den tiden. Litt synd at bakgrunnsmusikken er mikset for høyt så den til tider drukner intervjuene, så det er dessverre deler som er vanskelig eller umulig å få med seg.

Det jeg ikke hadde fått med meg før nå var at VVP var en programserie, hvor hver sending var dedikert til et tema. Virker som de la flid i å få tittelen for hvert program til å passe forkortelsen på serien.

Finn bugs automatisk med SonarQube

Tilbake igjen etter JavaZone-konferansen som var i forrige uke. Alltid hyggelig å møte igjen kollegaer og eks-kollegaer jeg ikke ser så ofte, samt faglig påfyll.

I år holdt jeg en lyntale om SonarQube, bruk av statisk kodeanalyse og litt om hva slags problemer eller bugs vi kan oppdage. Målet er å kunne kontinuerlige sjekke etter problemer i kodebasen slik at vi kan rette dem opp i god tid før de havner i produksjon. Hvis dette høres interessant ut, ble det lagt ut opptak av foredraget  mitt.

(JavaZone var forøvrig veldig raske med å legge ut videor i år, og hadde lagt ut store deler allerede før konferansen var over.)

Maven – mer enn clean install

Tidligere denne uken var jeg på JavaZone-konferansen. Jeg så en rekke foredrag, hilste på gamle kjente og holdt en lyntale om Maven.

Maven er et byggverktøy som også holder orden på avhengighetene dine og ofte brukt i Java-prosjekter. Typisk bruk av Maven innebærer mvn clean install for å bygge et prosjekt og kjøre alle testene, men jeg ønsket å snakke litt om de andre tingene Maven kan gjøre.

Hvis dette høres interessant ut, finnes det en lengre beskrivelse av lyntalen i programmet, og du kan også se video av presentasjonen.

Testing expections in Java

Unit tests usually run a piece of code to verify the output or state to ensure it does what you excepted. With exceptions, it gets trickier. Once one is thrown the test ends abruptly, so how can you make sure that it was really triggered?

To demonstrate various strategies for testing exceptions, I’ve made a small example project in the form of a simple calculator. Most of the tests use plain JUnit4, except one which takes advantage of AssertJ assertions. But before we look at that, we should clarify what we want to accomplish by testing for exceptions. As with all testing, the main goal is to verify the code does what it is supposed to. In this case; throw an exception given a certain state or input. So we want to verify three things:
1. An exception was thrown
2. It was triggered by the state or input we wish to test
3. It was the error we expected

The example calculator is capable of adding or subtracting numbers. We will ignore the implementation for now, assume it is sane and focus on the tests. It has a special rule though, it should only add positive numbers together. For negative numbers, corresponding subtraction should be used instead. So if anything fails to follow this business rule, I want the the add()-method to throw an exception.

The first approach is covered in This suite contains some normal tests to ensure the calculator works as intended and one to verify it throws an exception when adding negative numbers. The latter is annotated with @Test(expected = IllegalArgumentException.class). This tells the test runner that the test should throw an exception of the specified type. The main problem here is that the annotation covers the whole test, which means that if any line throws such an exception the test will still pass. If we try to comment out the last line with calculator.add(1, -1); we might expect the test to fail since its no longer adding anything, but to our surprise it is still passing! Sounds like something else in the test is triggering an exception, but it’s hard to tell since it doesn’t seem possible to verify error message we get with the annotation. Thus, it only succeeds in point 1, but fails on 2 and 3. As soon as you do more that one thing in a test, you can no longer be sure which of the statements triggered the exception.

Since the annotation seemed too broad, let’s try to focus more on what we are trying to test. Ultimately, we want to know if the statement calculator.add(1, -1); throws an exception. So how do we normally deal with exceptions? Try-catch, of course. On to This is a quite normal pattern which has several variations, but the core concept is that we do some set up, then call the statement we wish to test inside a try block and assert that we got the exception we wanted. Of course we also need to keep an eye out for other possible outcomes, so there’s two additional checks to mark the test as a failure if another or no exceptions are thrown. Without, the test would still pass even though it didn’t trigger the exception we want.

When running this test it is easier to see why the annotated test failed earlier; the constructor is rather picky and excpects the name to start with a capital letter. Once we’ve fixed that, the test works as expected. Actually, the constructor should be called outside the try-block, since it is only part of the arrangement setting up the necessary prerequisites for the test. The core of the test is the add()-method, so we should have as little as possible else inside the try-catch. If an exception is thrown in the setup, the test should of course fail because we didn’t achieve the necessary state to test our specification.

This way, we know the exception was thrown, we’ve limited the code in the try-block to just the method call we want to test and we inspect the error message to verify what we got. In other words, the try-catch pattern accomplishes all three goals we established at the start. However, it is a bit cumbersome to set up with all the try-catch boilerplate each time we want to test an exception. Worst case, we create an incomplete test which misses a case without reporting the test as failing.

For an alternative use of this pattern, see It uses a boolean flag to ensure that we don’t leave the test without asserting properly. I think this is somewhat better, but we still need to write a lot of boilerplate and end up introducing a new variable.

While I think the try-catch pattern is a step in the right direction, I’m not too happy with the need to add the same extra lines as safeguards over and over. Luckily, I found that JUnit (version 4.7 and newer) comes with a built-in rule to make this easier. The rule is called ExpectedException and is used in The rule is defined at the top and basically says that by default, no exceptions should be thrown by the tests. But where you want an exception to be triggered, the rule can be instructed to look for the exception type and error message which is expected. These instructions can be placed after all the all the setup so that we have it separated from the minimal section we wish to test.

This guarantees that the exception is triggered where we wanted it (goal #2), as well as specifying type and error message (goal #3). If it doesn’t encounter an exception matching its expected criteria it will mark the test as a failure, thereby fulfilling goal #1. All in all, it does an excellent job to fulfil all requirements.

The examples above are all using JUnit4, but I also looked for other solutions. I found AssertJ, a fluent assertion framework which contains a lot of useful things. (It started out as a fork of fest assert, for those more familiar with that). contains an example demonstrating how it can deal with exceptions.

The code which should throw the exception is placed inside a lambda expression, which makes it possible to observe and verify the result from the outside. In terms of separation, this is perhaps one step further than the other examples, since we know that the exception can only be triggered by the code we place inside the lambda. We can also inspect it, looking at the type and the error message. This allows us full control to verify the exception when it has been thrown as well as cleary separate the section we except to throw something from the other parts of the test.

In conclusion, I prefer ExpectedException because it gives you the greatest amount of control/readability when testing exceptions. The annotation can lead to brittle tests if they have more than one line or method call in them. Setting up try-catch each time seems too cumbersome, plus I fear it is far too easy to write a bad test if you forget to add one of the safe guards. I liked the AssertJ approach though, I will consider using this for future projects.

And as a bonus at the end, there is an interesting proposal in the JUnit bug tracker on something similar to what AssertJ does, which means it might become available in JUnit someday.