Meer met Maven – Convention over configuration

In elke editie zal Robert Scholte een probleem voorleggen en deze oplossen met behulp van Apache Maven om meer inzicht te geven in Maven zelf en de vele beschikbare plugins.

Er zijn tal van communities en mailinglists waarlangs developers vragen kunnen stellen als ze met een probleem zitten. Eén van deze communities is stackoverflow.com, waar ook ik regelmatig antwoord geef op onder meer Maven vraagstukken. Tot mijn verbazing staat een relatief eenvoudig probleem bovenaan mijn meest gewaarde antwoorden:

 

“I have a minor problem with maven. When I run the command mvn package I get the following warning:

[WARNING] JAR will be empty – no content was marked for inclusion!

The build is successful but the produced jar-file is empty as the warning says. Why is this and what am I doing wrong?”

 

Hierna volgt een pom.xml met allerlei geconfigureerde paden en dito plugins.

Botweg zijn er twee mogelijkheden voor deze oorzaak: de maven-jar-plugin kijkt in de verkeerde directories voor content óf de maven-jar-plugin kijkt wel in de juiste directories, maar deze zijn leeg. In dit geval bleek het laatste geval het probleem te zijn: de maven-compiler-plugin was dusdanig geconfigureerd dat er geen code was om te compileren. Het verwijderen van de configuratie van deze plugin bleek al voldoende om de jar te vullen.

Dit is één van de vele voorbeelden die ik heb gezien, waar uiteindelijk blijkt dat ‘Less is more’. En dat is een van de belangrijkste uitgangspunten geweest bij het ontwikkelen van Maven als antwoord op de ervaringen met Ant.

Apache Ant is (nog steeds) een hele krachtige tool waarmee je taken uit kunt voeren. Er is een hele set aan ‘tasks’ die je kunt gebruiken, maar deze moet je zelf steeds expliciet uitwerken in een build.xml. Met een lege build.xml bereik je niks. Dit was een behoorlijke doorn in het oog bij de ontwikkelaars van Maven. Waarom moet je steeds zoveel uitwerken, terwijl voor bijvoorbeeld een java-project de uit te voeren stappen altijd hetzelfde zijn en waarbij je vaak al afspraken hebt gemaakt over de locaties van de source-bestanden. Vandaar dat men kwam met het principe van ‘convention over configuration’, oftewel: ken default waarden toe daar waar mogelijk, maar biedt altijd de oplossing om dit aan te passen.

Het volgende voorbeeld is de minimale pom.xml en dit is al voldoende om onder andere code te compileren, te testen en te packagen tot een jar. Ter vergelijking: in een build.xml voor Ant moet je elk van de zes stappen van de jar-lifecycle expliciet opnemen en configureren met als gevolg dat je al snel ruim honderd regels aan instructies hebt voor hetzelfde resultaat.


<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>
</project>

 

Als je projecten wilt migreren naar Maven, dan kun je dus prima je folder structuur in tact laten en in de pom.xml de default waardes voor deze directories overschrijven. Dit heeft ook als voordeel dat je in deze periode beide buildtools kunt gebruiken. Migreren naar Maven hoeft dus niet in een ‘big bang’ te gebeuren. Echter zou ik bij het starten van nieuwe projecten proberen om zo veel mogelijk gebruik te maken van de beschikbare conventies. Hierdoor blijft de pom.xml overzichtelijker én weten de collega ontwikkelaars en eventuele nieuwe teamleden meteen waar ze aan toe zijn zonder eerst de build-instructies uit te pluizen.

Zie ook http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html voor de uitleg van de default folder structuur.