<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>blog.grejpfrut.org &#187; ant</title>
	<atom:link href="http://grejpfrut.org/blog/tag/ant/feed/" rel="self" type="application/rss+xml" />
	<link>http://grejpfrut.org/blog</link>
	<description>a DRY KISS</description>
	<lastBuildDate>Fri, 22 Jan 2010 20:58:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>M2: tworzenie wersji dystrybucyjnej</title>
		<link>http://grejpfrut.org/blog/2006/04/20/m2-tworzenie-wersji-dystrybucyjnej/</link>
		<comments>http://grejpfrut.org/blog/2006/04/20/m2-tworzenie-wersji-dystrybucyjnej/#comments</comments>
		<pubDate>Thu, 20 Apr 2006 19:37:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[po polsku]]></category>
		<category><![CDATA[ant]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://maneo.webd.pl/blog/?p=14</guid>
		<description><![CDATA[
Hmmm&#8230;   maven to elastyczne narzędzie, żeby osiągnąć zamierzony cel trzeba czasami przebić się przez całkiem sporo nakonfigurować. W dzisiejszym odcinku   będzie o trzech pluginach: assembly, jar i antrun. W maven 1.x było wszechobecne Jelly, chciałem się przekonać jak będzie wyglądało tworzenie wersji dystrybucyjnej w m2.


Zacznijmy od projektu który wygenerowaliśmy poprzednim razem, [...]]]></description>
			<content:encoded><![CDATA[<p>
<b>Hmmm&#8230; <img src='http://grejpfrut.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  maven to elastyczne narzędzie</b>, żeby osiągnąć zamierzony cel trzeba czasami przebić się przez całkiem sporo nakonfigurować. W dzisiejszym odcinku <img src='http://grejpfrut.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  będzie o trzech pluginach: assembly, jar i antrun. W maven 1.x było wszechobecne Jelly, chciałem się przekonać jak będzie wyglądało tworzenie wersji dystrybucyjnej w m2.
</p>
<p>
<b>Zacznijmy od projektu</b> który wygenerowaliśmy poprzednim razem, jeżeli chcielibyśmy wygenerować teraz jar&#8217;a wystarczy wydać polecenie <code>mvn package</code>. M2 bez żadnych problemów stworzy nam jar&#8217;a, teraz dodajmy do naszego projektu jakieś zasoby. Aby zasoby były bezproblemowo dołączone do jar&#8217;a musimy stworzyć katalog $project.base.dir/src/main/resources i wszystkie zasoby wrzucać właśnie do niego. Po utworzeniu jar&#8217;a zostaną one przekopiowane do podstawowej ścieżki archiwum.
</p>
<p>
Gdy zajdzie konieczność <b>zmiany manifestu jar&#8217;a</b> to wedle mojej skromnej wiedzy musimy pogrzebać trochę w konfiguracji maven-jar-plugin. Można to zrobić specyfikując w pom.xml następujący blok:</p>
<pre class="brush: xml;">
&lt;build&gt;
     ...
    &lt;plugins&gt;
     &lt;plugin&gt;
      &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
      &lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
      &lt;configuration&gt;
	 &lt;archive&gt;
	   &lt;manifest&gt;
	     &lt;addClasspath&gt;true&lt;/addClasspath&gt;
	     &lt;addExtensions&gt;true&lt;/addExtensions&gt;
	     &lt;classpathPrefix&gt;./lib/&lt;/classpathPrefix&gt;
 	     &lt;mainClass&gt;org.grejpfrut.App&lt;/mainClass&gt;
             &lt;packageName&gt;org.grejpfrut&lt;/packageName&gt;
	   &lt;/manifest&gt;
 	 &lt;/archive&gt;
      &lt;/configuration&gt;
     &lt;/plugin&gt;
    &lt;/plugins&gt;
    ...

  &lt;build&gt;
</pre>
<p><b>Cała magia</b> siedzi wewnątrz sekcji <code>&lt;configuration&gt;</code> tutaj specyfikujemy, że do manifestu ma być dodana informacja o classpath, tag classpathPrefix instruuje maven-jar-plugin aby przed każdą zależnością dostawiał ścieżke <code>./lib</code> (np. <code>./lib/log4j-1.2.13.jar</code>). Takie rozwiązanie pozwala utrzymać porządek w katalogu dystrybucji i rozdzielić główny jar od jego zależności. Pozostałe parametry nie wymagają wyjaśnień.
</p>
<p>
Aby sprawdzić poprawność manifestu możemy użyć kodu App.java który podałem w poście o maven 1.x, należy uaktualnić plik <code>pom.xml</code> o opis <code>log4j</code> w sekcji dependencies i wydać polecenie <code>mvn package</code>. Po rozpakowaniu jar&#8217;a możemy podejrzeć plik <code>Meta-inf/Manifest.mf</code>. W katalogu Meta-inf maven umieszcza kopie pom.xml oraz plik pom.properties który zawiera najbardziej podstawowe informacje o projekcie (wersja, artifactId, groupId). Po co te pliki? </p>
<p><i>&#8220;The pom.xml and pom.properties files are packaged up in the JAR so that each artifact produced by Maven is self-describing and also allows you to utilize the metadata in your own application if the need arises. One simple use might be to retrieve the version of your application.&#8221;</i><a href="http://maven.apache.org">maven.apache.org</a>
</p>
<p>
<b>Wyobrażmy sobie jednak</b>, że pojawia się kolejny problem&#8230; mianowicie w przypadku zasobów związanych z umiedzynarodowieniem naszej aplikacji bywa, że properties muszą znajdować się w katalogu src w katalogu związanym z odpowiednim pakietem. Problem ten wystąpi zawsze gdy będziemy chcieli umieścić zasoby w katalogu innym niż wposmniane wcześniej src/main/resources (bądź działającym na tej podobnej zasadzie src/test/resources). W czasie tworzenia jar&#8217;a m2 po prostu nie przekopiuje niczego poza skompilowanymi klasami. Zastosowane przez nas rozwiązanie zostało oparte o ant&#8217;a.
</p>
<p> <b>W m2 wszystko związane jest z fazami</b> i cyklem zycia oprogramowania. W starym mavenie specyfikowaliśmy sekcje post i pregoal w maven.xml. W m2 aby użyć jakiegoś celu/wtyczki który nie należy do zdefiniowanego cyklu budowania musimy go zadeklarować w pom.xml. Tak też musimy postąpić z maven-antrun-plugin.</p>
<pre class="brush: xml;">
    &lt;plugin&gt;
      &lt;artifactId&gt;maven-antrun-plugin&lt;/artifactId&gt;
      &lt;executions&gt;
        &lt;execution&gt;
	   &lt;phase&gt;compile&lt;/phase&gt;
	   &lt;configuration&gt;
	    &lt;tasks&gt;
		&lt;copy todir=&quot;${basedir}/target/classes/&quot;&gt;
	  	  &lt;fileset dir=&quot;${basedir}/src/main/java/&quot;&gt;
		     &lt;include name=&quot;**/lang/*.properties&quot;&gt;
	 	  &lt;/fileset&gt;
		&lt;/copy&gt;
	    &lt;/tasks&gt;
	   &lt;/configuration&gt;
	   &lt;goals&gt;
	     &lt;goal&gt;run&lt;/goal&gt;
	   &lt;/goals&gt;
	 &lt;/execution&gt;
      &lt;/executions&gt;
     &lt;/plugin&gt;
</pre>
<p>Plugin antrun pozwala wykonać dowolne zadania ant&#8217;a i przypisać je do konkretnego etapu tworzenia oprogramowania. Widzimy tutaj prosty skrypt który wykonuje to czego m2 nie robi.
</p>
<p>
<b>Jesteśmy coraz bliżej</b> działającej dystrybucji <img src='http://grejpfrut.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . Do tworzenia dystrybucji używa się wtyczki assembly. Jest ona całkiem przyzwoicie opisana, więc w razie pytań warto <a href="http://maven.apache.org/plugins/maven-assembly-plugin/">tam zajrzeć</a>. Poza tym naprawde dobrze opisał to <a href="http://laskowski.org.pl/">Jacek Laskowski</a>. Mój opis będzie więc zgrubny, ogranicze się tylko do wypisania tego co zmieniłem w stosunku do tego co zaporoponował <a href="http://laskowski.org.pl">Jacek</a>. Oto co zostało dodane do pom.xml:</p>
<pre class="brush: xml;">
       &lt;plugin&gt;
	 &lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;
	 &lt;version&gt;2.0.1&lt;/version&gt;
	 &lt;configuration&gt;
	   &lt;descriptors&gt;
  	     &lt;descriptor&gt;src/main/assembly/jar.xml&lt;/descriptor&gt;
	   &lt;/descriptors&gt;
 	   &lt;finalName&gt;${artifactId}&lt;/finalName&gt;
	 &lt;/configuration&gt;
	&lt;/plugin&gt;
</pre>
<p>Jedyną ciekawą rzeczą w tym kawałku xml&#8217;a jest specyfikacja deskryptora. Standardowo deskryptory dla assembly składowane są w src/main/assembly, nasz projekt może być dystrybuowany na więcej niż jeden sposobów. To w jaki sposób każdy z nich będzie tworzony zależy właśnie od opisu. Dokładny opis możliwości i predefiniowanych deskryptorów na stronie pluginu. </p>
<p>
Deskryptor jar.xml musi zostać dodany do projektu w ścieżce która specyfikujemy w pom.xml.</p>
<pre class="brush: xml;">
    &lt;assembly&gt;
        &lt;id&gt;zip&lt;/id&gt;
	&lt;formats&gt;
	 &lt;format&gt;jar&lt;/format&gt;
	&lt;/formats&gt;
	&lt;includeBaseDirectory&gt;false&lt;/includeBaseDirectory&gt;
	&lt;fileSets&gt;
 	  &lt;fileSet&gt;
           &lt;directory&gt;target&lt;/directory&gt;
           &lt;outputDirectory&gt;&lt;/outputDirectory&gt;
            &lt;includes&gt;
             &lt;include&gt;*.jar&lt;/include&gt;
            &lt;/includes&gt;
           &lt;/fileSet&gt;
           &lt;fileSet&gt;
	     &lt;directory&gt;lib&lt;/directory&gt;
             &lt;outputDirectory&gt;&lt;/outputDirectory&gt;
             &lt;includes&gt;
              &lt;include&gt;*.dll&lt;/include&gt;
             &lt;/includes&gt;
           &lt;/fileSet&gt;
        &lt;/fileSets&gt;
       &lt;dependencySets&gt;
         &lt;dependencySet&gt;
           &lt;outputDirectory&gt;/lib&lt;/outputDirectory&gt;
           &lt;unpack&gt;false&lt;/unpack&gt;
           &lt;scope&gt;runtime&lt;/scope&gt;
           &lt;/dependencySet&gt;
         &lt;/dependencySets&gt;
       &lt;/assembly&gt;
</pre>
<p>Tu będzie troche komentarza, określamy format dystrybucji (oprócz zip&#8217;a może być jeszcze chyba tar i jar) tutaj zip. Pierwszy fileset załącza do dystrybucji nasz jar, wygenerowany gdzieś około pierwszego akapitu tego artykułu. Znajdzie sie on w katalogu /target/ i zostanie przekopiowany do głównego katalogu dystrybucji. W <a href="http://weed.xt.pl">Weed</a> używamy kilku dll&#8217;i, który na codzień mieszkają w $project.base.dir/lib zostaną również przekopiowane do katalogu lib. Następnie włączamy do dystrybucji wszystkie zależności, zgodnie z opisaną wcześniej filozofią zostaną one przeniesione do lib. Przy specyfikacji <code>dependencySet</code> ważne jest aby zaznaczyć jaki <code>scope</code> mają mieć zależności włączane do dist&#8217;a  (tutaj np. nie zostanie włączony junit który ma <code>scope</code> test).
</p>
<p>
<b>To właściwie wszystko <img src='http://grejpfrut.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </b>. Prawda jakie to proste <img src='http://grejpfrut.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  <img src='http://grejpfrut.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . teraz <code>mvn assembly:assembly</code> dostaniemy ładnego zip&#8217;a którego po rozpakowaniu możemy uruchomić gdzie nam się spodoba. Drugi wart zapamiętania cel to <code>mvn assembly:directory</code> tworzy on całą strukturę, ale nie pakuje jej do zip&#8217;a. Niezłe do testowania. Uruchamiamy : <code> java -jar test-1.0-SNAPSHOT.jar </code>
</p>
<p>
Problem: niewiem czemu zależności które mają scope : system, nie są uwzględniane w manifeście przy tworzeniu jar&#8217;a. jeżeli ktoś wie dlaczego i jak sobie z tym poradzić będę wdzięczny. <img src='http://grejpfrut.org/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://grejpfrut.org/blog/2006/04/20/m2-tworzenie-wersji-dystrybucyjnej/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
