<?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>The Code-House Blog</title>
	<atom:link href="http://blog.code-house.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.code-house.org</link>
	<description>Blog niewielkiej firmy z branży IT.</description>
	<lastBuildDate>Fri, 11 Jun 2010 15:43:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Brakujący element Javarsovii</title>
		<link>http://blog.code-house.org/2010/06/brakujacy-element-javarsovii/</link>
		<comments>http://blog.code-house.org/2010/06/brakujacy-element-javarsovii/#comments</comments>
		<pubDate>Fri, 11 Jun 2010 15:43:19 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Code-House]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=279</guid>
		<description><![CDATA[Tegoroczna edycja konferencji Javarsovia jest bez wątpienia największym wydarzeniem tej kategorii w Polsce. Grono sponsorów i partnerów nafaszerowane gigantycznymi korporacjami (IBM, Oracle, Microsoft, Adobe, Google). Pomyśleć, że Code-House w zeszłym roku był sponsorem tej niewielkiej konferencji a w tym roku nie przyszło by nam rywalizować nawet o ławkę sponsorów rezerwowych. :-) Moje gratulacje dla kapituły [...]]]></description>
			<content:encoded><![CDATA[<p>Tegoroczna edycja konferencji Javarsovia jest bez wątpienia największym wydarzeniem tej kategorii w Polsce. Grono sponsorów i partnerów nafaszerowane gigantycznymi korporacjami (<a href="http://www.javarsovia.pl/news/33/72/IBM-partnerem-konferencji.html">IBM</a>, <a href="http://www.javarsovia.pl/news/32/72/Oracle-Zlotym-Sponsorem.html">Oracle</a>, <a href="http://www.javarsovia.pl/news/27/72/Microsoft-Zlotym-Sponsorem-Javarsovii-2010.html">Microsoft</a>, <a href="http://www.javarsovia.pl/news/16/72/Adobe-sponsorem-Javarsovii-2010.html">Adobe</a>, <a href="http://www.javarsovia.pl/news/20/72/Google-zlotym-sponsorem-Javarsovia-2010.html">Google</a>). Pomyśleć, że Code-House w zeszłym roku był sponsorem tej niewielkiej konferencji a w tym roku nie przyszło by nam rywalizować nawet o ławkę sponsorów rezerwowych. :-) Moje gratulacje dla kapituły przekazuję już teraz.</p>
<p>Wróćmy jednak do meritum &#8211; a mianowicie czego brakuje na Javarsovii. :-) Brakuje prelekcji o OSGi, które mimo porządnego wieku (10 lat) jest w dalszym ciągu nowością dla wielu developerów. Szczęśliwie, w ramach spotkań <a href="http://groups.google.com/group/warszawa-jug/">Warszawa JUG</a> było zaplanowane spotkanie pt. <strong>Springowe spojrzenie na OSGi &#8211; Spring Dynamic Modules for OSGi(tm)</strong> &#8211; które miał poprowadzić Jacek Lis. Niestety, Jacek w planowanym terminie (15 czerwiec) będzie poza Warszawą. Aby obronić OSGi i załatać deficyt tego tematu na Javarsovii (zgłaszałem się z OSGi R4.2 Enterprise do C4P), postanowiłem zastąpić Jacka i poprowadzić prezentację &#8211; której temat również ewoluował na <strong>Spring Dynamic Modules, Blueprint, OSGi &#8211; deklaratywne</strong>.</p>
<p>Podsumowując, czego można się spodziewać w najbliższy wtorek:</p>
<ul>
<li>Celem prezentacji jest przedstawienie OSGi.</li>
<li>Tradycyjne podejście do usług w OSGi.</li>
<li>Co dodaje Spring DM/Blueprint.</li>
<li>Jak to uruchomić na <a href="http://felix.apache.org/site/apache-felix-karaf.html">Karafie</a><sup>1</sup></li>
</ul>
<p>Serdecznie zapraszam wszystkich zainteresowanych jak i zawiedzionych tym, że OSGi nie będzie na Javarsovii. :-)</p>
<hr />
<sup>1</sup> Trwają negocjacje, czy Apache Felix Karaf zostanie projektem wysokiego poziomu (TLP) fundacji Apache.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2010/06/brakujacy-element-javarsovii/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Praktyki studenckie w Code-House</title>
		<link>http://blog.code-house.org/2010/04/praktyki-studenckie-w-code-house/</link>
		<comments>http://blog.code-house.org/2010/04/praktyki-studenckie-w-code-house/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 11:35:52 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Code-House]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=273</guid>
		<description><![CDATA[Jakiś czas temu Jacek Laskowski wspominał o praktykach studenckich w IBM.

Celem praktyk w IBM jest zapoznanie się z produktami korporacji, praktyki w Code-House mają nieco inny wymiar &#8211; przede wszystkim technologiczny. Część z dziedzin, w których obracamy się obecnie przy okazji ServiceMixa jest nieco futurystyczna (OSGi R 4.2, dOSGi), część za to bardzo praktyczna np. [...]]]></description>
			<content:encoded><![CDATA[<p>Jakiś czas temu <a href="http://jaceklaskowski.pl/">Jacek Laskowski</a> wspominał o <a href="http://jlaskowski.blogspot.com/2010/03/praktyki-studenckie-w-ibm-ta-edycja.html">praktykach studenckich w IBM</a>.<br />
<!-- more --><br />
Celem praktyk w IBM jest zapoznanie się z produktami korporacji, praktyki w Code-House mają nieco inny wymiar &#8211; przede wszystkim technologiczny. Część z dziedzin, w których obracamy się obecnie przy okazji ServiceMixa jest nieco futurystyczna (OSGi R 4.2, dOSGi), część za to bardzo praktyczna np. szerokie użycie Mavena oraz Spring Framework czy JAX-WS/JAX-RS. <strong>Cały kod, który powstanie w wyniku praktyk będzie opublikowany na licencji Apache 2.0 i udostępniony publicznie</strong>.</p>
<p>Pula tematów dla praktykantów obejmuje następujące projekty fundacji Apache:</p>
<ul>
<li>Apache ServiceMix 4</li>
<li>Apache Ode</li>
<li>Apache ActiveMQ</li>
<li>Apache Camel</li>
<li>Apache Karaf</li>
</ul>
<h2>Organizacja praktyk</h2>
<p>Praktyki <strong>są bezpłatne</strong> (niestety), odbywają się w trybie zdalnym i trwają do 3 miesięcy &#8211; termin rozpoczęcia praktyk jest uzgadniany ze studentem. Nie ma konieczności przebywania w naszym biurze &#8211; cały proces naboru aplikacji odbywa się przy pomocy Internetu i dopiero ostatni etap &#8211; rozmowa kwalifikacyjna &#8211; wymaga spotkania. Na co dzień konsultacje będziemy odbywać przy pomocy komunikatorów &#8211; Skype, GTalk, w skrajnym wypadku Gadu-Gadu. ;-) Co dwa tygodnie podsumowujemy minioną &#8220;iterację&#8221; oraz planujemy następną.<br />
Po wprowadzeniu do narzędzi i projektów studenci będą wypływać na głębokie wody &#8211; czyli samodzielną realizację zadań.</p>
<p>Do zarządzania, koordynacji zadań oraz dokumentacji i weryfikacji kodu wykorzystujemy narzędzia Atlassian:</p>
<ul>
<li>JIRA</li>
<li>Green Hopper</li>
<li>Confluence</li>
<li>Bamboo</li>
<li>Fisheye</li>
</ul>
<h2>Jak aplikować?</h2>
<p>Jedyną wymaganą cechą jest znajomość języka Java &#8211; która zostanie zweryfikowana testem. Jeśli dysponujesz tą cechą i jesteś miłośnikiem technologii zapraszamy do wysyłania aplikacji pod adres rekrutacja@code-house.org z tematem Praktyki 2010. Nabór aplikacji na najbliższą edycję praktyk prowadzimy do 20 kwietnia. W zależności od rezultatów będą organizowane kolejne.<br />
Nieco więcej informacji znajdziecie na stronie <a href="http://code-house.org/o-firmie/praktyki/2010">Praktyki Studenckie 2010</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2010/04/praktyki-studenckie-w-code-house/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OSGi-fikacja oraz nowe bundle w repozytorium ServiceMix</title>
		<link>http://blog.code-house.org/2010/03/osgi-new-bundles-servicemix-repository/</link>
		<comments>http://blog.code-house.org/2010/03/osgi-new-bundles-servicemix-repository/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 15:26:52 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Camel]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[ServiceMix]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=249</guid>
		<description><![CDATA[W tym wpisie zostanie omówiony proces OSGi-fikacji artefaktów, który przechodziłem gdy uruchamiałem prostą usługę na ServiceMix, która miała śledzić zewnętrzny RSS i pobierać z niego wpisy. Postanowiłem skorzystać z camel-rss. Przykłady które były do niego załączone są wystarczające by stworzyć odpowiedniego konsumenta&#8230;

Problem zaczął się gdy usiłowałem uruchomić endpoint camela w OSGi. Mimo poprawnej konfiguracji, rozwiązanych [...]]]></description>
			<content:encoded><![CDATA[<p>W tym wpisie zostanie omówiony proces OSGi-fikacji artefaktów, który przechodziłem gdy uruchamiałem prostą usługę na ServiceMix, która miała śledzić zewnętrzny RSS i pobierać z niego wpisy. Postanowiłem skorzystać z camel-rss. Przykłady które były do niego załączone są wystarczające by stworzyć odpowiedniego konsumenta&#8230;<br />
<!-- more --><br />
Problem zaczął się gdy usiłowałem uruchomić endpoint camela w OSGi. Mimo poprawnej konfiguracji, rozwiązanych zależności otrzymywałem wyjątek:</p>
<pre class="brush: plain;">java.lang.NoClassDefFoundError: Could not initialize class com.sun.syndication.feed.synd.SyndFeedImpl
        at com.sun.syndication.io.SyndFeedInput.build(SyndFeedInput.java:123)
        at org.apache.camel.component.rss.RssUtils.createFeed(RssUtils.java:34)
        at org.apache.camel.component.rss.RssEntryPollingConsumer.createFeed(RssEntryPollingConsumer.java:54)
        at org.apache.camel.component.feed.FeedEntryPollingConsumer.poll(FeedEntryPollingConsumer.java:42)
        at org.apache.camel.impl.ScheduledPollConsumer.run(ScheduledPollConsumer.java:106)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
        at java.util.concurrent.FutureTask$Sync.innerRunAndReset(FutureTask.java:317)
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:150)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(ScheduledThreadPoolExecutor.java:98)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(ScheduledThreadPoolExecutor.java:181)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:205)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:619)
</pre>
<p>Naturalnie, strasznie zirytowany, wziąłem się za dochodzenie &#8211; początkowo byłem przekonany że brakuje importów w camel-rss jednakże krótkie googlowanie <a href="http://js.jipiju.com/2009/08/04/osgi-jumping-through-classoading-hoops/">wskazało rozwiązanie</a>. Winne było kilka linii w klasie PluginManager:</p>
<pre class="brush: java;">
    private Class[] getClasses() throws ClassNotFoundException {
        // Ten ClassLoader wskazuje na bundle w którym jest zdefiniowany endpoint!
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        List classes = new ArrayList();
        boolean useLoadClass = Boolean.valueOf(System.getProperty(&quot;rome.pluginmanager.useloadclass&quot;, &quot;false&quot;)).booleanValue();
        for (int i = 0; i &lt;_propertyValues.length; i++) {
            // Naturalnie tutaj leciał ClassNotFoundException
            Class mClass = (useLoadClass ?  classLoader.loadClass(_propertyValues[i]) :
                Class.forName(_propertyValues[i], true, classLoader));
            classes.add(mClass);
        }
        Class[] array = new Class[classes.size()];
        classes.toArray(array);
        return array;
    }
</pre>
<p>Po przeróbce metoda wygląda następująco.</p>
<pre class="brush: java;">
    private Class[] getClasses() throws ClassNotFoundException {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        List classes = new ArrayList();
        boolean useLoadClass = Boolean.valueOf(System.getProperty(&quot;rome.pluginmanager.useloadclass&quot;, &quot;false&quot;)).booleanValue();
        for (int i = 0; i &lt;_propertyValues.length; i++) {
            Class mClass = null;
            try {
                if (useLoadClass) {
                    mClass = classLoader.loadClass(_propertyValues[i]);
                } else {
                    mClass = Class.forName(_propertyValues[i], true, classLoader);
                }
            } catch (ClassNotFoundException e) {
                // Jeśli zewnętrzny class loader zgłosi wyjątek usiłujemy załadować klasę
                // z bieżącej paczki
                mClass = getClass().getClassLoader().loadClass(_propertyValues[i]);
            }
            classes.add(mClass);
        }
        Class[] array = new Class[classes.size()];
        classes.toArray(array);
        return array;
    }
</pre>
<p>Naturalnie, można się zastanawiać po co bibliotece do obsługi RSS zabiegi z ClassLoaderami. Otóż ROME wykorzystuje plik .properties do konfiguracji &#8220;pluginów&#8221; (poors man DI). W określonych miejscach możemy dodać własne klasy które obsłużą jakiś niestandardowy format. Problem w tym, że &#8220;patent&#8221; z plikiem properties świetnie sprawdza się przy płaskim classloaderze, niestety zawodzi w OSGi. Należy pamiętać o tym, że w OSGi nasz class loader ma dostęp do tego, do czego mu pozwalają importy i nie wszystko to, co widzi nasze oko w archiwum musi być dostępne dla naszego programu.</p>
<p>Przy okazji stworzenia <a href="https://issues.apache.org/activemq/browse/SMX4-510">bundle z ROME 1.0</a> postanowiłem również stworzyć bundle dla <a href="https://issues.apache.org/activemq/browse/SMX4-511">Apache POI 3.6</a>. Bibliotekę tą wykorzystywałem wspólnie z <a href="http://nurkiewicz.blogspot.com/">Tomkiem Nurkiewiczem</a> podczas prezentacji &#8220;Mule ESB vs ServiceMix&#8221;.</p>
<h2>OSGi-fikacja</h2>
<p>Bardzo swobodna definicja:</p>
<blockquote><p><a name="OSGi-fikacja">OSGi-fikacja</a> to proces mający na celu stworzenie działającego bundle z istniejącej już biblioteki. Wiele z projektów nie dostarczają poprawnych z punktu widzenia frameworku OSGi manifestów, czasami są budowane poprzez Ant bądź w ogóle są dostępne tylko ich binarne wersje co utrudnia analizę. Proces ten w większości przypadków sprowadza się do analizy zależności klas (importów) oraz zadeklarowanych klas (eksportów). W skrajnych wypadkach konieczna jest dodanie kodu bądź podmiana jego fragmentów tak by nie powodowały problemów po uruchomieniu. W celu zachowania porządku w publicznych repozytoriach Mavena stworzone w ten sposób archiwa są zapisywane z innym ArtifactId bądź GroupId, natomiast z zachowaniem oryginalnej wersji.</p></blockquote>
<p>Nie aspiruję do miana człowieka który tworzy nowe pojęcia. Ten nieco przydługi wywód ma na celu jedynie przybliżenie działań które czasami są konieczne do uzyskania biblioteki działającej w OSGi.</p>
<p>Na potrzeby przykładu OSGi-fikacji wybrałem <a href="http://logging.apache.org/log4j/1.2/index.html">log4j</a>, jako popularną bibliotekę z małym zbiorem zależności. Wersja 1.2.12 nie zawiera poprawnego manifestu OSGi przez co nie można jej użyć pod Equinoxem czy Felixem.<br />
Zależności które ma log4j takie jak:</p>
<ul>
<li>javax.mail</li>
<li>javax.swing</li>
<li>javax.naming</li>
<li>javax.activation</li>
<li>javax.management</li>
<li>com.sun.jdmk.comm</li>
</ul>
<p>Są opcjonalne, co znaczy że biblioteka bez problemów uruchomi się jeśli nie uda się zaimportować wyżej wymienionych paczek. Określimy zatem ich <strong>resolution</strong> na <em>optional</em>. </p>
<p>Pozostałe zależności wymienione poniżej są wymagane by móc odczytać plik log4j.xml:</p>
<ul>
<li>org.w3c.dom</li>
<li>javax.xml.parsers</li>
<li>org.xml.sax</li>
</ul>
<p>Poniżej znajduje się pom.xml który przygotowałem po to by zaprezentować użycie wcześniej wspomnianych pluginów. Pom ten ma skutkować stworzeniem artefaktu OSGi gotowego do uruchomienia pod Kara-fem.</p>
<pre class="brush: xml;">&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;parent&gt;
      &lt;groupId&gt;org.apache.servicemix.bundles&lt;/groupId&gt;
      &lt;artifactId&gt;bundles-pom&lt;/artifactId&gt;
      &lt;version&gt;4&lt;/version&gt;
    &lt;/parent&gt;

    &lt;groupId&gt;org.apache.servicemix.bundles&lt;/groupId&gt;
    &lt;artifactId&gt;org.apache.servicemix.bundles.log4j&lt;/artifactId&gt;
    &lt;version&gt;1.2.12-SNAPSHOT&lt;/version&gt;
    &lt;packaging&gt;bundle&lt;/packaging&gt;
    &lt;name&gt;Apache ServiceMix Bundles: ${pkgArtifactId}-${pkgVersion}&lt;/name&gt;
    &lt;description&gt;
        This bundle simply wraps ${pkgArtifactId}-${pkgVersion}.jar.
    &lt;/description&gt;

    &lt;properties&gt;
        &lt;!-- Zmienne dla maven-bundle-plugin --&gt;
        &lt;servicemix.osgi.export.pkg&gt;
            org.apache.log4j*;version=${pkgVersion}
        &lt;/servicemix.osgi.export.pkg&gt;
        &lt;servicemix.osgi.import.pkg&gt;
            &lt;!-- Zależności opcjonalne --&gt;
            com.sun.jdmk.comm;resolution:=optional,
            javax.jms;resolution:=optional,
            javax.mail*;resolution:=optional,
            javax.management;resolution:=optional,
            javax.naming;resolution:=optional,
            javax.swing*;resolution:=optional,
            * &lt;!-- Wszystkie inne zależności jakie doda analizator --&gt;
        &lt;/servicemix.osgi.import.pkg&gt;
        &lt;!-- Zmienne artefaktu --&gt;
        &lt;pkgGroupId&gt;log4j&lt;/pkgGroupId&gt;
        &lt;pkgArtifactId&gt;log4j&lt;/pkgArtifactId&gt;
        &lt;pkgVersion&gt;1.2.12&lt;/pkgVersion&gt;
    &lt;/properties&gt;

    &lt;dependencies&gt;
        &lt;!-- zależność do log4j --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;${pkgGroupId}&lt;/groupId&gt;
            &lt;artifactId&gt;${pkgArtifactId}&lt;/artifactId&gt;
            &lt;version&gt;${pkgVersion}&lt;/version&gt;
            &lt;optional&gt;true&lt;/optional&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;

    &lt;build&gt;
        &lt;plugins&gt;
            &lt;!-- Kopiowanie plików .class --&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
                &lt;artifactId&gt;maven-shade-plugin&lt;/artifactId&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;phase&gt;package&lt;/phase&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;shade&lt;/goal&gt;
                        &lt;/goals&gt;
                        &lt;configuration&gt;
                            &lt;artifactSet&gt;
                                &lt;includes&gt;
                                    &lt;include&gt;${pkgGroupId}:${pkgArtifactId}&lt;/include&gt;
                                &lt;/includes&gt;
                            &lt;/artifactSet&gt;
                            &lt;filters&gt;
                                &lt;filter&gt;
                                    &lt;artifact&gt;${pkgGroupId}:${pkgArtifactId}&lt;/artifact&gt;
                                    &lt;excludes&gt;
                                        &lt;exclude&gt;**&lt;/exclude&gt;
                                    &lt;/excludes&gt;
                                &lt;/filter&gt;
                            &lt;/filters&gt;
                            &lt;promoteTransitiveDependencies&gt;true&lt;/promoteTransitiveDependencies&gt;
                            &lt;createDependencyReducedPom&gt;true&lt;/createDependencyReducedPom&gt;
                        &lt;/configuration&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/build&gt;
&lt;/project&gt;
</pre>
<p>Teraz pora na instalację bundla na szynie:</p>
<pre class="listing">
<span class="startup">
 ____                  _          __  __ _
/ ___|  ___ _ ____   _(_) ___ ___|  \/  (_)_  __
\___ \ / _ \ '__\ \ / / |/ __/ _ \ |\/| | \ \/ /
 ___) |  __/ |   \ V /| | (_|  __/ |  | | |&gt;  &lt;
|____/ \___|_|    \_/ |_|\___\___|_|  |_|_/_/\_\
</span><span class="bold">
  Apache ServiceMix</span> (4.2.0-fuse-01-00)

Hit '<span class="bold">&lt;tab&gt;</span>' for a list of available commands
and '<span class="bold">[cmd] --help</span>' for help on a specific command.
<span class="bold">karaf</span>@root&gt;

<span class="bold">karaf</span>@root&gt; <span class="command">install mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.log4j/1.2.12-SNAPSHOT</span>
Bundle ID: 186
<span class="bold">karaf</span>@root&gt; <span class="command">list|grep log4j</span>
[ 186] [Resolved   ] [            ] [       ] [   60] Apache ServiceMix Bundles: <span class="grep">log4j</span>-1.2.12 (1.2.12.SNAPSHOT)
<span class="bold">karaf</span>@root&gt; <span class="command">start 186</span>
<span class="bold">karaf</span>@root&gt; <span class="command">list|grep log4j</span>
[ 186] [Active     ] [            ] [       ] [   60] Apache ServiceMix Bundles: <span class="grep">log4j</span>-1.2.12 (1.2.12.SNAPSHOT)
<span class="bold">karaf</span>@root&gt; <span class="command">packages:imports 186</span>
OSGi System Bundle (0): javax.management; version="0.0.0"
OSGi System Bundle (0): javax.naming; version="0.0.0"
OSGi System Bundle (0): javax.swing; version="0.0.0"
OSGi System Bundle (0): javax.swing.border; version="0.0.0"
OSGi System Bundle (0): javax.swing.event; version="0.0.0"
OSGi System Bundle (0): javax.swing.table; version="0.0.0"
OSGi System Bundle (0): javax.swing.text; version="0.0.0"
OSGi System Bundle (0): javax.swing.tree; version="0.0.0"
OSGi System Bundle (0): javax.xml.parsers; version="0.0.0"
OSGi System Bundle (0): org.w3c.dom; version="0.0.0"
OSGi System Bundle (0): org.xml.sax; version="0.0.0"
OSGi System Bundle (0): org.xml.sax.helpers; version="0.0.0"
OPS4J Pax Logging - API (3): org.apache.log4j.spi; version="1.2.15"
OPS4J Pax Logging - API (3): org.apache.log4j.xml; version="1.2.15"
OPS4J Pax Logging - API (3): org.apache.log4j; version="1.2.15"
geronimo-jms_1.1_spec (64): javax.jms; version="1.1.0"
Apache ServiceMix Bundles: mail-1.4.1 (86): javax.mail.internet; version="1.4.1"
Apache ServiceMix Bundles: mail-1.4.1 (86): javax.mail; version="1.4.1"
<span class="bold">karaf</span>@root&gt; <span class="command">packages:exports 186</span>
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.util; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.net; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.viewer; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.jmx; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.jdbc; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.config; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.helpers; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.config; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.or.jms; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.nt; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.or.sax; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.viewer.categoryexplorer; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.or; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.chainsaw; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.varia; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.viewer.configure; version="1.2.12"
Apache ServiceMix Bundles: log4j-1.2.12 (186): org.apache.log4j.lf5.viewer.images; version="1.2.12"
<span class="bold">karaf</span>@root&gt;
</pre>
<p>Jak widać wszystko działa i ma się dobrze. :) Jedyna uwaga jaką mam to by nie używać tak spreparowanego log4j. W specyfikacji OSGi R4 V4.2 Enterprise jest opisana usługa logująca. Oprócz niej jest jeszcze <a href="http://wiki.ops4j.org/display/paxlogging/Pax+Logging">Pax Logging</a> (używany przez Karafa) wspierająca kilka różnych bibliotek od log4j poprzez slf4j po wspomnianą usługę OSGi.</p>
<p>Pozdrawiam i życzę miłej OSGi-fikacji! :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2010/03/osgi-new-bundles-servicemix-repository/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Specyfikacja Enterprise OSGi została opublikowana</title>
		<link>http://blog.code-house.org/2010/03/enterprise-osgi-released/</link>
		<comments>http://blog.code-house.org/2010/03/enterprise-osgi-released/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 18:26:24 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=247</guid>
		<description><![CDATA[Dnia dzisiejszego została wydana finalna wersja specyfikacji OSGi R4 V4.2 Enterprise. Wersja jest gotowa do pobrania pod adresem http://www.osgi.org/Download/Release4V42. Dokument ma 483 strony. :-)
]]></description>
			<content:encoded><![CDATA[<p>Dnia dzisiejszego została wydana finalna wersja specyfikacji OSGi R4 V4.2 Enterprise. Wersja jest gotowa do pobrania pod adresem <a href="http://www.osgi.org/Download/Release4V42">http://www.osgi.org/Download/Release4V42</a>. Dokument ma 483 strony. :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2010/03/enterprise-osgi-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enterprise OSGi</title>
		<link>http://blog.code-house.org/2010/03/enterprise-osgi/</link>
		<comments>http://blog.code-house.org/2010/03/enterprise-osgi/#comments</comments>
		<pubDate>Tue, 23 Mar 2010 11:26:18 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=233</guid>
		<description><![CDATA[Do opublikowania tego postu zachęcił mnie Jacek Laskowski swym postem pod tytułem W piątek 4Developers ze mną z Enterprise OSGi i in.
Bardzo się cieszę że na 4Developers (na którym niestety mnie nie będzie) temat Enterprise OSGi będzie poruszony, ponieważ jak się zdaje jest to nieuchronny kierunek rozwoju Javy. Pod wpływem słów Jacka zacząłem się zastanawiać [...]]]></description>
			<content:encoded><![CDATA[<p>Do opublikowania tego postu zachęcił mnie <a href="http://jlaskowski.blogspot.com/">Jacek Laskowski</a> swym postem pod tytułem <a href="http://jlaskowski.blogspot.com/2010/03/w-piatek-4developers-ze-mna-z.html">W piątek 4Developers ze mną z Enterprise OSGi i in</a>.</p>
<p>Bardzo się cieszę że na 4Developers (na którym niestety mnie nie będzie) temat Enterprise OSGi będzie poruszony, ponieważ jak się zdaje jest to nieuchronny kierunek rozwoju Javy. Pod wpływem słów Jacka zacząłem się zastanawiać nad długofalowymi efektami jakie OSGi ma wnieść do developmentu.</p>
<p>Hałas który obecnie jest wokół OSGi w przybiera konkretne kształty w postaci projektów takich jak <a href="http://incubator.apache.org/aries/">Aries</a> czy <a href="http://www.eclipse.org/gemini/">Gemini</a>. Obydwa projekty skupiają się nad ostatnimi draftami OSGi R4 V4.2 i mają na celu udostępnienie technologii takich jak JNDI, JPA i JMX wewnątrz kontenerów OSGi. Zacznijmy jednak od początku..</p>
<h2>OSGi a jarhell</h2>
<blockquote><p>JAR-hell occurs when software is deployed into a runtime environment which is unsuitable, but nothing other than full integration testing would detect this. Having multiple software packages dependent upon the same piece of software, with unpredictable incompatibilities, is pure hell. Ensuring the compatibility of a variety of dependent packages is duanting, doing it amongst the variety supported by a hierarchy of complex class loaders, is inhuman.</p>
<p align="right">Źródło <a href="http://incubator.apache.org/depot/version/jar-hell.html">Apache Depot</a></p>
</blockquote>
<p>Czyli w skrócie &#8211; piekło zaczyna się robić gdy pojawiają się niekompatybilności między bibliotekami w poprawnym środowisku. Co więcej owe niekompatybilności można wykryć dopiero po dogłębnych testach we wszystkich środowiskach w których ma działać aplikacja.</p>
<p>W przypadku OSGi wszystkie zależności są przewidywalne, co więcej nie uda się nam uruchomić paczki bez jej zależności &#8211; stąd teoretycznie nigdy nie powinniśmy widzieć ClassNotFoundException. Nie uda nam się również uruchomić naszego bundle jeśli powstanie konflikt w używanych zależnościach. Przykład z życia wzięty &#8211; mamy bundle zależące od camel-activemq oraz activemq-core. Pierwszy z nich pozwala na import spring-jms w wersji < 4.0, natomiast drugi w wersji < 2.6. Jeśli do tego mamy dwie wersje bundle spring-jms: 2.5.6 oraz 3.0.0 to mamy klapę. Naszej paczki nie da się wystartować ponieważ otrzymamy "Packages usage conflict". Zostaliśmy ochronieni przed JAR Hellem kosztem zablokowania kodu nawet jeśli zależność była opcjonalna.</p>
<h3>Rozwiązanie zagadki packages usage.</h3>
<p>Problem wydaje się trywialny &#8211; teoretycznie to są dwie różne wersje Springa, nie da się zaprzeczyć że 2.5.6 != 3.0.0. W praktyce jednak zmiany w spring-jms były tak niewielkie że można bez problemu uruchomić activemq-core z nową wersją. W takim wypadku jesteśmy zmuszeni do czekania na nową wersję ActiveMQ, która będzie pozwalała na korzystanie ze Springa 3.0 bądź samodzielnie zmodyfikować manifesty. Obydwa rozwiązania są równie złe &#8211; jedno to czekanie, drugie to tworzenie nowej dystrybucji ActiveMQ.</p>
<p>Co w takim wypadku możemy zrobić? Możemy użyć serwisów OSGi, które pozwalają na oddzielenie implementacji od interfejsu, dzięki czemu możemy połączyć dwie wersje bibliotek za fasadą w postaci <a href="http://www.osgi.org/javadoc/r4v42/org/osgi/framework/ServiceReference.html">ServiceReference</a>. Tutaj jednak może pojawić się inny problem &#8211; mianowicie część bibliotek które lubią dostęp do ClassLoaderów może skutecznie protestować &#8211; na przykład Hibernate czy Open JPA. Dla przykładu diagram obrazujący kolejny z życia wzięty przypadek:<br />
<img src="http://blog.code-house.org/wp-content/uploads/bundle2.png" alt="Diagram bundli" title="Diagram powiązań pomiędzy paczkami OSGi" width="1049" height="871" class="alignleft size-full wp-image-238" /><br />
W tym przypadku usiłowałem stworzyć działającą usługę która zapisywała by przychodzące komunikaty w bazie danych. Może parę słów o tym, który bundle co robi:</p>
<ul>
<li><strong>datasource</strong> otwiera połączenie do bazy danych, tworzy ConnectionFactory dla JMS a także EntityManagera.</li>
<li><strong>binding</strong> bramka do przyjmowania komunikatów &#8211; w tym przypadku był to web service.</li>
<li><strong>engine</strong> definicja routingu z użyciem Camela.</li>
<li><strong>persistence</strong> użycie EntityManagera do zapisywania komunikatów</li>
<li><strong>domain</strong> POJO, klasy domenowe</li>
</ul>
<p>Całość komunikacji odbywała się z JMS w trybie request-reply dzięki Apache Camel. Po bardzo długich &#8220;walkach&#8221; poniższą strukturę udało się uruchomić pod OSGi. Ostatecznie całość działa z Hibernate w układzie takim jak poniżej.<img src="http://blog.code-house.org/wp-content/uploads/bundle2-final.png" alt="Działająca struktura" title="Działająca struktura" width="1191" height="514" class="alignleft size-full wp-image-240" /><br />
Z diagramu wyrzuciłem paczki które nie są istotne takie jak driver JDBC czy Commons ConnectionPool. Jedyny mankament na jaki trafiłem wiąże się z <strong>DAO Service</strong>, mianowicie bundle który go eksportuje poprzez Spring-DM musi zadeklarować widoczność wszystkich swoich klas dla paczki która będzie korzystać z usługi co jak by nie patrzeć jest drobnym wypaczeniem fasady jaką ma być ServiceReference. Niestety po 2 tygodniach poświęconych na uruchomienie JPA w OSGi nie siliłem się na elegancję.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xmlns:osgi=&quot;http://www.springframework.org/schema/osgi&quot;
    xsi:schemaLocation=&quot;
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/osgi
        http://www.springframework.org/schema/osgi/spring-osgi.xsd
    &quot;&gt;

    &lt;osgi:reference id=&quot;dataSource&quot; interface=&quot;javax.sql.DataSource&quot; /&gt;

    &lt;osgi:service id=&quot;exchangeDAOExporter&quot; ref=&quot;exchangeDAO&quot;
        context-class-loader=&quot;service-provider&quot;
        interface=&quot;org.code_house.dataaccess.ExchangeDAO&quot; /&gt;
&lt;/beans&gt;
</pre>
<h2>Kolejne metadane</h2>
<p>Problem jaki powstaje z OSGi to metadane. Do tej pory &#8211; jeśli zarządzałem zależnościami do bibliotek robiłem to przez dependencyManagement Mavena, dzięki któremu rozwiązywałem wszystkie konflikty. OSGi jednak nie wiąże się z Mavenem ponieważ są to dwa różne obszary o zgoła innym funkcjonowaniu &#8211; OSGi to runtime, Maven to build time. Dopóki nie zapanuje harmonia pomiędzy tymi dwoma uruchamianie czegokolwiek w OSGi będzie katorgą. Należy do tego dodać jeszcze jeden element związany z OSGi &#8211; mianowicie <strong>O</strong>SGi <strong>B</strong>undle <strong>R</strong>epository (OBR), a OBR nijak się ma do repozytoriów Mavena przez co rozbieżności tylko się nasilają.<br />
Aby temu zapobiegać najpopularniejsze istniejące repozytoria <a href="http://www.springsource.com/repository/app/">SpringSource Enterprise Bundle Repository</a> oraz <a href="http://servicemix.apache.org/SMX4/bundles-repository.html">ServiceMix 4 Bundles repository</a> &#8211; publikują artefakty w repozytoriach Mavena. Problem w tym, że część artefaktów jest powielona. Tak jak kiedyś były 3 wersje Java Persistence API tak teraz dochodzą kolejne dwie &#8211; z manifestami OSGi. Czy ktoś wspominał o piekle?<br />
Należy również dodać że nie każdy JAR który ląduje w OSGi jest traktowany tak samo &#8211; oprócz standardowych bundli są również fragmenty, które są świetnym rozwiązaniem, jednakże początkowo potrafią przysporzyć wielu problemów. Cały trik sprowadza się do tego, że fragmenty mają wspólny class loader z paczką do której są przypięte.</p>
<h2>Korzyści z Enterprise OSGi</h2>
<p><img src="http://blog.code-house.org/wp-content/uploads/vendor-lock.png" alt="Vendor Lock" title="Vendor Lock" width="204" height="265" class="alignright size-full wp-image-242" /> Po całych tych wywodach na temat problemów z OSGi pora na to co ma ono nam dać &#8211; przenośność. Podobnie jak Java EE 6 z profilami tak OSGi ma zapewnić większą przenośność klocków pomiędzy środowiskami. Wyobrażacie sobie, że można przenieść aplikację z kontenera servletów na serwer aplikacyjny bez modyfikacji? Albo usługę z szyny integracyjnej na kontener servletów? Niedorzeczne, ale z OSGi możliwe do wykonania. Wystarczy zainstalować wszystkie wymagane bundle i całość będzie działać.</p>
<p>Oczywiście naiwna była by wiara w to, że tak będzie. Każda specyfikacja która powstaje dla Javy ma standaryzować i ujednolicać środowiska. W praktyce jednak każda z nich staje się punktem wyjściowym do rozwoju nowych produktów. Każdy dostawca oferuje zgodność ze specyfikacją plus coś. Nie twierdzę, że to złe, ponieważ polaryzacja rynku oprogramowania jest tak samo potrzebna jak wolny rynek, należy się jednak wystrzegać monopolistów a w przypadku oprogramowania również vendor locków.</p>
<p>Patrzę na OSGi z nadzieją ponieważ w moim mniemaniu jest to przedłużenie idei jaką niosła specyfikacja <strong>J</strong>ava <strong>B</strong>usiness <strong>I</strong>ntegration. <a href="http://jcp.org/en/jsr/results?id=4206">Propozycja JBI 2.0</a> spotkała się z krytyką ze strony IBM oraz BEA Systems zasłaniających się tym, że istnieje SCA. Problem w tym, że obydwie specyfikacje traktują o innych warstwach integracji &#8211; SCA gwarantuje przenośność usług, podczas gdy JBI miało zapewnić przenośność komponentów i komunikacji między nimi. SCA i JBI mogą a nawet powinny iść w parze. Teoria JBI mówiła o możliwości uruchomienia servicemix-cxf-bc (zgodnego z JBI) na Open ESB, w praktyce okazywało się to jednak bardzo trudne. Dzięki OSGi/Enterprise OSGi stanie się to łatwiejsze.</p>
<p>W ciągu kilku najbliższych lat trend OSGi dzięki zainteresowaniu wielkich korporacji będzie rósł w siłę. Trzymam kciuki by Enterprise OSGI przyniosło więcej korzyści niż tylko zbawienie od JAR Hella.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2010/03/enterprise-osgi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wprowadzenie do Apache ServiceMix 4 cz. 1</title>
		<link>http://blog.code-house.org/2010/03/introduction-to-apache-servicemix4-part-1/</link>
		<comments>http://blog.code-house.org/2010/03/introduction-to-apache-servicemix4-part-1/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 11:19:50 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Camel]]></category>
		<category><![CDATA[Consulting]]></category>
		<category><![CDATA[FUSE Source]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[ServiceMix]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=179</guid>
		<description><![CDATA[Dnia 23 lutego w ramach Warszawa JUG miałem przyjemność wraz z Tomkiem Nurkiewiczem prezentować narzędzia integracyjne z otwartym kodem źródłowym. Tomek przedstawił Mule ESB, podczas gdy ja zająłem się Apache ServiceMix i Apache Camel. Ze względu na objętość przykładu ten wpis będzie jedynie wprowadzeniem do konsoli.

Niestety podczas prezentacji nie udało mi się uruchomić przykładu na [...]]]></description>
			<content:encoded><![CDATA[<p>Dnia 23 lutego w ramach Warszawa JUG miałem przyjemność wraz z <a href="http://nurkiewicz.blogspot.com/">Tomkiem Nurkiewiczem</a> prezentować narzędzia integracyjne z otwartym kodem źródłowym. Tomek przedstawił Mule ESB, podczas gdy ja zająłem się Apache ServiceMix i Apache Camel. Ze względu na objętość przykładu ten wpis będzie jedynie wprowadzeniem do konsoli.<br />
<!-- more --><br />
Niestety podczas prezentacji nie udało mi się uruchomić przykładu na &#8220;szynie&#8221; &#8211; ponieważ uniemożliwiły to zależności do bibliotek których nie miałem zapisanych lokalnie. Drugim mym przeciwnikiem był czas &#8211; nie było wielu chętnych by słuchać po 2h tłumaczeń dlaczego się nie udało :-) Na problem z zależnościami stworzyłem rozwiązanie i zgłosiłem je do Karaf-a (<a href="https://issues.apache.org/jira/browse/FELIX-2141">FELIX 2141</a>). W przyszłej wersji &#8211; 1.6 &#8211; wszyscy będą mogli skorzystać z polecenia <tt>features:info -t</tt> które wyświetli całe drzewko zależności potrzebnych do zainstalowania nowych funkcjonalności.</p>
<h3>Przygotowanie środowiska</h3>
<p>Do uruchomienia przykładów potrzebować będziemy dwóch paczek &#8211; pierwsza to <a href="http://servicemix.apache.org">Apache ServiceMix</a>, druga to <a href="http://maven.apache.org">Apache Maven</a>. Ze swojej strony polecam pobranie <a href="http://fusesource.com/downloads/">FUSE ESB 4.2</a>, produktu który jest oparty o ServiceMix. Zgodnie z moimi zapowiedziami od tej wersji FUSE Source wprowadza pełne wsparcie produkcyjne dla ServiceMix 4. Jeśli nie masz zainstalowanego Mavena i nigdy tego nie robiłeś zajrzyj na wiki <a href="http://inside.code-house.org/confluence/">Code-House</a>: <a href="http://inside.code-house.org/confluence/display/MVN/Wprowadzenie+do+Maven+2">Wprowadzenie do Maven 2</a></p>
<p>Po pobraniu odpowiedniej wersji należy ją rozpakować do wybranego folderu. Szynę uruchamiamy skryptem servicemix.bat. Jeśli wszystko przebiegło poprawnie naszym oczom powinien ukazać się obrazek jak poniżej:</p>
<pre class="listing">
<span class="command">E:\tools\progress\fuse-esb\4.2.0-b\bin>servicemix.bat</span>
 ____                  _          __  __ _
/ ___|  ___ _ ____   _(_) ___ ___|  \/  (_)_  __
\___ \ / _ \ '__\ \ / / |/ __/ _ \ |\/| | \ \/ /
 ___) |  __/ |   \ V /| | (_|  __/ |  | | |>  <
|____/ \___|_|    \_/ |_|\___\___|_|  |_|_/_/\_\

  Apache ServiceMix (4.2.0-fuse-01-00)

Hit '<tab>' for a list of available commands
and '[cmd] --help' for help on a specific command.
karaf@root&gt;
</pre>
<p>Od tej chwili mamy do dyspozycji konsolę administracyjną. Aby zwiększyć jej użyteczność wykonujemy następujące polecenia:</p>
<pre class="listing">
karaf@root&gt; <span class="command">osgi:install wrap:mvn:http://download.java.net/maven/2!net.java.dev.jna/jna/3.1.0</span>
Bundle ID: 134
</pre>
<p>Spowoduje to pobranie z repozytorium Mavena (http://download.java.net/maven/2) biblioteki JNA w wersji 3.1.0. Nie musimy oczywiście określać za każdym razem adresu repozytoriów, ale o tym nieco później. Prefix wrap: spowoduje wygenerowanie manifestu OSGi na podstawie zawartości pobranej biblioteki. Jest on konieczny ponieważ JNA nie dostarcza potrzebnych danych do uruchomienia w środowisku OSGi.</p>
<pre class="listing">
karaf@root&gt; <span class="command">osgi:install mvn:http://jansi.fusesource.org/repo/release!org.fusesource.jansi/jansi/1.2</span>
Bundle ID: 135
</pre>
<p>Druga biblioteka wykorzystuje JNA i umożliwia kolorowanie tekstu w konsoli windowsowej zgodnie z ANSI, czyli tak jak w standardowych terminalach Unix-a. Po zainstalowaniu tych dwóch rzeczy pora zaprząc je do pracy. Poniżej filtrujemy listę zainstalowanych rzeczy po słowie Console.</p>
<pre class="listing">
karaf@root&gt; <span class="command">list|grep Console</span>
[  10] [Active     ] [Created     ] [       ] [   30] Apache Felix Karaf :: Shell Console (1.4.0.fuse-01-00)
karaf@root&gt; <span class="command">refresh 10</span>
</pre>
<p>Numer 10 oznacza id paczki OSGi, tekst Active to stan paczki a tekst Created informuje o stanie kontekstu blueprint, czwarty bloczek to stan kontekstu Springa, numer 30 to start level paczki a w ostatnim nawiasie mamy wersję. Sporo informacji jak na jedną linijkę, nieprawdaż? Blueprint to standaryzowanie tego czym jest Spring i Spring DM, także można korzystać zamiennie bądź z jednego bądź z drugiego rozwiązania. Ciekawe porównanie funkcjonalności obu rozwiązań &#8211; Spring DM oraz Blueprint opublikował kilka dni temu Guillaume Nodet na swoim blogu we wpisie <a href="http://gnodet.blogspot.com/2010/03/spring-dm-aries-blueprint-and-custom.html">Spring-DM, Aries Blueprint and custom namespaces</a>. Apache Camel od wersji 2.3 będzie wspierał Blueprint (<a href="https://issues.apache.org/activemq/browse/CAMEL-2022">CAMEL-2022</a>).</p>
<pre class="listing">
<span class="startup">
 ____                  _          __  __ _
/ ___|  ___ _ ____   _(_) ___ ___|  \/  (_)_  __
\___ \ / _ \ '__\ \ / / |/ __/ _ \ |\/| | \ \/ /
 ___) |  __/ |   \ V /| | (_|  __/ |  | | |>  <
|____/ \___|_|    \_/ |_|\___\___|_|  |_|_/_/\_\
</span><span class="bold">
  Apache ServiceMix</span> (4.2.0-fuse-01-00)

Hit '<span class="bold">&lt;tab&gt;</span>' for a list of available commands
and '<span class="bold">[cmd] --help</span>' for help on a specific command.
<span class="bold">karaf</span>@root&gt;
</pre>
<p>Teraz wykonanie poleceń z filtrem <strong>grep</strong> spowoduje podświetlenie szukanej frazy:</p>
<pre class="listing">
<span class="bold">karaf</span>@root&gt; <span class="command">list |grep Console</span>
[  10] [Active     ] [Created     ] [       ] [   30] Apache Felix Karaf :: Shell <span class="grep">Console</span> (1.4.0.fuse-01-00)
</pre>
<p>Takie małe udogodnienie przy przeglądaniu dłuższych rezultatów jest nieocenione.</p>
<h3>Podstawowe polecenia konsoli</h3>
<p>Polecenia w Apache Karaf są podzielone na kilka grup, które ułatwiają zarządzanie. Pierwszą grupą jest OSGi.</p>
<h4>Polecenia OSGi</h4>
<table class="listing">
<tr>
<th>Polecenie</th>
<th>Przeznaczenie</th>
</tr>
<tr>
<td>list</td>
<td>Wyświetlenie listy zainstalowanych paczek</td>
</tr>
<tr>
<td>ls [bundle id]</td>
<td>Wyświetlenie usług eksportowanych przez paczkę.</td>
</tr>
</tr>
<tr>
<td>ls -u [bundle id]</td>
<td>Wyświetlenie usług używanych przez paczkę.</td>
</tr>
<tr>
<td>headers [bundle id]</td>
<td>Wyświetlenie manifestu paczki.</td>
</tr>
<tr>
<td>start [bundle id]</td>
<td>Uruchomienie paczki o danym ID.</td>
</tr>
<tr>
<td>stop [bundle id]</td>
<td>Zatrzymanie paczki o danym ID.</td>
</tr>
<tr>
<td>restart [bundle id]</td>
<td>Zatrzymanie i wystartowanie paczki o danym ID.</td>
</tr>
<tr>
<td>update [bundle id]</td>
<td>Aktualizacja paczki.</td>
</tr>
<tr>
<td>refresh [bundle id]</td>
<td>Odświeżenie importów paczki a także przeładowanie kontekstu Spring-DM.</td>
</tr>
<tr>
<td>install [url]</td>
<td>Zainstalowanie nowej paczki.</td>
</tr>
<tr>
<td>uninstall [bundle id]</td>
<td>Odinstalowanie paczki.</td>
</tr>
<tr>
<td>shutdown</td>
<td>Zatrzymanie kontenera.</td>
</tr>
<tr>
<td>bundle-level [bundle id] [startLevel]</td>
<td rowspan="2">Ustawienie start levelu dla paczki.</td>
</tr>
<tr>
<td>start-level</td>
</tr>
</table>
<p>Kiedy znamy już listę poleceń nie pozostaje nic innego jak je wypróbować. :-) Checkout <a href="http://svn.code-house.org/wjug/">przykładowego kodu</a> z SVN pozwoli wykonać nam kilka ćwiczeń. Po wykonaniu polecenia <strong>mvn clean install</strong> w repozytorium Mavena są JARy które, naturalnie, chcemy zainstalować. Rezultat jaki powinniśmy zobaczyć w konsoli to:</p>
<pre class="listing">
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] Money transfer ServiceMix example ..................... SUCCESS [2.028s]
[INFO] Money transfer :: API ................................. SUCCESS [3.182s]
[INFO] Money transfer :: POI bundle .......................... SUCCESS [7.504s]
[INFO] Money transfer :: Internal ............................ SUCCESS [0.093s]
[INFO] Money transfer :: Internal :: CSV ..................... SUCCESS [4.399s]
[INFO] Money transfer :: Internal :: XLS ..................... SUCCESS [2.823s]
[INFO] Money transfer :: Internal :: Mail .................... SUCCESS [2.309s]
[INFO] Money transfer :: Internal :: Splitter ................ SUCCESS [0.936s]
[INFO] Money transfer :: Internal :: Routes .................. SUCCESS [1:21.241s]
[INFO] Money transfer :: External ............................ SUCCESS [0.016s]
[INFO] Money transfer :: External :: Customer ................ SUCCESS [3.182s]
[INFO] Money transfer :: External :: Bank .................... SUCCESS [2.059s]
[INFO] Money transfer :: External :: Validator ............... SUCCESS [2.918s]
[INFO] Money transfer :: Features ............................ SUCCESS [0.171s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 54 seconds
[INFO] Finished at: Mon Mar 22 10:47:27 CET 2010
[INFO] Final Memory: 127M/341M
[INFO] ------------------------------------------------------------------------
</pre>
<p>Może teraz kilka słów o modułach które są widoczne w Mavenie.</p>
<table class="listing">
<tr>
<th width="28%">Moduł</th>
<th width="32%">Ścieżka<br />Maven ID</th>
<th>Przeznaczenie</th>
</tr>
<tr>
<td>Money transfer :: API</td>
<td>api<br />org.code-house.samples/api</td>
<td>API systemów zewnętrznych oraz POJO wykorzystywane do komunikacji.</td>
</tr>
<tr>
<td>Money transfer :: POI bundle</td>
<td>poi<br />org.code-house.samples/poi</td>
<td>Bundle zawierający bibliotekę Apache POI oraz wszystkie jej zależności z Manifestem OSGi pozwalającym na jej uruchomienie na szynie.</td>
</tr>
<tr>
<td>Money transfer :: Internal :: CSV</td>
<td>internal/csv<br />org.code-house.samples.internal/csv</td>
<td>Paczka zawierająca implementację procesora przetwarzającego pliki CSV na POJO MoneyTransfer.</td>
</tr>
<tr>
<td>Money transfer :: Internal :: XLS</td>
<td>internal/xls<br />org.code-house.samples.internal/xls</td>
<td>Paczka zawierająca implementację procesora przetwarzającego pliki XLS na POJO MoneyTransfer.</td>
</tr>
<tr>
<td>Money transfer :: Internal :: Mail</td>
<td>internal/mail<br />org.code-house.samples.internal/mail</td>
<td>Paczka z kodem dzielącym przychodzący mail z załącznikami na pojedyncze wiadomości które można przetworzyć jako XLS bądź CSV.</td>
</tr>
<tr>
<td>Money transfer :: Internal :: Splitter</td>
<td>internal/splitter<br />org.code-house.samples.internal/splitter</td>
<td>Paczka z kodem odpowiedzialnym za rozdzielanie listy obiektów MoneyTransfer na listę wiadomości.</td>
</tr>
<tr>
<td><strong>Money transfer :: Internal :: Routes</strong></td>
<td>internal/routes<br />org.code-house.samples.internal/routes</td>
<td><strong>Główna paczka z definicjami routingu</strong></td>
</tr>
<tr>
<td>Money transfer :: External :: Customer</td>
<td>external/customer<br />org.code-house.samples.external/customer</td>
<td>Implementacja WebService odpowiedzialnego za pobieranie danych klienta na podstawie numeru rachunku bankowego.</td>
</tr>
<tr>
<td>Money transfer :: External :: Bank</td>
<td>external/bank<br />org.code-house.samples.external/bank</td>
<td>Implementacja usługi zwracającej informację o nazwie banku na podstawie numeru rachunku.</td>
</tr>
<tr>
<td>Money transfer :: External :: Validator</td>
<td>external/validator<br />org.code-house.samples.external/validator</td>
<td>Usługa weryfikująca czy MoneyTransfer jest poprawny.</td>
</tr>
<tr>
<td>Money transfer :: Features</td>
<td>features<br />org.code-house.samples/features</td>
<td>Moduł zawierający opcjonalny deskryptor do uruchomienia modułów.</td>
</tr>
</table>
<p>Jak widać dwa główne obszary projektu są skupione w katalogach internal oraz external. Ten pierwszy zawiera implementacje ściśle związaną z usługami natomiast drugi to &#8220;zatyczki&#8221; emulujące działanie systemów zewnętrznych. Drobna nota &#8211; kolumna Maven ID nie zawiera informacji o wersji &#8211; w każdym module jest to <strong>1.0.0.SNAPSHOT</strong>.</p>
<p>Aby zainstalować któryś bundle przechodzimy do konsoli ServiceMix&#8217;a i wykonujemy takie polecenia:</p>
<pre class="listing">
<span class="bold">karaf</span>@root&gt; <span class="command">install -s mvn:org.code-house.samples/api/1.0.0.SNAPSHOT</span>
Bundle ID: 210
<span class="bold">karaf</span>@root&gt; <span class="command">features:install camel-jetty</span>
<span class="bold">karaf</span>@root&gt; <span class="command">install -s mvn:org.code-house.samples.external/customer/1.0.0.SNAPSHOT</span>
Bundle ID: 211
</pre>
<p>Po wykonaniu tych poleceń powinien być uruchomiony Web Service którego WSDL znajduje się pod adresem http://localhost:9001/CustomerWs?wsdl. Przełącznik <strong>-s</strong> w przypadku polecenia install powoduje że po zainstalowaniu bundle zostanie wystartowany. Polecenie <strong>features-install camel-jetty</strong> jest potrzebne nie ze względu na to że kolejna paczka korzysta z Camela, dzięki jego wykonaniu zostanie zainstalowane Jetty, z którego korzysta CXF.</p>
<p>Kolejne paczki instalujemy analogicznie:</p>
<pre class="listing">
<span class="bold">karaf</span>@root&gt; <span class="command">features:install camel-activemq</span>
<span class="bold">karaf</span>@root&gt; <span class="command">install -s mvn:org.code-house.samples.external/validator/1.0.0.SNAPSHOT</span>
Bundle ID: 215
<span class="bold">karaf</span>@root&gt; <span class="command">install -s mvn:org.code-house.samples.external/bank/1.0.0.SNAPSHOT</span>
Bundle ID: 217
</pre>
<p>Rozszerzenie <a href="http://camel.apache.org/activemq.html">camel-activemq</a> jest rozszerzeniem modułu <a href="http://camel.apache.org/jms.html">camel-jms</a> które pozwala na nieco wydajniejszą pracę z <a href="http://activemq.apache.org">ActiveMQ</a>.</p>
<h4>Integracja ServiceMix z repozytoriami Mavena</h4>
<p>Maven jako narzędzie do budowania korzysta z określonego schematu składowania bibliotek które następnie są automatycznie pobierane. Karaf, który jak wspomniałem podczas prezentacji, wyłonił się z projektu ServiceMix Kernel korzysta z biblioteki <a href="http://wiki.ops4j.org/display/paxurl/Documentation">Pax URL</a>. Dzięki temu z marszu mamy dostęp do standardowych repozytoriów Mavena, co jednak gdy mamy swoje repozytorium, które zawiera tylko nasze artefakty?<br />
Otwieramy plik etc/org.ops4j.pax.url.mvn.cfg i dodajemy w nim co trzeba. Moja standardowa konfiguracja wygląda następująco:</p>
<pre class="brush: plain;">
org.ops4j.pax.url.mvn.settings=E:/tools/maven-2.2.1/conf/settings.xml
org.ops4j.pax.url.mvn.localRepository=E:/repository
org.ops4j.pax.url.mvn.defaultRepositories=file:${karaf.home}/${karaf.default.repository}@snapshots
org.ops4j.pax.url.mvn.repositories= \
    http://repo1.maven.org/maven2, \
    http://repo.fusesource.com/maven2, \
    http://repo.fusesource.com/maven2-snapshot@snapshots@noreleases, \
    http://repository.apache.org/content/groups/snapshots-group@snapshots@noreleases, \
    http://repository.ops4j.org/maven2, \
    http://svn.apache.org/repos/asf/servicemix/m2-repo, \
    http://repository.springsource.com/maven/bundles/release, \
    http://repository.springsource.com/maven/bundles/external, \
    http://repository.code-house.org/content/groups/release, \
    http://repository.code-house.org/content/groups/snapshot@snapshots@noreleases, \
    http://jansi.fusesource.org/repo/release
</pre>
<p>Dzięki temu PAX w pierwszej kolejności będzie skanował katalog E:/repository zamiast standardowego ~/.m2/repository. Jeśli któreś z repozytoriów wymaga autoryzacji adres powinien wyglądać następująco:</p>
<pre class="brush: plain;">http://user:pass@jansi.fusesource.org/repo/release</pre>
<h3>Podsumowanie</h3>
<p>Mam nadzieję że wpis ten przybliży chociaż w niewielkim stopniu ServiceMix 4 oraz Karafa. W przyszłym wpisie, którego daty publikacji nie sposób przewidzieć zostaną dokładniej omówione polecenia z grupy <strong>features</strong>. Póki co życzę miłej zabawy z konsolą. :-) W razie pytań, niejasności i problemów &#8211; proszę o komentarze.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2010/03/introduction-to-apache-servicemix4-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wygodne środowisko dla programisty z JRebel</title>
		<link>http://blog.code-house.org/2010/01/wygodne-srodowisko-dla-programisty-z-jrebel/</link>
		<comments>http://blog.code-house.org/2010/01/wygodne-srodowisko-dla-programisty-z-jrebel/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 16:48:56 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=170</guid>
		<description><![CDATA[Od dłuższego czasu pracuję z następującymi narzędziami: Maven, Eclipse, Jetty. Nigdy nie starałem się na to by moje projekty dobrze współgrały z Eclipse ponieważ wszystko i tak uruchamiam przez Mavena. Korzyścią jest przenośność tego rozwiązania, wadą brak klikalnej wygody, tj zakładki serwerów w Eclipse i aplikacji które są na nich uruchomione.

Tuż przed nowym rokiem udało [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.code-house.org/wp-content/uploads/jrebel_bigger.png" alt="jrebel_bigger" title="jrebel_bigger" width="73" height="73" class="alignleft size-full wp-image-176" />Od dłuższego czasu pracuję z następującymi narzędziami: Maven, Eclipse, Jetty. Nigdy nie starałem się na to by moje projekty dobrze współgrały z Eclipse ponieważ wszystko i tak uruchamiam przez Mavena. Korzyścią jest przenośność tego rozwiązania, wadą brak klikalnej wygody, tj zakładki serwerów w Eclipse i aplikacji które są na nich uruchomione.<br />
<span id="more-170"></span><br />
Tuż przed nowym rokiem udało mi się skonfigurować <a href="http://maven.apache.org">Mavena</a> i <a href="http://eclipse.org">Eclipse</a> oraz <a href="http://www.zeroturnaround.com/jrebel/">JRebel</a>. Teraz po zmianie klasy czy konfiguracji Springa z poziomu Eclipse zmiany widać w Jetty uruchomionym z poziomu Mavena. Nie byłby to sukces sam w sobie gdyby nie fakt, że udało się to zrobić w z wieloma modułami. Oto przykład struktury projektu:</p>
<ul>
<li><strong>domain</strong> &#8211; model danych oraz encje</li>
<li><strong>security</strong> &#8211; kod związany z zabezpieczeniami oraz ich konfiguracją</li>
<li><strong>dataaccess</strong>
<ul>
<li><strong>api</strong> &#8211; interfejsy DAO oraz Fasad</li>
<li><strong>jpa</strong> -dostęp do danych przy użyciu JPA</li>
<li><strong>jdbc</strong> &#8211; dostęp dod anych z użyciem gołego JDBC</li>
</ul>
</li>
<li><strong>web</strong> &#8211; końcówka webowa &#8211; kontrolery itp.</li>
<li><strong>distribution</strong> &#8211; tworzenie dystrybucji do środowiska testowego i produkcyjnego</li>
</ul>
<p>Ogólnie strukturę tą można coraz bardziej rozdrabniać bądź zbijać tak by odpowiadała ona naszym potrzebom, w tym przypadku pominiemy dywagacje ponieważ nie o tym ten wpis ma być. Problemem przy tego typu strukturze jest to że zmiany w modułach <em>dao</em> są dostępne w module <em>web</em> dopiero po przebudowaniu obydwu, co czasami bywa uciążliwe. Rozwiązaniem byłoby użycie OSGi i serwera który to wspiera, po zmianie robili byśmy deploy bundle który się zmienił &#8211; było by to z pewnością wygodniejsze niż dwukrotny mvn install, jest jednak rozwiązanie jeszcze wygodniejsze &#8211; <a href="http://www.zeroturnaround.com/jrebel/">JRebel</a>.</p>
<h2>Konfiguracja Mavena</h2>
<p>Jak już wspomniałem całość zmian nie wymaga nic od Eclipse ze względu na to, że całość deskryptorów jest generowana z poziomu Mavena przy pomocy <a href="http://maven.apache.org/plugins/maven-eclipse-plugin/">maven-eclipse-plugin</a>.</p>
<pre class="brush: xml;">
&lt;plugin&gt;
    &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
    &lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
    &lt;configuration&gt;
        &lt;buildOutputDirectory&gt;target/classes&lt;/buildOutputDirectory&gt;
        &lt;projectNameTemplate&gt;[groupId]_[artifactId]&lt;/projectNameTemplate&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;
</pre>
<p>Drugi krok to stworzenie bądź modyfikacja zmiennej środowiskowej MAVEN_OPTS:</p>
<pre class="brush: bash;">
-noverify -javaagent:E:\tools\jrabel-2.2.1\jrebel.jar -Xdebug -Drebel.log.stdout=true -Drebel.log=true -Xrunjdwp:transport=dt_socket,server=y,address=4000,suspend=n -Xmx768m
</pre>
<p>Trzeci krok to konfiguracja JRebel. Oczywiście można skorzystać z javarebel-maven-plugin, ale mi nie udało się go poprawnie skonfigurować, dlatego też plik został stworzony ręcznie:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;application xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns=&quot;http://www.zeroturnaround.com&quot; xsi:schemaLocation=&quot;http://www.zeroturnaround.com/alderaan/rebel-2_0.xsd&quot;&gt;

    &lt;classpath&gt;
        &lt;dir name=&quot;${basedir}/target/classes&quot; /&gt;
        &lt;dir name=&quot;${basedir}/../domain/target/classes&quot; /&gt;
        &lt;dir name=&quot;${basedir}/../security/domain/target/classes&quot; /&gt;
        &lt;dir name=&quot;${basedir}/../dataaccess/api/target/classes&quot; /&gt;
        &lt;dir name=&quot;${basedir}/../dataaccess/jpa/target/classes&quot; /&gt;
        &lt;dir name=&quot;${basedir}/../dataaccess/jdbc/target/classes&quot; /&gt;
    &lt;/classpath&gt;

    &lt;war dir=&quot;${basedir}/webapp&quot; /&gt; &lt;!-- lokalizacja plików JSP itp --&gt;

    &lt;web&gt;
        &lt;link target=&quot;/myapp&quot;&gt; &lt;!-- nazwa kontekstu --&gt;
            &lt;dir name=&quot;${basedir}/webapp&quot;&gt;
            &lt;/dir&gt;
        &lt;/link&gt;
    &lt;/web&gt;

&lt;/application&gt;
</pre>
<p>Dodatkowo należy wyłączyć przeładowania Jetty tak by nie kolidowały one z agentem JRebel. Całość w dalszym ciągu działa z poziomu Mavena i jest przenośne. Po tych wszystkich zmianach możemy się cieszyć trialem przez 30 dni bądź kupić licencję za jedyne 149$. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2010/01/wygodne-srodowisko-dla-programisty-z-jrebel/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Spring 3.0 RC3 + Maven</title>
		<link>http://blog.code-house.org/2009/12/spring-3-0-rc3-maven/</link>
		<comments>http://blog.code-house.org/2009/12/spring-3-0-rc3-maven/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 18:25:34 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Spring Source]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=162</guid>
		<description><![CDATA[Właśnie wyłapałem na Twitterze, że Spring 3.0 RC3 został wydany.
Dla tych, którzy chcieli by pobrać nową wersję do swojego projektu opartego o Mavena drobna informacja &#8211; repozytorium z tymi artefaktami znajduje się pod adresem http://maven.springframework.org/milestone. Miejmy nadzieję, że będzie to repozytorium które się nie zmieni po 3 miesiącach na inne.
W razie problemów &#8211; można zawsze [...]]]></description>
			<content:encoded><![CDATA[<p>Właśnie wyłapałem na Twitterze, że <a href="http://www.springsource.com/download?project=Spring%20Framework">Spring 3.0 RC3</a> został wydany.</p>
<p>Dla tych, którzy chcieli by pobrać nową wersję do swojego projektu opartego o Mavena drobna informacja &#8211; repozytorium z tymi artefaktami znajduje się pod adresem <a href="http://maven.springframework.org/milestone">http://maven.springframework.org/milestone</a>. Miejmy nadzieję, że będzie to repozytorium które się nie zmieni po 3 miesiącach na inne.</p>
<p>W razie problemów &#8211; można zawsze skorzystać z repozytorium utrzymywanego na <a href="http://repository.code-house.org/content/repositories/com.springsource.repository.bundles.milestone/">serwerze Code-House</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2009/12/spring-3-0-rc3-maven/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GWT oraz implementacje MVC</title>
		<link>http://blog.code-house.org/2009/11/gwt-and-mvc-implementations/</link>
		<comments>http://blog.code-house.org/2009/11/gwt-and-mvc-implementations/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 20:15:54 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[gwt]]></category>
		<category><![CDATA[gxt]]></category>
		<category><![CDATA[pure mvc]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=154</guid>
		<description><![CDATA[GWT, czyli Google Web Toolkit to nic innego jak zbiór komponentów, które można użyć podczas tworzenia aplikacji. GWT jest łatwe, kod tworzy się szybko i łatwo uruchamia chociażby z poziomu Mavena, jednakże największym problemem nie jest to jak stworzyć okienko, ale jak zorganizować projekt. W tym poście postaram się przedstawić kilka gotowych bibliotek, z którymi [...]]]></description>
			<content:encoded><![CDATA[<p>GWT, czyli Google Web Toolkit to nic innego jak zbiór komponentów, które można użyć podczas tworzenia aplikacji. GWT jest łatwe, kod tworzy się szybko i łatwo uruchamia chociażby z poziomu Mavena, jednakże największym problemem nie jest to jak stworzyć okienko, ale jak zorganizować projekt. W tym poście postaram się przedstawić kilka gotowych bibliotek, z którymi się zetknąłem podczas swych bojów z budowaniem sporej aplikacji.</p>
<p><!-- more --><br />
Ilość implementacji MVC dla GWT jest dosyć duża a temat był poruszany na zagranicznych blogach już nie jeden raz, wystarczy zajrzeć na poniższe strony:</p>
<ul>
<li><a href="http://raibledesigns.com/rd/entry/gxt_s_mvc_framework">W marcu 2009</a> Matt Raible opisał swoje problemy z komponentami GXT oraz problematycznym MVC stworzonym przez autorów tejże biblioteki </li>
<li><a href="http://supplychaintechnology.wordpress.com/2009/04/07/gwt_mvc_survey/">W kwietniu 2009</a> pojawiło się pierwsze zestawienie implementacji MVC na blogu Supply Chain Technology</li>
<li><a href="http://supplychaintechnology.wordpress.com/2009/05/07/more-mvc-for-gwt/">W maju 2009</a> na tym samym blogu pojawiła się aktualizacja z nowymi pozycjami.</li>
<li><a href="http://googlecode.blogspot.com/2009/06/google-web-toolkit-at-google-io.html">Również w maju 2009</a> odbyła się konferencja Google IO na której temat developmentu GWT był szeroko i dokładnie omówiony.</li>
</ul>
<p>Zacząłem nieśmiało, bo od stworzenia &#8220;szyny&#8221; którą mogły by się komunikować różne komponenty. Miała ona na celu zmniejszenie ilości bezpośrednich powiązań między elementami aplikacji. Pomogło, ale to nie było jeszcze to, co uporządkowało aplikację. </p>
<p>Drugie podejście mimo obaw wyniesionych <a href="http://raibledesigns.com/rd/entry/gxt_s_mvc_framework">z pierwszego linku</a> padło na lightweight MVC z biblioteki GXT. Udało mi się stworzyć działającą aplikację, jednakże brak jasnego podziału co, kto i jak ma robić strasznie mi doskwierał. Problematyczna okazała się również próba stworzenia hierarchii kontrolerów, a zrobienie aplikacji od zera sprowadzało się tak na prawdę do skopiowania i przerobienia przykładu z <a href="http://christianposta.com/blog/?p=6">Mail App</a>. Podobnie jak Matt nigdy też nie wyłapałem różnicy między metodami Dispatcher.dispatch() oraz Dispatcher.forwardEvent().</p>
<p>Trzecie podejście do MVC zakrawało już szaleństwem. Po przejrzeniu dokumentacji GWTruts stwierdziłem, że zapowiada się ciekawie. Odseparowany widok i kontroler, API przypominające nieco Spring MVC, nieco XML do okraszenia całości wstrzykiwaniem zależności. Wszystko to jednak na nic, gdyż całość opiera się na mapowaniu adresów z przeglądarki do kontrolerów. Krzywe koniec końców okazało się też przekazywanie map z argumentami i w dalszym ciągu brak jakichkolwiek idei na zorganizowanie wszystkiego. A zapomniałbym &#8211; jeśli chcecie walidacji to musicie pogodzić się z tym że 1 kontroler to 1 klasa do sprawdzania danych. Szkoda że tego nie można &#8220;wstrzyknąć&#8221;.</p>
<p>Dobra, skoro nie GWTruts, nie GXT, i nie Event Bus to co? Krótki przegląd <a href="http://code.google.com/p/gwt-mvc/">GWT-MVC</a> skończył się odrzuceniem szkieletu. Skąd niby kontroler ma zajmować się tym gdzie ma wylądować widok? A tak właśnie się dzieje w tym szkielecie ponieważ kontroler wywołuje DOMPlacera by gdzieś umieścić widok. Jak by tych fanaberii było mało doszedł jeszcze interfejs <a href="http://code.google.com/p/gwt-mvc/source/browse/trunk/gwt-mvc/src/main/java/com/googlecode/gwtmvc/client/Maskable.java">Maskable</a> który ma przykrywać elementy w trakcie renderowania. Dodajmy do tego przykłady które się sprowadzały do przycisków +2, -2 i inputa. Pytanie &#8211; co to ma do klasycznego MVC? </p>
<p>Tym oto sposobem dotarłem do ostatniego projektu, który mi zaimponował rozmiarem dokumentacji, spójną koncepcją i masą ograniczeń &#8211; <a href="http://puremvc.org/">Pure MVC</a>. Projekt, który pierwotnie miał sporo do czynienia z Flashem, a który dzięki swojemu porządkowi został przepisany również na inne języki &#8211; min. PHP, Javę. Wśród portów nie zabrakło również wersji dla GWT. Nie muszę pisać jak bardzo mnie to ucieszyło, prawda? :-)<br />
Całkiem duży przykład obrazuje powiązania pomiędzy komponentami oraz to jak powinny się komunikować:<br />
<a href="http://trac.puremvc.org/Demo_Java_MultiCore_GWT_EmployeeAdmin"><img src="http://blog.code-house.org/wp-content/uploads/ea_screenshot.png" alt="Employee Admin Demo" title="Employee Admin Demo" width="806" height="486" class="aligncenter size-full wp-image-156" /></a></p>
<p>Uzbrojony w ten zakres informacji stworzyłem pierwszą przykładową aplikację z ekranem logowania oraz jedną tabelką. Stopniowo go rozbudowując dotarłem do momentu w którym moja aplikacja w końcu przestała się kręcić wokół tego &#8220;które MVC&#8221; wybrać i zaczęła nabierać funkcjonalności biznesowej. Po długich bojach i masie straconego czasu, odradzam wszystkie inne implementacje <em>Model View Controller</em> dla GWT. Pure MVC jest po prostu najlepsze. :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2009/11/gwt-and-mvc-implementations/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Instalowanie oprogramowania Atlassian cz. 1</title>
		<link>http://blog.code-house.org/2009/10/instalowanie-oprogramowania-atlassian-cz-1/</link>
		<comments>http://blog.code-house.org/2009/10/instalowanie-oprogramowania-atlassian-cz-1/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 10:01:44 +0000</pubDate>
		<dc:creator>Łukasz Dywicki</dc:creator>
				<category><![CDATA[Code-House]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.code-house.org/?p=137</guid>
		<description><![CDATA[Kilka dni temu trafiłem na informacje o tym, że firma Atlassian uruchomiła &#8220;promocję&#8221; w której wyprzedaje licencje startowe na swoje produkty za 10$. Tym oto sposobem za równowartość dobrego obuwia (niecałe 175 zł) wszedłem w posiadanie sześciu licencji na Crowd, Jira, GreenHopper, Confluence, Fisheye i Bamboo. W poście tym krótki opis instalacji na Tomcat 6.x [...]]]></description>
			<content:encoded><![CDATA[<p>Kilka dni temu trafiłem na informacje o tym, że firma Atlassian uruchomiła &#8220;promocję&#8221; w której wyprzedaje licencje startowe na swoje produkty za 10$. Tym oto sposobem za równowartość dobrego obuwia (niecałe 175 zł) wszedłem w posiadanie sześciu licencji na Crowd, Jira, GreenHopper, Confluence, Fisheye i Bamboo. W poście tym krótki opis instalacji na Tomcat 6.x pierwszych czterech.<!-- more --></p>
<h2>Przygotowania</h2>
<p>Uprzedzam, że instrukcja jest pisana z pamięci więc mogą pojawić się jakieś braki. W przypadku gdy instrukcja nie zadziała proszę o komentarz, a postaram się pomóc i uzupełnić wpis tak by był kompletny.<br />
Aby ułatwić sobie życie i zaoszczędzić pamięć na serwerze wszystkie produkty będzie obsługiwała jedna instancja Tomcat i PostgreSQL. Niestety Fisheye i Bamboo są dostępne tylko w wersji standalone, stąd proces ich instalacji będzie nieco inny. Zanim ruszymy z całością pobieramy od producenta oprogramowanie.<br />
<img src="http://blog.code-house.org/wp-content/uploads/crowd.jpg" alt="Pobieranie Crowd" title="Pobieranie Crowd" width="647" height="247" class="aligncenter size-full wp-image-138" /><br />
Przeskakujemy na zakładkę Linux i następnie klikamy w prawym górnym rogu i pobieramy wersję standalone. Wykonujemy polecenie</p>
<pre class="brush: bash;">tar -xvzf atlassian-crowd-2.0.2.tar.gz</pre>
<p>Po rozpakowaniu pojawią się następujące katalogi</p>
<ul>
<li>apache-tomcat</li>
<li>client</li>
<li>crowd-openidclient-webapp</li>
<li>crowd-openidserver-webapp</li>
<li>crowd-webapp</li>
<li>demo-src</li>
<li>demo-webapp</li>
<li>etc</li>
</ul>
<p>Będziemy potrzebować tylko dwóch &#8211; <strong>crowd-webapp oraz opcjonalnie openidserver</strong>. Dystrybucja standalone zawiera już Tomcata, zatem najpotrzebniejsze biblioteki weźmiemy już stąd. :) Kopiujemy biblioteki:</p>
<ul>
<li>activation-1.1.jar</li>
<li>mail-1.4.jar</li>
<li>jta-1.0.1B.jar</li>
</ul>
<p>Do katalogu lib naszego tomcata. Na Gentoo jest to <strong>/usr/share/tomcat-6/lib</strong>.<br />
Pierwsze dwie biblioteki będą potrzebne do używania obiektu <strong>javax.mail.Session zapisanego w drzewie JNDI</strong>. Dodatkowo <a href="http://jdbc.postgresql.org/download.html">pobieramy driver</a> JDBC dla bazy PostgreSQL. Należy pamiętać że wersja JDBC 4 jest przeznaczona do uruchamiania na Java 1.6. Ja ściągnąłem wersję <a href="http://jdbc.postgresql.org/download/postgresql-8.4-701.jdbc4.jar">8.4-701.jdbc4</a>. Mając te biblioteki przystępujemy do konfiguracji kontekstu Tomcata.<br />
W pierwszym kroku dodajemy globalną sesję mailową którą będziemy współdzielić między aplikacjami. W ten sposób zmiana w jednym miejscu będzie skutkować &#8220;aktualizacją&#8221; konfiguracji wszystkich aplikacji. Edytujemy plik $TOMCAT_HOME/conf/server.xml. W sekcji GlobalNaminResources umieszczamy dodatkowy fragment:</p>
<pre class="brush: xml; class-name: xml;">  &lt;GlobalNamingResources&gt;
    &lt;!-- Ten wpis jest domyślnie dostępny --&gt;
    &lt;Resource name=&quot;UserDatabase&quot; auth=&quot;Container&quot;
              type=&quot;org.apache.catalina.UserDatabase&quot;
              description=&quot;User database that can be updated and saved&quot;
              factory=&quot;org.apache.catalina.users.MemoryUserDatabaseFactory&quot;
              pathname=&quot;conf/tomcat-users.xml&quot; /&gt;

    &lt;Resource name=&quot;mail/Session&quot; auth=&quot;Container&quot;
              type=&quot;javax.mail.Session&quot;
              description=&quot;JavaMail Session&quot;
              username=&quot;user&quot;
              password=&quot;pass&quot;
              mail.smtp.host=&quot;host&quot;
              mail.smtp.auth=&quot;true&quot;
              mail.user=&quot;user&quot;
              mail.password=&quot;pass&quot;
              mail.transport.protocol=&quot;smtp&quot;
              /&gt;
  &lt;/GlobalNamingResources&gt;</pre>
<p>Konieczna będzie również zmiana sekcji Server:</p>
<pre class="brush: xml; class-name: xml;">    &lt;Connector port=&quot;8080&quot; protocol=&quot;HTTP/1.1&quot;
               connectionTimeout=&quot;20000&quot;
               redirectPort=&quot;8443&quot; URIEncoding=&quot;UTF-8&quot; /&gt;&lt;!-- dodajemy URIEncoding --&gt;</pre>
<p>Atrybut URIEncoding będzie wymagany przez min. confluence i umożliwia przesyłanie krzaczków w adresie. Warto również zwiększyć limity pamięci Tomcata ponieważ na domyślnych długo nie pociągnie i prawdopodobnie już przy instalacji JIRA albo Confluence poleci OutOfMemory.</p>
<p>Drugi krok to ustawienie zmiennej crowd-home. W tym celu należy <strong>wyedytować plik crowd-webapp/WEB-INF/classes/crowd-init.properties</strong>.</p>
<pre class="brush: plain;">crowd.home=/var/lib/tomcat-6/atlassian/crowd-home</pre>
<p>W razie problemów można &#8220;zresetować&#8221; instalację usuwając folder home, czego oczywiście nie radzę robić. :) Trzeci krok to konfiguracja kontekstu Crowd.</p>
<pre class="brush: xml; class-name: xml;">&lt;Context path=&quot;/crowd&quot; docBase=&quot;/var/lib/tomcat-6/atlassian/crowd-webapp&quot; debug=&quot;0&quot;&gt;
    &lt;Resource name=&quot;jdbc/CrowdDS&quot; auth=&quot;Container&quot; type=&quot;javax.sql.DataSource&quot;
            username=&quot;user&quot;
            password=&quot;pass&quot;
            driverClassName=&quot;org.postgresql.Driver&quot;
            validationQuery=&quot;select 1&quot;
            url=&quot;jdbc:postgresql://localhost:5432/database&quot;/&gt;

    &lt;ResourceLink name=&quot;mail/Session&quot;
            global=&quot;mail/Session&quot;
            type=&quot;javax.mail.Session&quot; /&gt;
&lt;/Context&gt;</pre>
<p>W miejscu docBase należy podać folder w którym znajduje się crowd. Kopiujemy plik crowd.xml do katalogu $TOMCAT_HOME/conf/Catalina/localhost. Ok wygląda na to, że to wszystko co było potrzebne, zatem teraz restart Tomcata i powinno działać.. Powinno, ale nie działa. Problem, z którym męczyłem się bardzo długo to <strong>niewidoczny zasób jdbc/CrowdDS</strong> w procesie instalacji. O dziwo <strong>mail/Session</strong> był widoczny. Przy pierwszym podejściu poddałem się i skonfigurowałem połączenie w instalatorze podając te same dane co w konfiguracji kontekstu. Jednakże, po chwili zastanowienia i tych samych problemach z JIRA postanowiłem powtórzyć proces. Logi wskazywały że data source nie uruchamia się, ponieważ pojawiały się wpisy WARN o nieodnalezionej klasie. Poszperałem i dowiedziałem się że potrzebuję biblioteki tomcat-dbcp.jar, której oczywiście nie ma w dystrybucji. Całe szczęście znalazłem <a href="http://www.java2s.com/Code/Jar/STUVWXYZ/Downloadtomcatdbcpjar.htm">w serwisie Java2S</a>. Po ściągnięciu zipa, należy go rozpakować i <strong>skopiować tomcat-dbcp.jar</strong> do $TOMCAT_HOME/lib.</p>
<h2>Instalacja CROWD</h2>
<p>Status aplikacji powinien być widoczny w managerze Tomcata. Jeśli wszystko jest w porządku, przechodzimy do instalatora. W pierwszej kolejności zostaniemy zapytani o licencję, następnie o połączenie z bazą danych i sesję mailową. Podajemy zatem co trzeba &#8211; ścieżka do data source to <strong>java:comp/env/jdbc/CrowdDS</strong> a do maila <strong>java:comp/env/mail/Session</strong>. Konfigurację grup i tak dalej pominę i odeślę do <a href="http://confluence.atlassian.com/display/ATLAS/Dragons+Stage+1+-+Install+Java%2C+PostgreSQL+and+Crowd#DragonsStage1-InstallJava%2CPostgreSQLandCrowd-Step4.InstallCrowd">oficjalnej dokumentacji</a>.</p>
<h2>Instalacja JIRA</h2>
<p>JIRA jako oprogramowanie bardziej wymagające będzie wymagała kilku dodatkowych bilbiotek. Przede wszystkim pobieramy <a href="http://confluence.atlassian.com/download/attachments/200709089/jira-jars-tomcat6.zip?version=1&#038;modificationDate=1252474277487">jira-tomcat6-jars.zip</a>. Całość należy wpakować do $TOMCAT_HOME/lib. Następnie pobieramy wersję WAR/EAR:<br />
<img src="http://blog.code-house.org/wp-content/uploads/jira.jpg" alt="Pobieranie JIRA" title="Pobieranie JIRA" width="852" height="188" class="aligncenter size-full wp-image-147" /><br />
Po rozpakowaniu
<pre class="brush: bash;">unzip atlassian-jira-enterprise-4.0.zip</pre>
<p> przechodzimy do katalogu atlassian-jira-enterprise-4.0/edit-webapp/WEB-INF/classes. Musimy tutaj zmienić końcówkę pliku entityengine.xml:</p>
<pre class="brush: xml; class-name: xml;">
    &lt;datasource name=&quot;defaultDS&quot; field-type-name=&quot;postgres72&quot;
      schema-name=&quot;public&quot;
      helper-class=&quot;org.ofbiz.core.entity.GenericHelperDAO&quot;
      check-on-start=&quot;true&quot;
      use-foreign-keys=&quot;false&quot;
      use-foreign-key-indices=&quot;false&quot;
      check-fks-on-start=&quot;false&quot;
      check-fk-indices-on-start=&quot;false&quot;
      add-missing-on-start=&quot;true&quot;
      check-indices-on-start=&quot;true&quot;&gt;
        &lt;jndi-jdbc jndi-server-name=&quot;default&quot; jndi-name=&quot;java:comp/env/jdbc/JiraDS&quot;/&gt;
&lt;!-- Orion format: &lt;jndi-jdbc jndi-server-name=&quot;default&quot; jndi-name=&quot;jdbc/JiraDS&quot;/&gt; --&gt;
&lt;!-- JBoss format: &lt;jndi-jdbc jndi-server-name=&quot;default&quot; jndi-name=&quot;java:/DefaultDS&quot;/&gt; --&gt;
&lt;!-- Weblogic format: &lt;jndi-jdbc jndi-server-name=&quot;default&quot; jndi-name=&quot;JiraDS&quot;/&gt; --&gt;
    &lt;/datasource&gt;
</pre>
<p>Poszczególne atrybuty oznaczają:</p>
<ul>
<li><strong>field-type-name</strong> &#8211; rodzaj bazy danych, wartość <strong>postgres72</strong> oznacza PostgreSQL 7.2 i nowsze.</li>
<li><strong>schema-name</strong> &#8211; nazwa domyślnego schematu, trzeba przepisać z PUBLIC, które akceptuje HSQL na public</li>
<li><strong>jndi-jdbc/jndi-name</strong> &#8211; pozostawiamy bez zmian, nasz data source będzie w lokalizacji <strong>java:comp/env/jdbc/JiraDS</strong></li>
</ul>
<p>Pozostaje <strong>ustawienie jira.home w pliku jira-application.properties</strong> i uruchomienie polecenia build.sh. Po tych krokach tworzymy plik jira.xml w którym zdefiniujemy kontekst tej aplikacji.</p>
<pre class="brush: xml; class-name: xml;">&lt;Context path=&quot;/jira&quot; docBase=&quot;/var/lib/tomcat-6/atlassian/atlassian-jira-4.0.war&quot; debug=&quot;0&quot;&gt;
    &lt;Resource name=&quot;jdbc/JiraDS&quot; auth=&quot;Container&quot; type=&quot;javax.sql.DataSource&quot;
            username=&quot;user&quot;
            password=&quot;pass&quot;
            driverClassName=&quot;org.postgresql.Driver&quot;
            validationQuery=&quot;select 1&quot;
            url=&quot;jdbc:postgresql://localhost:5432/database&quot;/&gt;
    &lt;Resource name=&quot;UserTransaction&quot; auth=&quot;Container&quot; type=&quot;javax.transaction.UserTransaction&quot;
            factory=&quot;org.objectweb.jotm.UserTransactionFactory&quot; jotm.timeout=&quot;60&quot;/&gt;
    &lt;ResourceLink name=&quot;mail/Session&quot;
            global=&quot;mail/Session&quot;
            type=&quot;javax.mail.Session&quot; /&gt;
&lt;/Context&gt;</pre>
<p>Plik kopiujemy do $TOMCAT_HOME/conf/Catalina/localhost. Procedura instalacji powinna przebiegać podobnie jak w przypadku Crowd, czyli podajemy licencję, określamy bazę danych (java:comp/env/jdbc/JiraDS) i kilka kolejnych parametrów.</p>
<h2>Instalacja GreenHopper</h2>
<p>GreenHopper jako dodatek do JIRA nie wymaga konfiguracji bazy danych. Jedyne co robimy po jego pobraniu to <strong>kopiujemy go do $JIRA_HOME/plugins/installed-plugins</strong>. Reload kontekstu z managera Tomcata, i przechodzimy do administracji naszym bugtrackerem. W lewym menu szukamy sekcji <em>System/GreenHopper Licence</em>. Po podaniu klucza należy stworzyć projekt. Bez niego nie zobaczymy GreenHoppera w akcji.</p>
<h2>Instalacja Confluence</h2>
<p>Ostatni krok to instalacja Confluence. Pobieramy dystrybucję WAR/EAR:<br />
<img src="http://blog.code-house.org/wp-content/uploads/confluence.jpg" alt="Pobieranie Confluence" title="Pobieranie Confluence" width="647" height="309" class="aligncenter size-full wp-image-151" /></p>
<p>Tutaj też czeka nas nieco zabawy, ale nie tak dużo. Po rozpakowaniu
<pre class="brush: bash;">unzip confluence-3.0.2.zip</pre>
<p> edytujemy plik confluence-3.0.2/confluence/WEB-INF/classes/confluence-init.properties:</p>
<pre class="brush: plain;">confluence.home=/var/lib/tomcat-6/atlassian/confluence-home</pre>
<p>Mając to wszystko, możemy spokojnie zająć <strong>kontekstem confluence.xml</strong>:</p>
<pre class="brush: xml; class-name: xml;">&lt;Context path=&quot;/confluence&quot; docBase=&quot;/var/lib/tomcat-6/atlassian/confluence-3.0.2.war&quot; debug=&quot;0&quot;&gt;
    &lt;Resource name=&quot;jdbc/ConfDS&quot; auth=&quot;Container&quot; type=&quot;javax.sql.DataSource&quot;
            username=&quot;user&quot;
            password=&quot;pass&quot;
            driverClassName=&quot;org.postgresql.Driver&quot;
            validationQuery=&quot;select 1&quot;
            url=&quot;jdbc:postgresql://localhost:5432/database&quot;/&gt;

  &lt;ResourceLink name=&quot;mail/Session&quot;
            global=&quot;mail/Session&quot;
            type=&quot;javax.mail.Session&quot; /&gt;

&lt;/Context&gt;</pre>
<p>Plik podobnie jak poprzednie zapisujemy w $TOMCAT_HOME/conf/Catalina/localhost. Po tym wszystkim instalujemy.</p>
<h2>Konfiguracja Apache</h2>
<p>Skakanie po portach i kontekstach nie jest bardzo wygodne, dlatego też warto skonfigurować Apache i mod_proxy aby wszystko było dostępne z poziomu portu 80, a nie 8080. W ten oto sposób Nexus którego używamy jest widoczny pod adresem <a href="http://repository.code-house.org/">repository.code-house.org</a>, a nie localhost:8080. W konfiguracji vhosta umieszczamy:</p>
<pre class="brush: plain;">&lt;IfModule mod_proxy.c&gt;
ProxyRequests On

ProxyPass /jira http://localhost:8080/jira
ProxyPassReverse /jira http://localhost:8080/jira
ProxyPreserveHost On

ProxyPass /confluence http://localhost:8080/confluence
ProxyPassReverse /confluence http://localhost:8080/confluence
ProxyPreserveHost On

ProxyPass /crowd http://localhost:8080/crowd
ProxyPassReverse /crowd http://localhost:8080/crowd
ProxyPreserveHost On

&lt;/IfModule&gt;</pre>
<h2>Podsumowanie</h2>
<p>Instalacja tych 3 aplikacji (nie licząc GreenHoppera) zajęła mi praktycznie cały dzień. Przyczyną największych problemów był Tomcat i wszystko inne &#8211; czyli np. źle wypakowane archiwum. Diagnostyka z logów Tomcata jest trudna, nie uświadczyłem w nich stack trace z wyjątkiem że nie może połączyć się do bazy. Nie mogłem zestawić również log4j na poziomie kontenera &#8211; który kłócił się później z Nexusem, a konfiguracja commons-logging jest jak na moje oko pokręcona. Po tym jak już dowiedziałem się co Tomcat powinien mieć w lib/ poszło z górki. Jeszcze nie zdecydowałem się na integrację JIRA i Confluence z Crowd ponieważ pierwsze podejście było nieudane i JIRA odmówiła uruchomienia się grzecznie zgłaszając java.lang.NullPointerException. :)<br />
Mam nadzieję, że dzięki tej krótkiej instrukcji Wy drodzy czytelnicy nie będziecie mieli tylu problemów.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.code-house.org/2009/10/instalowanie-oprogramowania-atlassian-cz-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
