11 maja 2009

Apache Maven: ${basedir} w pom.xml w projekcie wielomodułowym

To już nie pierwszy raz, kiedy testy jednostkowe w projekcie zarządzanym przez Apache Maven działają, kiedy są uruchomione z katalogu projektu, ale już nie, kiedy są uruchomione z katalogu projektu macierzystego. Za przykład możnaby wziąć projekt examples/webservices-ws-security z Apache OpenEJB, który wywołuje sun.security.tools.KeyTool - narzędzie, które jest narzędziem zewnętrznym w stosunku do mavena i dla którego ścieżki względne w pom.xml mają znaczenie. Jeśli więc umieścimy taki fragment w pom.xml:
 <property name="server.alias" value="serveralias"/>
<property name="server.keypass" value="serverPassword"/>
<property name="server.keystore" value="target/classes/META-INF/serverStore.jks"/>
<property name="server.storepass" value="keystorePass"/>
<property name="server.dname" value="'cn=serveralias'"/>

<java classname="sun.security.tools.KeyTool">
<arg line="-genkey" />
<arg line="-alias ${server.alias}" />
<arg line="-keypass ${server.keypass}" />
<arg line="-keystore ${server.keystore}" />
<arg line="-storepass ${server.storepass}" />
<arg line="-dname ${server.dname}" />
<arg line="-keyalg ${keyalg}" />
<permissions>
<grant class="java.security.AllPermission" />
</permissions>
</java>
to oczywiście zmienna server.keystore jest względna i czuła na miejsce uruchomienia poleceń mvn - w katalogu projektu wszystko jest cacy, ale już poza nim (chociażby w katalogu wyżej) pojawi się błąd braku wskazanego pliku (ścieżka wskaże nieistniejący plik, a nawet poszczególne katalogi)!

Szczęśliwie, rozwiązanie jest pod ręką - zmienna ${basedir}. Wystarczy poprzedzić ścieżki względne zmienną ${basedir}, aby uniezależnić je od miejsca wykonania poleceń w projekcie.

Ostatecznie zmiana dotyczy jedynie server.keystore z ${basedir}:
 <property name="server.keystore" value="${basedir}/target/classes/META-INF/serverStore.jks"/>
Poza tym, żadnych innych zmian.

Więcej o ${basedir} w dokumentacji Apache Maven - POM Reference::The BaseBuild Element Set oraz Maven Getting Started Guide (szukaj "basedir").

Wciąż pod wpływem Apache Maven, czy może powrót do korzeni, czyli Apache Ant z Apache Ivy? A może Apache Buildr? Zauważam coraz częściej potrzebę łączenia kilku narzędzi do zarządzania projektem, czyli Maven dobry, ale jest wciąż miejsce dla Ant, a nieśmiało zerkam w stronę Buildr.