<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-928894612202750731</atom:id><lastBuildDate>Thu, 05 Jan 2012 18:48:52 +0000</lastBuildDate><category>koncerty</category><category>JPA</category><category>Spring Framework</category><category>Świat</category><category>skalowalność</category><category>bazy danych</category><category>testy wydajnościowe</category><category>Java 7</category><category>Java ME</category><category>LWUIT</category><category>ludzie</category><category>db2</category><category>Spring Security</category><category>firebird</category><category>programowanie</category><category>EJB</category><category>szkoła</category><category>kabaret</category><category>geecon</category><category>Hadoop</category><category>eclipse</category><category>konferencje</category><category>głupoty</category><category>niesamowite</category><category>humor</category><category>linux</category><category>recenzja</category><category>JMeter</category><category>Oracle Coherence</category><category>Internet</category><category>php</category><category>samochody</category><category>Poznań-JUG</category><category>Web services</category><category>Java</category><category>NetBeans</category><category>Google</category><category>OpenBaseMovil-db</category><category>jDeveloper</category><category>JavaFX</category><category>O mnie</category><category>VoIP</category><category>Muzyka</category><category>dbMonster</category><category>JMX</category><category>Agile</category><category>JSF</category><category>film</category><category>Glassfish</category><category>Facelets</category><title>Łukasz Stachowiak blog</title><description>notes &amp;amp; other stuff...</description><link>http://blog.lstachowiak.pl/</link><managingEditor>noreply@blogger.com (WooKasZ)</managingEditor><generator>Blogger</generator><openSearch:totalResults>156</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/wookasz" /><feedburner:info uri="wookasz" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-741226147880404041</guid><pubDate>Fri, 01 Jul 2011 06:52:00 +0000</pubDate><atom:updated>2011-07-01T08:52:50.895+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Poznań-JUG</category><title>Poznań JUG - Warsztaty z języka Scala</title><description>&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/en/archive/8/85/20090127225152!Scala_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="46" src="http://upload.wikimedia.org/wikipedia/en/archive/8/85/20090127225152!Scala_logo.png" width="320" /&gt;&lt;/a&gt;Dzięki uprzejmości Grzegorza Balcerka, który zgłosił pomysł oraz siebie jako ochotnika do poprowadzenia warsztatów, mam przyjemność zaprosić wszystkich na otwarte warsztaty z języka Scala!&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Scala ostatnio robi się dość popularna, więc warto przyjść i "liznąć" trochę z tego języka. Bez przedłużania dane szczegółowe:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Data: &lt;b&gt;09.07.2011 (sobota)&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Godzina: &lt;b&gt;10:00&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Miejsce: &lt;b&gt;Siedziba Cognifide (uwaga zmiana adresu!) &amp;nbsp;ul. Murawa 12-18&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Rejestracja:&amp;nbsp;&lt;b&gt;&lt;a href="http://oiola.com/e/738-warsztaty-z-jezyka-scala/reg/"&gt;tutaj&lt;/a&gt;&amp;nbsp;(wymagana, liczba miejsc ograniczona!)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Wymagane jest posiadanie własnego laptopa (prosimy zabrać listwy zasilające;) z JDK 6.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Opis warsztatów nadesłany od autora:&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;Zakres: od podstaw do .... - nie wiem, zależy na ile czas&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;pozwoli.Poniżej kolejne tematy które mogłyby być omawiane, ale nie&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;wydaje mi się żeby było możliwe omówienie wszystkiego - ze względów&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;czasowych: wprowadzenie, podstawy składni, podstawowe typy danych,&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;wyrażenia sterujące, klasy, cechy, metody, obiekty, typy ogólne,&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;standardowe typy ogólne, funkcje, dopasowywanie wzorców, klasy i&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;obiekty przypadków, pakiety, klauzule importu, uprawnienia, wyjątki i&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;wyrażenie return, modyfikator implicit, kolekcje, pętla for, XML,&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;programowanie interfejsów graficznych, programowanie współbieżne,&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 12px;"&gt;parsowanie, adnotacje, języki dostosowane do dziedziny, kompilator&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;Przewidziana jest przerwa obiadowa z pizzą i napojami :-)&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Zapraszam!&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-741226147880404041?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/8m5yZmNhgMw/poznan-jug-warsztaty-z-jezyka-scala.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2011/07/poznan-jug-warsztaty-z-jezyka-scala.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-5557091764087773132</guid><pubDate>Fri, 24 Jun 2011 21:50:00 +0000</pubDate><atom:updated>2011-06-25T00:15:13.824+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">Java 7</category><title>(Prawdopodobnie ostatnie) Podsumowanie nowości w Java 7</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-8IpObTKwMhI/Sbzz9OuVopI/AAAAAAAADDM/TLLVOTBiNZA/s1600/duke.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-8IpObTKwMhI/Sbzz9OuVopI/AAAAAAAADDM/TLLVOTBiNZA/s1600/duke.png" /&gt;&lt;/a&gt;&lt;/div&gt;Wpisów na temat rzeczy, które mają się pojawić w Java 7 już kilka u mnie powstało (&lt;a href="http://blog.lstachowiak.pl/search/label/Java%207"&gt;3&lt;/a&gt;). Ale ten chyba będzie ostatnim, bo termin wydania jest już znany i bliski - &lt;b&gt;28 lipca 2011&lt;/b&gt;! Z tej okazji postanowiłem przejrzeć ten brzydki dokument&amp;nbsp;&lt;a href="http://www.jcp.org/en/jsr/detail?id=336"&gt;JSR 336&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Żeby nie zanudzać i nie rozwodzić się za bardzo (większość rzeczy już jak wspomniałem &lt;a href="http://blog.lstachowiak.pl/search/label/Java%207"&gt;opisałem&lt;/a&gt;), lista zwycięzców tej długiej bitwy:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Bytecode&lt;/b&gt;&lt;br /&gt;
Lepsze wsparcie dla języków dynamicznych opartych na JVM - dodanie instrukcji &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;invokedynamic&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Java Beans&lt;/b&gt;&lt;br /&gt;
Tutaj głównie poprawki w API. Dodano adnotację @Transient i oznaczono nią trochę getterów, poza tym poprawki w API ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Kolekcje&lt;/b&gt;&lt;br /&gt;
Tutaj podobnie dodatki w API. Głównie chwalą się dodaniem metod &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Collections.emptyIterator()&lt;/span&gt; oraz &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Collection&lt;span class="Apple-style-span" style="white-space: nowrap;"&gt;s.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="white-space: nowrap;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;emptyEnumeration()&lt;/span&gt; oraz zaktualizowaniem dokumentacji.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;I/O&lt;/b&gt;&lt;br /&gt;
Nowe IO! NIO.2 opisane w &lt;a href="http://jcp.org/en/jsr/detail?id=203"&gt;JSR 203&lt;/a&gt; :-) Wsparcie dla POSIX i ACL, nowy pakiet &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;java.nio.file&lt;/span&gt; zawierający stuff do obsługi metadanych, dowiązań, ułatwienia przeglądania katalogów (interface &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;FileVisitor&lt;/span&gt;) &amp;nbsp;i jeszcze trochę tego, ale za bardzo się nie zagłębiałem akurat w ten temat.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;java.lang&lt;/b&gt;&lt;br /&gt;
Tutaj tzw. &lt;a href="http://jcp.org/en/jsr/summary?id=334"&gt;project coin (JSR 334)&lt;/a&gt; z zestawem kilku zmian do samego języka: switch po stringu, blok try dla zasobów wymagających zamykania, multi-catch, rozszerzona składnia dla liczb, dedukcja typów (dla generyków). Poza &lt;span class="Apple-style-span" style="font-family: inherit;"&gt;tym wiadomo dodatki/usprawnienia w API (w tym już chyba sławny&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;&lt;em style="font-style: normal;"&gt;java&lt;/em&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;.&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;&lt;em style="font-style: normal;"&gt;util&lt;/em&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 19px;"&gt;&lt;em style="font-style: normal;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Objects&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; z metodami do porównywania obiektów, obliczania hashcode itp.)&lt;/span&gt;.&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Class loader&lt;/b&gt;&lt;br /&gt;
Wsparcie dla współbieżnych class loaderów! :-)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Współbieżność&lt;/b&gt;&lt;br /&gt;
Dodano nowy framework ForkJoin przeznaczony dla aplikacji z intensywnymi obliczeniami. Posiada dobre wsparcie dla maszyn wieloprocesorowych i jest niezależny od platformy. + dodatki w standardowym API.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;I18N&lt;/b&gt;&lt;br /&gt;
Wsparcie dla Unicode 6.0.0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To były główne zmiany, poza tym różnorakie zmiany w:&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;java.util.logging&lt;/span&gt;,&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;java.util.regex&lt;/span&gt;, &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;java.net&lt;/span&gt;, JMX, &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;java.util.zip&lt;/span&gt;, bezpieczeństwie (obsługa TLS 1.2) oraz dodatki do Swinga i AWT.&lt;br /&gt;
&lt;br /&gt;
Jak widać ostatecznie domknięcia nie zmieściły się w wersji finalnej. To samo tyczy się projektu Jigsaw czyli modularyzacji JDK (co mnie bardzo zdziwiło, bo myślałem, że to pewniak). Jestem z tego powodu bardzo zawiedziony, bo to dla mnie były właśnie te &lt;i&gt;killing-features&lt;/i&gt;, które wprowadziłyby nowy blask językowi.&lt;br /&gt;
&lt;br /&gt;
No cóż... z nadzieją musimy obserwować rozwój specyfikacji &lt;a href="http://jcp.org/en/jsr/detail?id=337"&gt;Javy 8&lt;/a&gt;... :-/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-5557091764087773132?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/Vz3S4DME8Ks/prawdopodobnie-ostatnie-podsumowanie.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-8IpObTKwMhI/Sbzz9OuVopI/AAAAAAAADDM/TLLVOTBiNZA/s72-c/duke.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2011/06/prawdopodobnie-ostatnie-podsumowanie.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-5665573765648167194</guid><pubDate>Sun, 19 Jun 2011 10:40:00 +0000</pubDate><atom:updated>2011-06-19T12:46:47.844+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">Hadoop</category><title>Pierwszy Job z Hadoop</title><description>Zanim napiszemy pierwszego joba trzeba przygotować sobie środowisko. Obsługa wszystkiego z konsoli może z czasem być nużąca (chociaż ja tam lubię;).&lt;br /&gt;
&lt;br /&gt;
Ja do dewelopmentu używam &lt;a href="http://netbeans.org/"&gt;NetBeansa&lt;/a&gt; i polecam wtyczkę &lt;a href="http://www.karmasphere.com/Download/register-for-community-edition.html"&gt;Karmaspehere Community Edition&lt;/a&gt;. Pozwala ona w łatwy sposób definiować i odpalać sobie zadania Hadoopa.&lt;br /&gt;
Aby zainstalować tę wtyczkę należy dodać do listy 'update sites' adres: http://hadoopstudio.org/updates/updates.xml. Ja zainstalowałem wszystkie 4 dostępne pluginy od Karmasphere. Polecam też się zarejestrować i aktywować plugin, bo będą się pojawiać komunikaty o aktywacji (ale chyba można pracować bez niej).&lt;br /&gt;
&lt;br /&gt;
Ok, możemy zacząć pisać :-) Projekt oparłem o maven, pom.xml nie jest zbyt rozdbudowany:&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;

    &amp;lt;groupId&amp;gt;pl.lstachowiak&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;HadoopSamples&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;

    &amp;lt;name&amp;gt;HadoopSamples&amp;lt;/name&amp;gt;
    &amp;lt;url&amp;gt;http://blog.lstachowiak.pl&amp;lt;/url&amp;gt;

    &amp;lt;properties&amp;gt;
        &amp;lt;project.build.sourceEncoding&amp;gt;UTF-8&amp;lt;/project.build.sourceEncoding&amp;gt;
    &amp;lt;/properties&amp;gt;

    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;4.8&amp;lt;/version&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
        
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.apache.mahout.hadoop&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;hadoop-core&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;0.20.1&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;commons-logging&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;commons-logging&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;1.1.1&amp;lt;/version&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/project&amp;gt;&lt;/pre&gt;&lt;br /&gt;
Problem jaki wybrałem dla pierwszego przykładu to analiza statystyk serwera Apache. Bierzemy plik access.log i analizujemy typy żądań do serwera. Na końcu chcemy mieć liczbę żądań każdego typu.&lt;br /&gt;
Mój pomysł na Map i Reduce jest następujący:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-K4K4n7LgVYc/Tf2-HULOJ3I/AAAAAAAAECQ/er6OzwuYfXM/s1600/MapReduceSample1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="121" src="http://2.bp.blogspot.com/-K4K4n7LgVYc/Tf2-HULOJ3I/AAAAAAAAECQ/er6OzwuYfXM/s640/MapReduceSample1.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Czyli:&lt;br /&gt;
- Hadoop wczytuje i dzieli plik na tzw '&lt;b&gt;input splits&lt;/b&gt;'&lt;br /&gt;
- przekazuje każdy split do funkcji map, gdzie kluczem jest numer linii w pliku a wartością sama linia&lt;br /&gt;
- implementowana przez nas funkcja &lt;b&gt;map&lt;/b&gt; sprawdza jaki tym żądania HTTP znajduje się w linii i zwraca jako klucz typ żądania a jako wartość liczbę 1 (umownie sobie tak robimy)&lt;br /&gt;
- Hadoop wykonuje tzw. &lt;b&gt;shuffle&lt;/b&gt; grupując nam wyniki z map w pary [TYP] -&amp;gt; [KOLEKCJA JEDYNEK]&lt;br /&gt;
- nasza funkcja &lt;b&gt;reduce&lt;/b&gt;&amp;nbsp;jedyne co robi to zlicza liczbę elementów w kolekcji i zwraca jako klucz typ żądania a jako wartość liczbę elementów w kolekcji co jest zarazem wynikiem końcowym&lt;br /&gt;
- Hadoop zapisuje dane na dysk&lt;br /&gt;
&lt;br /&gt;
(Bardzo) Możliwe, że nie jest to idealne rozwiązanie, ale nie mam jeszcze wielkiego doświadczenia z Hadoop ;)&lt;br /&gt;
&lt;br /&gt;
Przejdźmy&amp;nbsp;do implementacji. Funkcja map:&lt;br /&gt;
&lt;i&gt;HttpMethodMapper.java&lt;/i&gt;:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;package pl.lstachowiak.hadoop.sample1;

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;


public class HttpMethodMapper extends Mapper&amp;lt;LongWritable, Text, Text, IntWritable&amp;gt; { // 1

    @Override
    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        HttpMethod method = getMethodFromLine(value); // 2
        context.write(new Text(method.name()), new IntWritable(1)); // 3
    }

    HttpMethod getMethodFromLine(Text value) {

        if (value.find(HttpMethod.CONNECT.name()) != -1) {
            return HttpMethod.CONNECT;
        }

        if (value.find(HttpMethod.DELETE.name()) != -1) {
            return HttpMethod.DELETE;
        }

        if (value.find(HttpMethod.GET.name()) != -1) {
            return HttpMethod.GET;
        }

        if (value.find(HttpMethod.HEAD.name()) != -1) {
            return HttpMethod.HEAD;
        }

        if (value.find(HttpMethod.OPTIONS.name()) != -1) {
            return HttpMethod.OPTIONS;
        }

        if (value.find(HttpMethod.PATH.name()) != -1) {
            return HttpMethod.PATH;
        }

        if (value.find(HttpMethod.POST.name()) != -1) {
            return HttpMethod.POST;
        }

        if (value.find(HttpMethod.PUT.name()) != -1) {
            return HttpMethod.PUT;
        }

        if (value.find(HttpMethod.TRACE.name()) != -1) {
            return HttpMethod.TRACE;
        }

        return HttpMethod.UNKNOWN;
    }
}
&lt;/pre&gt;Krótki komentarz do tego co się dzieje w kodzie:&lt;br /&gt;
1 - klasa mappera musi (od wersji API 0.20) rozszerzać klasę Mapper. Parametrami są kolejno:&lt;br /&gt;
- typ klucza (numer linii)&lt;br /&gt;
- typ wartości (linia w pliku)&lt;br /&gt;
- typ klucza wynikowego (typ żądania http)&lt;br /&gt;
- typ wartości wynikowe (liczba 1)&lt;br /&gt;
2 - pobranie typu żądania z linii, wiem, że rozwiązanie jest dalekie od idealnego, ale nie o to chodzi w przykładzie ;)&lt;br /&gt;
3 - zapis wyniku&lt;br /&gt;
&lt;br /&gt;
Jak widać Hadoop posiada własny zestaw typów danych. W większości są to obudowane typy podstawowe. Stworzone zostały one aby w troszkę lepszy sposób serializować dane i przesyłać przez sieć. Zaleca się ich używanie. Typ HttpRequest to zwykły enum z listą dostępnych typów żądań HTTP. Dostępny jest w źródłach.&lt;br /&gt;
&lt;br /&gt;
Funkcja reduce:&lt;br /&gt;
&lt;i&gt;HttpMethodReducer.java&lt;/i&gt;:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;package pl.lstachowiak.hadoop.sample1;

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.Reducer.Context;


public class HttpMethodReducer extends Reducer&amp;lt;Text, IntWritable, Text, IntWritable&amp;gt; { // 1

    @Override
    protected void reduce(Text key, Iterable&amp;lt;IntWritable&amp;gt; values, Context context) throws IOException, InterruptedException { // 2
        int counter = countValues(values); // 3
        context.write(key, new IntWritable(counter)); // 4
    }
    
    &amp;lt;T&amp;gt; int countValues(Iterable&amp;lt;T&amp;gt; values) {
        int counter = 0;
        for (T value : values) {
            counter++;
        }
        
        return counter;
    }
}&lt;/pre&gt;Ponownie krótki komentarz:&lt;br /&gt;
1 - musimy rozszerzać klasę Reducer, parametry kolejno to:&lt;br /&gt;
- typ klucza z Map&lt;br /&gt;
- typ wartości z Map&lt;br /&gt;
- typ klucza wynikowego&lt;br /&gt;
- typ wartości wynikowej&lt;br /&gt;
2 - tutaj widać efekt działania operacji shuffle. Zamiast otrzymywać tą jedynkę z funkcji Map otrzymujemy iterator po kolekcji jedynek (w naszym przykładzie).&lt;br /&gt;
3 - zliczamy elementy&lt;br /&gt;
4 - zapisujemy w wynikach :-)&lt;br /&gt;
&lt;br /&gt;
No to jeszcze program do uruchomienia zadania:&lt;br /&gt;
&lt;i&gt;HttpMethodJob.java&lt;/i&gt;:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;package pl.lstachowiak.hadoop.sample1;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;


public class HttpMethodJob {
    
    public static void main(String[] args) throws Exception {
        
        if (args.length != 2) {
            System.err.println("Usage: HttpMethodJob &amp;lt;input path&amp;gt; &amp;lt;output path&amp;gt;");
            System.exit(-1);
        }
        
        Job job = new Job();
        job.setJarByClass(HttpMethodJob.class); // 1
        
        FileInputFormat.addInputPath(job, new Path(args[0])); // 2
        FileOutputFormat.setOutputPath(job, new Path(args[1])); // 3
        
        job.setMapperClass(HttpMethodMapper.class); // 4
        job.setReducerClass(HttpMethodReducer.class); // 5
        
        job.setOutputKeyClass(Text.class); // 6
        job.setOutputValueClass(IntWritable.class); // 7
        
        System.exit(job.waitForCompletion(true) ? 0 : 1); // gogogo!
        
    }
}&lt;/pre&gt;&lt;br /&gt;
1 - tworzymy zadanie i podajemy klasę główna&lt;br /&gt;
2,3 - podajemy źródło danych oraz miejsce zapisu danych wynikowych (wczytywane z argumentów)&lt;br /&gt;
4,5 - podajemy klasę mappera i reducera&lt;br /&gt;
6,7 - konfiguracja typów danych wynikowych&lt;br /&gt;
I uruchomienie zadania :-)&lt;br /&gt;
&lt;br /&gt;
Zanim jednak zaczniemy potrzebne są jeszcze jakieś dane do analizy. Ja wygooglałem coś &lt;a href="http://www.twoquail.com/logs/access.log"&gt;tutaj&lt;/a&gt;&amp;nbsp;(4,3MB).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Uruchomienie&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Tutaj obrazkowo:) Przechodzimy do zakładki Services (NetBeans) -&amp;gt; Servers -&amp;gt; Hadoop Jobs -&amp;gt; New Job. Wybieramy nazwę dla Joba i typ 'Hadoop Job from pre-existing JAR file'.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-JB4NEyIekpg/Tf3L6_XfDdI/AAAAAAAAECU/1gLIc1HVw10/s1600/newHadoopJob1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="277" src="http://2.bp.blogspot.com/-JB4NEyIekpg/Tf3L6_XfDdI/AAAAAAAAECU/1gLIc1HVw10/s400/newHadoopJob1.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Następnie wpisujemy ścieżkę do JARa (ja podałem z targeta) oraz klasę z funkcją main.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-NYysWy9xCGA/Tf3MWDTX1pI/AAAAAAAAECY/lqNirsQqdrE/s1600/newHadoopJob2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="213" src="http://2.bp.blogspot.com/-NYysWy9xCGA/Tf3MWDTX1pI/AAAAAAAAECY/lqNirsQqdrE/s400/newHadoopJob2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;W następnym oknie wybieramy klaster dla wersji 0.20 oraz wpisujemy argumenty dla zadania. Kolejno plik access.log oraz katalog w którym mają być składowane wyniki końcowe.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-E-JqVPewTCg/Tf3MrnM6ObI/AAAAAAAAECc/iRXyfx3LH_0/s1600/newHadoopJob3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-E-JqVPewTCg/Tf3MrnM6ObI/AAAAAAAAECc/iRXyfx3LH_0/s400/newHadoopJob3.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I klikamy 'finish' :-)&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Teraz możemy odpalać!&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Prawy guzik na nowego Joba -&amp;gt; Run Job -&amp;gt; Run.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;Wszystko powinno pójść dobrze, stan konsoli na końcu (statystyki):&lt;br /&gt;
&lt;pre&gt;11/06/19 11:53:26 INFO mapred.JobClient: Job complete: job_local_0001
11/06/19 11:53:26 INFO mapred.JobClient: Counters: 12
11/06/19 11:53:26 INFO mapred.JobClient:   FileSystemCounters
11/06/19 11:53:26 INFO mapred.JobClient:     FILE_BYTES_READ=18153346
11/06/19 11:53:26 INFO mapred.JobClient:     FILE_BYTES_WRITTEN=9462349
11/06/19 11:53:26 INFO mapred.JobClient:   Map-Reduce Framework
11/06/19 11:53:26 INFO mapred.JobClient:     Reduce input groups=4
11/06/19 11:53:26 INFO mapred.JobClient:     Combine output records=0
11/06/19 11:53:26 INFO mapred.JobClient:     Map input records=17484
11/06/19 11:53:26 INFO mapred.JobClient:     Reduce shuffle bytes=0
11/06/19 11:53:26 INFO mapred.JobClient:     Reduce output records=4
11/06/19 11:53:26 INFO mapred.JobClient:     Spilled Records=34968
11/06/19 11:53:26 INFO mapred.JobClient:     Map output bytes=142014
11/06/19 11:53:26 INFO mapred.JobClient:     Combine input records=0
11/06/19 11:53:26 INFO mapred.JobClient:     Map output records=17484
11/06/19 11:53:26 INFO mapred.JobClient:     Reduce input records=17484&lt;/pre&gt;W katalogu wynikowym powinien znajdować się także plik part-r-00000 z zawartością:&lt;br /&gt;
&lt;pre&gt;GET 15341
HEAD 1744
POST 398
PUT 1&lt;/pre&gt;&lt;br /&gt;
I mamy gotowe statystyki :-)&lt;br /&gt;
Pełne źródła dostępne są&amp;nbsp;&lt;a href="https://bitbucket.org/lstachowiak/hadoopsamples"&gt;tutaj&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-5665573765648167194?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/dt4lhGvurBU/pierwszy-job-z-hadoop.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-K4K4n7LgVYc/Tf2-HULOJ3I/AAAAAAAAECQ/er6OzwuYfXM/s72-c/MapReduceSample1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2011/06/pierwszy-job-z-hadoop.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-4384746157593420541</guid><pubDate>Sat, 18 Jun 2011 14:37:00 +0000</pubDate><atom:updated>2011-06-18T16:37:25.966+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Poznań-JUG</category><title>Wideo z Poznańskiego Code Retreat</title><description>Trochę czasu minęło od &lt;a href="http://www.jug.poznan.pl/materialy-ze-spotkan/materialy/1-poznanski-code-retreat/"&gt;pierwszego Poznańskiego Code Retreat&lt;/a&gt;, ale parę dni temu pojawił się w sieci krótki filmik z tej imprezy. Wg mnie jest świetny :) Dynamiczny i nawet gdzieś tam mnie widać! Brawa dla autora, którym jest &lt;a href="http://bloggodiscover.wordpress.com/"&gt;Zbigniew Wantuch&lt;/a&gt;!&lt;br /&gt;
&lt;br /&gt;
Zapraszam do obejrzenia:&lt;br /&gt;
&lt;p&gt;&lt;embed src="http://blip.tv/play/AYK_hV0C" type="application/x-shockwave-flash" width="480" height="306" wmode="transparent" allowscriptaccess="always" allowfullscreen="true" &gt;&lt;/embed&gt;&lt;/p&gt;&lt;br /&gt;
Źródło: &lt;a href="http://www.jug.poznan.pl/2011/06/video-z-pierwszego-poznanskiego-code-retreat/"&gt;Poznań JUG&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-4384746157593420541?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/5X1Ghf5088o/wideo-z-poznanskiego-code-retreat.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2011/06/wideo-z-poznanskiego-code-retreat.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-7527622389326194862</guid><pubDate>Wed, 15 Jun 2011 19:14:00 +0000</pubDate><atom:updated>2011-06-15T21:51:12.925+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><category domain="http://www.blogger.com/atom/ns#">Hadoop</category><title>Szybka instalacja Apache Hadoop dzięki dystrybucji Cloudera</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-mR9bdgeq7n8/Tfj5vy6_IhI/AAAAAAAAD_k/aTjxkg2cE3k/s1600/hadoop-logo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-mR9bdgeq7n8/Tfj5vy6_IhI/AAAAAAAAD_k/aTjxkg2cE3k/s1600/hadoop-logo.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;Mając w pamięci trudne doświadczenia z czasów studiów z &lt;a href="http://hadoop.apache.org/"&gt;frameworkiem Hadoop&lt;/a&gt;, postanowiłem wrócić do tematu dzięki &lt;a href="http://ciurana.eu/GeeCON-2011/"&gt;prezentacji Eugiene Ciurana&lt;/a&gt; podczas tegorocznego &lt;a href="http://geecon.org/"&gt;GeeCONa&lt;/a&gt;. Eugienie opowiedział trochę o firmie&amp;nbsp;&lt;a href="http://www.cloudera.com/"&gt;Cloudera&lt;/a&gt;&amp;nbsp;która odwaliła kawał dobrej roboty tworząc i udostępniając dla wszystkich łatwą w instalacji dystrybucję Hadoopa.&lt;br /&gt;
&lt;br /&gt;
Oto jak w szybko zainstalować i uruchomić Hadoop na Ubuntu 11.04:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Dodanie nowego repozytorium&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;sudo touch /etc/apt/sources.list.d/cloudera.list&lt;/pre&gt;I dopisać do zawartości:&lt;br /&gt;
&lt;pre&gt;deb http://archive.cloudera.com/debian lucid-cdh3 contrib
deb-src http://archive.cloudera.com/debian lucid-cdh3 contrib&lt;/pre&gt;(Nie ma jeszcze dostępnej wersji dedykowane dla Natty :-/)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Instalacja!&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;sudo apt-get update
apt-cache search hadoop
sudo apt-get install hadoop-0.20&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;3. Odpalamy przykład :-)&lt;/b&gt;&lt;br /&gt;
&lt;pre&gt;hadoop jar /usr/lib/hadoop-0.20/hadoop-examples.jar pi 10 100&lt;/pre&gt;&lt;br /&gt;
Jeśli wszystko przebiegło poprawnie na końcu powinniśmy otrzymać coś takiego w konsoli:&lt;br /&gt;
&lt;pre&gt;11/06/15 21:09:07 INFO mapred.JobClient: Job complete: job_local_0001
11/06/15 21:09:07 INFO mapred.JobClient: Counters: 14
11/06/15 21:09:07 INFO mapred.JobClient:   FileSystemCounters
11/06/15 21:09:07 INFO mapred.JobClient:     FILE_BYTES_READ=1642249
11/06/15 21:09:07 INFO mapred.JobClient:     FILE_BYTES_WRITTEN=2108417
11/06/15 21:09:07 INFO mapred.JobClient:   Map-Reduce Framework
11/06/15 21:09:07 INFO mapred.JobClient:     Reduce input groups=2
11/06/15 21:09:07 INFO mapred.JobClient:     Combine output records=0
11/06/15 21:09:07 INFO mapred.JobClient:     Map input records=10
11/06/15 21:09:07 INFO mapred.JobClient:     Reduce shuffle bytes=0
11/06/15 21:09:07 INFO mapred.JobClient:     Reduce output records=0
11/06/15 21:09:07 INFO mapred.JobClient:     Spilled Records=40
11/06/15 21:09:07 INFO mapred.JobClient:     Map output bytes=180
11/06/15 21:09:07 INFO mapred.JobClient:     Map input bytes=240
11/06/15 21:09:07 INFO mapred.JobClient:     Combine input records=0
11/06/15 21:09:07 INFO mapred.JobClient:     Map output records=20
11/06/15 21:09:07 INFO mapred.JobClient:     SPLIT_RAW_BYTES=1110
11/06/15 21:09:07 INFO mapred.JobClient:     Reduce input records=20
Job Finished in 2.361 seconds
Estimated value of Pi is 3.14800000000000000000&lt;/pre&gt;&lt;br /&gt;
Oczywiście uruchomiony Hadoop działa w trybie standalone, który idealnie będzie się dla nas nadawać do deweloperskiej zabawy ;-)&lt;br /&gt;
W następnym odcinku trochę pokodzimy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-7527622389326194862?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/URv9-mgIpSU/szybka-instalacja-apache-hadoop-dzieki.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-mR9bdgeq7n8/Tfj5vy6_IhI/AAAAAAAAD_k/aTjxkg2cE3k/s72-c/hadoop-logo.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2011/06/szybka-instalacja-apache-hadoop-dzieki.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-6568164481365822536</guid><pubDate>Wed, 25 May 2011 21:01:00 +0000</pubDate><atom:updated>2011-05-25T23:01:47.862+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">konferencje</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><title>Eclipse DemoCamp Indigo 2011 - Poznań [02.06.2011]</title><description>Za tydzień w Poznaniu kolejne spotkanie z cyklu&lt;b&gt; Eclipse DemoCamp&lt;/b&gt;! Tym razem świętujemy wydanie wersji &lt;b&gt;Indigo.&lt;/b&gt;&lt;br /&gt;
Jak zwykle impreza oprócz charakteru naukowego (prezentacje) będzie miała także aspekt społeczny (dyskusje, piwo i pizza). Co najlepsze dzięki sponsorom piwo i pizza będzie dla uczestników darmowe!&amp;nbsp;Poza tym przewidywane jest do wygrania trochę gadżetów.&lt;br /&gt;
...chyba na tym mógłbym już zakończyć tego newsa, bo już wystarczająco zachęciłem do przyjścia ;)&lt;br /&gt;
&lt;br /&gt;
Poniżej plakat promujący wraz z &lt;b&gt;agendą&lt;/b&gt;:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-s6Dww106DZI/Td1sSVij7PI/AAAAAAAAD_E/HwmyymFi_1I/s1600/eclipse-demo-camp-final-2011.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://1.bp.blogspot.com/-s6Dww106DZI/Td1sSVij7PI/AAAAAAAAD_E/HwmyymFi_1I/s400/eclipse-demo-camp-final-2011.png" width="282" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Miejsce i czas:&lt;/b&gt;&lt;br /&gt;
2 czerwca (czwartek) 2011&lt;br /&gt;
Pub Brogans, ul. Szewska 20a, Poznań&lt;br /&gt;
Start godzina 18:00&lt;br /&gt;
&lt;br /&gt;
Linki:&lt;br /&gt;
&lt;b&gt;Szczegóły&lt;/b&gt;:&amp;nbsp;&lt;a href="http://wiki.eclipse.org/Eclipse_DemoCamps_Indigo_2011/Poznan"&gt;link&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;Rejestracja&lt;/b&gt;:&amp;nbsp;&lt;a href="http://oiola.com/e/732-8-eclipse-democamp-poznan/"&gt;link&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Do zobaczenia!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-6568164481365822536?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/OrrlBtdxRII/eclipse-democamp-indigo-2011-poznan.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-s6Dww106DZI/Td1sSVij7PI/AAAAAAAAD_E/HwmyymFi_1I/s72-c/eclipse-demo-camp-final-2011.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2011/05/eclipse-democamp-indigo-2011-poznan.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-3970219129387496319</guid><pubDate>Wed, 23 Feb 2011 21:40:00 +0000</pubDate><atom:updated>2011-02-24T08:56:57.327+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Spring Framework</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><title>Caching Abstract w Spring Framework 3.1 M1</title><description>Po krótkiej przerwie wracamy do pisania ;)&lt;br /&gt;
Przyszło mi pójść do pracy i trochę blog się zakurzył, ale mam zamiar go systematycznie przecierać ściereczką, żeby raz na jakiś czas coś dało się przeczytać.&lt;br /&gt;
&lt;br /&gt;
Całkiem niedawno SpringSource &lt;a href="http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/"&gt;wydał milestone pierwszy nowego Springa 3.1&lt;/a&gt;. Przeglądając listę zmian napotkałem zupełnie nowy komponent służący do cachowania. Caching Abstract - bo tak został nazwany, jest warstwą abstrakcji (samym API) wspierającym programistę podczas cachowania pobieranych danych z dowolnych źródeł. Z techniczego punktu widzenia (na tę chwilę) zostały wprowadzone dwie nowe adnotacje: &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;@Cacheable&lt;/span&gt; oraz &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;@CacheEvict&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Za pomocją @Cacheable adnotujemy metody których zwracane wartości mają trafiać do cache:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Cacheable("something")
public List&amp;lt;Object&amp;gt; getMeSomething(String param) {
 // ...
}&lt;/pre&gt;Jako parametr podajemy nazwę cache do którego mają trafić wyniki. Kluczem dla zapamiętywanych wyników staje się parametr metody. Jeśli metoda posiada kilka parametrów lub przyjmuje jako taki np jakieś DTO, można wyspecyfikować klucz za pomocą atrybutów,przykłady:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Cacheable(value="magic", key="magicDto.id")
public List&amp;lt;Object&amp;gt; getSomethingMore(MagicDto magicDto) {
 // ..
}&lt;/pre&gt;Dla wielu parametrów:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Cacheable(value="magic", key="param2")
public List&amp;amp;ls;Object&amp;gt; getSomething(String param1, int param2, boolean param3) {
 // ..
}&lt;/pre&gt;Możliwe jest także wykorzystanie dowolnej metody do wyliczenia klucza:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Cacheable(value="magic", key="T(myKeyGenerator).getKey(param2)")
public List&amp;amp;ls;Object&amp;gt; getSomething(String param1, int param2, boolean param3) {
 // ..
}&lt;/pre&gt;Domyślnie Spring korzysta z metody hashCode dla wygenerowania klucza z podanej wartości. Można to zmienić podmieniając implementację klasy &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;org.springframework.cache.KeyGenerator&lt;/span&gt; (więcej w dokumentacji).&lt;br /&gt;
&lt;br /&gt;
Za pomocą atrybutu &lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;condition&lt;/span&gt;&lt;/i&gt; można zdefiniować warunek, kiedy wyniki mają zostać cachowane:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Cacheable(value="something", condition="param.length &amp;gt; 1024")
public List&amp;lt;Object&amp;gt; getSomething(String param) {
 return Collections.emptyList();
}&lt;/pre&gt;Jako wartość można wstawić dla niego dowolne wyrażenie w SpEL które zwróci wartość boolowską.&lt;br /&gt;
&lt;br /&gt;
Jak już uzbieramy trochę obiektów to możemy się ich pozbyć za pomocą&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;@CacheEvict&lt;/span&gt;.&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@CacheEvict(value="magicCache", allEntries=true)
public void clearMyCache(int param1) {
        //...
}&lt;/pre&gt;Jako &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;i&gt;value&lt;/i&gt;&lt;/span&gt; podajemy cache (lub ich wiele) z którego mają zostać usunięte obiekty. Parametr &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;i&gt;allEntries&lt;/i&gt;&lt;/span&gt; jest opcjonalny i służy do usuwania wszystkich przechowywanych obiektów. Jeśli nie zostanie użyty obiekty będą usuwane wg klucza, zasady podobne jak w przypadku &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;@Cacheable&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Tyle szybko jeśli chodzi o API. Aby zacząć go używać trzeba jeszcze zrobić mały update konfiguracji o następującą treść:&lt;pre name="code" class="xml"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;beans xmlns="http://www.springframework.org/schema/beans"
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 &amp;nbsp; xmlns:cache="http://www.springframework.org/schema/cache"
&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 &amp;nbsp; http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"&amp;gt;

 &amp;nbsp; &amp;lt;cache:annotation-driven /&amp;gt;

&amp;lt;/beans&amp;gt;&lt;/pre&gt;Domyślnie w Springa wbudowana jest obsługa dwóch "fizycznych" cache:&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: monospace;"&gt;ConcurrentMap&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&amp;nbsp;oraz &lt;i&gt;ehcache&lt;/i&gt;. Jęsli ktoś używa/potrzebuje czegoś innego musi jak na razie pokusić się o napisanie własnej implementacji.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Aby skorzystać z ehcache we własnej aplikacji trzeba dopisać jeszcze dwie linie:&lt;/span&gt;&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;!-- konfiguracja springowego CacheManagera --&amp;gt;
&amp;lt;bean id="cacheManager" class="org.springframework.cache.ehcache.EhcacheCacheManager" p:cache-manager="ehcache"/&amp;gt;
&amp;lt;!-- konfiguracja ehcache --&amp;gt;
&amp;lt;bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="ehcache.xml"/&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Fajnie, że nareszcie tego typu komponent trafił do Springa. Możliwe będzie cachowanie dowolnych wartości niezależnie czy pobieramy jest przez WebService, bazę danych, z pliku czy czegokolwiek. Posługując się tylko API jednej biblioteki! Nie powinno być także żadnych kolizji jeśli chodzi o cache drugiego poziomu JPA. W tej wersji brakuje mi jeszcze jakiejkolwiek konfiguracji. Nie można (przynajmniej nie znalazłem nigdzie w dokumentacji ani w API) zdefiniować czasu życia dla obiektów w cache co jest kwestią dość podstawową. Ale poczekam jeszcze na wersję finalną....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-3970219129387496319?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/FsOvBUFwovE/caching-abstract-w-spring-framework-31.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>2</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2011/02/caching-abstract-w-spring-framework-31.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-3556794211406412339</guid><pubDate>Mon, 27 Sep 2010 21:51:00 +0000</pubDate><atom:updated>2010-09-27T23:51:43.421+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Oracle Coherence</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><title>Oracle Coherence - tworzenie klastra</title><description>Żeby w pełni wykorzystać możliwości jakie daje Coherence trzeba utworzyć klaster składający się z wielu węzłów. Mogą być one uruchamiane na jednej maszynie lub wielu - zależnie od potrzeb i możliwości sprzętowych.&lt;br /&gt;
&lt;br /&gt;
Zanim przejdę do tego w jaki sposób jest tworzony klaster przypomnijmy sobie co jest wyświetlane podczas uruchamiania węzła w konsoli:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TKD9fAsZl7I/AAAAAAAAD78/-FPIkab2C2c/s1600/coherence_node_start.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="404" src="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TKD9fAsZl7I/AAAAAAAAD78/-FPIkab2C2c/s640/coherence_node_start.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;W pierwszej kolejności konsola wyrzuca informację o używanej wersji Coherence. Później trochę informacji o przyłączaniu węzła do klastra (pierwszy uruchamiany węzeł wyświetla tam informację o tworzonym przez niego klastrze).&lt;br /&gt;
Krótka sekcja &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Group&lt;/span&gt; jest bardzo ważna ponieważ zawiera adres multicastowy, port oraz wartość TTL. Coherence podczas uruchamiania węzła używa tych parametrów aby nawiązać komunikację z innymi uruchomionymi węzłami. Jeśli z jakimś nawiąże komunikację (oraz nie będzie innych konfiguracyjnych problemów) przyłączy się do jego klastra. Adres multicastowy jest ściśle związany z wersją Coherence. W moim przypadku wersją jest 3.6.0, więc adresem jest 224.3.6.0, dla 3.5.1 będzie to 224.3.5.1. Podobny mechanizm zastosowany został także co do numeru portu, tylko tam wykorzystywany jest numer builda. Taka numeracja została użyta aby zapobiec łączeniu węzłów obsługiwanych przez różne wersje Coherence.&lt;br /&gt;
Sekcja &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;MasterMemberSet&lt;/span&gt; zawiera dane o wszystkich węzłach przyłączonych do klastra. W pierwszej kolejności wypisany jest aktualny węzeł oraz węzeł najstarszy (ten który&amp;nbsp;najdłużej&amp;nbsp;znajduje się w klastrze). Następnie wymienione są wszyscy członkowie wraz z adresami sieciowymi i portami na których działają.&lt;br /&gt;
&lt;br /&gt;
Jeśli występuje jakiś problem podczas uruchamiania węzła, to najczęściej jest to problem z mutlicastem. W katalogi &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;/bin/&lt;/span&gt; instalacji jest dostępny skrypt &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;multicast-test&lt;/span&gt; umożliwiający przetestowanie czy mechanizm ten działa prawidłowo na Twojej maszynie.&lt;br /&gt;
Aby uruchomić test tak aby sprawdził działanie na pojedynczej maszynie (najczęstsza konfiguracja podczas tworzenia oprogramowania) można uruchomić skrypt z parametrem&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; -ttl 0&lt;/span&gt;:&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;mutlicast-test -ttl 0&lt;/span&gt;&lt;br /&gt;
Konsola w odpowiedzi zwróci nam jeśli wszystko jest ok:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TKEFjPTLVbI/AAAAAAAAD8A/V_mM-FX6UNs/s1600/coherence_multicast_test.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="187" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TKEFjPTLVbI/AAAAAAAAD8A/V_mM-FX6UNs/s640/coherence_multicast_test.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Jeśli coś jest nie tak to powinno się sprawdzić konfigurację firewalla oraz inne ustawienia sieciowe.&lt;br /&gt;
&lt;br /&gt;
Domyślnie użycie multicastu do odnajdywania innych węzłów może zostać zastąpione poprzez skonfigurowanie konkretnych adresów IP serwerów (w terminologii Coherence: &lt;b&gt;Well Known Addressess - WKA&lt;/b&gt;). Dla ograniczenia klastra tylko do maszyny lokalnej należy w skrypcie &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cache-server&lt;/span&gt; dodać wpis dla parametrów &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;JAVA_OPTS&lt;/span&gt;:&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;-Dtangosol.coherence.wka=localhost&lt;/span&gt;&lt;br /&gt;
Całkowicie wyłączy to multicast, co może być bardzo pożądane w fazie produkcyjnej projektu.&lt;br /&gt;
Po tej operacji zamiast sekcji &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Group&lt;/span&gt; podczas uruchamiania węzła znajdować się będzie sekcja &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;WellKnownAddressesList&lt;/span&gt;, np:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;WellKnownAddressList(Size=1,&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;WKA{Address=192.168.0.2, Port=8088}&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;)&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;Kolejną kwestią podczas tworzenia klastra są porty na których działają węzły. Domyślnie pierwszy węzeł uruchamiany jest na porcie 8088 i jest on zwiększany o 1 dla każdego kolejnego węzła na tej samej maszynie. Jeśli jakaś inna aplikacja zajmuje już dany port możliwe jest skonfigurowanie Coherence aby użył innego numeru jako początkowy poprzez parametr:&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;-Dtangosol.coherence.localport=[numer portu]&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Opcje te mogą być także konfigurowane za pomocą pliku XML, ale o tym już w jednym z następnych odcinków ;-)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-3556794211406412339?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/Eq_BSgRrLbY/oracle-coherence-tworzenie-klastra.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TKD9fAsZl7I/AAAAAAAAD78/-FPIkab2C2c/s72-c/coherence_node_start.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/09/oracle-coherence-tworzenie-klastra.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-5321797950246003093</guid><pubDate>Sat, 11 Sep 2010 17:46:00 +0000</pubDate><atom:updated>2010-09-11T19:46:33.638+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">Oracle Coherence</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Oracle Coherence - działający przykład</title><description>Po &lt;a href="http://blog.lstachowiak.pl/2010/08/oracle-coherence-zabawy-z-in-memory.html"&gt;krótkim wstępie do Oracle Coherence&lt;/a&gt;, czas uruchomić prosty przykład z użyciem Javy. Coherence jest dość duży i wymagane jest wprowadzenie w wiele rzeczy zanim będzie można go sprawnie używać, jednak mam nadzieje, że uda mi się wszystko opisać w miarę kolejnych wpisów. Jak na razie zróbmy sobie prosty przykład bez używania konsoli ;-)&lt;br /&gt;
&lt;br /&gt;
Projekt Javy można utworzyć w dowolnym IDE.Ważne tylko aby dodać do niego bibliotekę &lt;i&gt;coherence.jar&lt;/i&gt; z paczki pobranej ze strony &lt;a href="http://www.oracle.com/technetwork/middleware/coherence/overview/index.html"&gt;Oracle&lt;/a&gt;.&lt;br /&gt;
Zacznijmy od stworzenia klasy która będzie przechowywana w klastrze Coherence. Niech to będzie wałkowany wszędzie pracownik.&lt;br /&gt;
&lt;i&gt;Employee.java&lt;/i&gt;:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;package pl.lstachowiak.coherence.example1;

import java.io.Serializable;
import java.math.BigDecimal;

public class Employee implements Serializable, Comparable {

 private int id;
 private String name;
 private String surname;
 private BigDecimal salary;
 private String city;

 public Employee() {
 }

 public Employee(int id, String name, String surname,
     BigDecimal salary, String city) {
  this.id = id;
  this.name = name;
  this.surname = surname;
  this.salary = salary;
  this.city = city;
 }

 public String getCity() {
  return city;
 }

 public void setCity(String city) {
  this.city = city;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public BigDecimal getSalary() {
  return salary;
 }

 public void setSalary(BigDecimal salary) {
  this.salary = salary;
 }

 public String getSurname() {
  return surname;
 }

 public void setSurname(String surname) {
  this.surname = surname;
 }

 @Override
 public String toString() {
  return "Employee{" + "id=" + id + " name=" + name + " surname="
    + surname + " salary=" + salary + " city=" + city + '}';
 }

 public int compareTo(Object o) {
  Employee other = (Employee) o;
  if (id &amp;gt; other.id) {
   return 1;
  } else if (id &amp;lt; other.id) {
   return -1;
  } else {
   return 0;
  }
 }
}&lt;/pre&gt;Jak widać klasa nie różni się niczym w stosunku to standardowych klas typu POJO. Jedyne co zostało dodane to implementacja interfejsu Serializable, ponieważ obiekt będzie przesyłany przez sieć oraz Comparable, żeby było po czym sortować, gdy będzie to potrzebne.&lt;br /&gt;
Napomnę tutaj, że Coherence wprowadził swój własny format serializacji obiektów. Jest od &amp;nbsp;bardziej wydajny, a obiekty po serializacji mniejsze. Więcej o tym w jednym z kolejnych wpisów.&lt;br /&gt;
&lt;br /&gt;
Operacje na Coherence&amp;nbsp;przeprowadźmy&amp;nbsp;w metodzie main...&lt;br /&gt;
&lt;i&gt;CoherenceExample1.java&lt;/i&gt;:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;package pl.lstachowiak.coherence.example1;

import com.tangosol.net.CacheFactory;
import com.tangosol.net.NamedCache;
import java.math.BigDecimal;
import java.util.Map;
import java.util.Set;

public class CoherenceExample1 {

    public static void main(String[] args) {
  // #1
        NamedCache employees = CacheFactory.getCache("employees");

  // #2
  employees.put(1, new Employee(1, "John", "Travolta", new BigDecimal(300000.0), "New York"));
  employees.put(2, new Employee(2, "Jason", "Statham", new BigDecimal(550000.0), "Chicago"));
  employees.put(3, new Employee(3, "Sylvester", "Stalone", new BigDecimal(600000.0), "Miami"));
  employees.put(4, new Employee(4, "Bruce", "Willis", new BigDecimal(780000.0), "Los Angeles"));
  employees.put(5, new Employee(5, "Chuck", "Norris", new BigDecimal(1300000.0), "Kansas"));
  employees.put(6, new Employee(6, "Steven", "Seagal", new BigDecimal(20100.0), "Lansing"));

  // #3
  System.out.println("Pracownik o ID=1: " + employees.get(1));
  System.out.println("Rozmiar cache: " + employees.size());
  System.out.println("Usuwam: " + employees.remove(5));
  System.out.println("Rozmiar cache: " + employees.size());

  // #4
  Set&amp;lt;Map.Entry&amp;gt; entries = employees.entrySet();
  for (Map.Entry entry : entries) {
   System.out.println(entry.getKey() + ": " + entry.getValue());
  }
    }
}&lt;/pre&gt;#1 - pierwszym co trzeba zrobić to uzyskać referencję do Cache w którym będą przechowywane obiekty pracowników.&amp;nbsp;&lt;a href="http://download.oracle.com/docs/cd/E15357_01/coh.360/e15725/com/tangosol/net/CacheFactory.html"&gt;CacheFactory&lt;/a&gt;&amp;nbsp;odpowiada za jego stworzenie jeśli nie istnieje i zwrócenie referencji. Obiekt zwracany jest typu&amp;nbsp;&lt;a href="http://download.oracle.com/docs/cd/E15357_01/coh.360/e15725/com/tangosol/net/NamedCache.html"&gt;NamedCache&lt;/a&gt;, który implementuje standardowy interfejs Map z biblioteki Javy.&lt;br /&gt;
2# - umieszczanie elementów jest bardzo proste, zwykły put na mapie.&lt;br /&gt;
3# - podobnie wszystkie operacje pobierania oraz usuwania, wszystko bardzo intuicyjne&lt;br /&gt;
4# - można też pobrać całą listę obiektów w cache. Metoda &lt;i&gt;entrySet()&lt;/i&gt;&amp;nbsp;występuję w kilku wersjach, można jest podać także filtr oraz komparator jeśli szukamy odpowiedniego podzbioru obiektów w cache.&lt;br /&gt;
&lt;br /&gt;
Po uruchomieniu powinno nam się pojawić coś podobnego do poniższego ekranu:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_QQi5tGIQ1eA/TIu4Of2WUrI/AAAAAAAAD74/Dr04nCR1ADU/s1600/coherence_example1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="313" src="http://4.bp.blogspot.com/_QQi5tGIQ1eA/TIu4Of2WUrI/AAAAAAAAD74/Dr04nCR1ADU/s640/coherence_example1.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Chciałbym tutaj zwrócić uwagę, że nie napisałem nic o uruchamianiu węzła Coherence przed odpalaniem aplikacji. Pomimo tego wszystko działa! Jest tak ponieważ domyślnie aplikacja którą stworzyliśmy automatycznie staje się pełnoprawnym węzłem w klastrze. Często jest to niepożądane zachowanie i można tego uniknąć poprzez uruchomienie jej z parametrem:&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;-Dtangosol.coherence.distributed.localstorage=false&lt;/span&gt;&lt;br /&gt;
co prawda nadal aplikacja będzie pełnoprawnym węzłem w klastrze, ale nie będzie przechowywać danych;) Wymagany jest wtedy co najmniej jeden węzeł to robiący aby uniknąć wyjątków po uruchomieniu.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-5321797950246003093?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/8pDXLiOCuSU/oracle-coherence-dziaajacy-przykad.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_QQi5tGIQ1eA/TIu4Of2WUrI/AAAAAAAAD74/Dr04nCR1ADU/s72-c/coherence_example1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/09/oracle-coherence-dziaajacy-przykad.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-3743089849587656512</guid><pubDate>Mon, 09 Aug 2010 19:05:00 +0000</pubDate><atom:updated>2010-08-09T21:05:11.454+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Oracle Coherence</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><title>Oracle Coherence - zabawy z in memory data grid</title><description>Obiecałem tematykę o skalowalności w bardziej praktyczny sposób to czas się z tego wywiązać i zacząć pisać! Przy okazji oczywiście samemu się ucząc, bo po to głównie to miejsce powstało.&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Przy okazji GeeCONa&amp;nbsp;podczas University Day&amp;nbsp;w wolnej chwili dosiadłem się na szkolenie Waldemara Kota o Oracle Coherence. To było moje pierwsze zetknięcie z tak zwanym in memory data grid, temat mnie zaciekawił i postanowiłem coś więcej o tym poczytać (przy okazji szkolenia dostałem książkę;)&lt;br /&gt;
Oracle Coherence jest (komercyjnym:-/) narzędziem które w łatwy sposób pozwala nam poprawić skalowalność, wydajność oraz dostępność aplikacji.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TDntbWewOEI/AAAAAAAAD64/IQ29JNaH0Qk/s1600/coherence-grid.png" imageanchor="1"&gt;&lt;img border="0" height="400" src="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TDntbWewOEI/AAAAAAAAD64/IQ29JNaH0Qk/s400/coherence-grid.png" width="393" /&gt;&lt;/a&gt;&lt;/div&gt;Umieszczane jest pomiędzy warstwą danych a aplikacją. Najczęściej między bazą danych a klastrem serwerów aplikacyjnych. Komunikacja między tymi warstwami odbywa się tylko poprzez Coherence (konfigurowalne) co w znacznym stopniu odciąża bazy danych i zwiększa czas odpowiedzi do warstwy aplikacji. Coherence przechowuje takie same obiekty jakie używane są w aplikacji, co eliminuje potrzebę ciągłego ładowania i przetwarzania danych w obiekty. Obiekty te rozprowadzane są pomiędzy węzły w klastrze co równoważy&amp;nbsp;obciążenie&amp;nbsp;przy czym dla aplikacji klaster pozostaje widoczny jako&amp;nbsp;pojedynczy&amp;nbsp;system. Zapewniona jest wysoka dostępność i odporność na&amp;nbsp;błędy&amp;nbsp;poprzez&amp;nbsp;przechowywanie&amp;nbsp;więcej niż jednej kopii danego obiektu w różnych miejscach. Co więcej, przechowywane są w pamięci co w znacznym stopniu poprawia czas dostępu do nich.&lt;br /&gt;
Co możemy robić z Coherence?&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;rozproszony cache - to chyba podstawowe zastosowanie, nie trzeba się martwić o synchronizację, w bardzo łatwy sposób można też podpiąć się pod wybrany ORM&lt;/li&gt;
&lt;li&gt;rozproszone zapytania - dane można wyciągać nie tylko wg nadanego klucza głównego, ale także możliwe jest wykonywania zapytań na klastrze. Np wybrać klientów powyżej 35 lat, którzy dodatkową posiadają kwotę na koncie pomiędzy 4000 a 6000 PLN&lt;/li&gt;
&lt;li&gt;współbieżne operacje i procedury składowane - podobnie jak w bazach danych możliwe jest tworzenie procedur i wykonywanie ich wewnątrz klastra, bez potrzeby przesyłania wszystkich danych do aplikacji. Co więcej możliwe jest też wykonywania operacji współbieżnie&lt;/li&gt;
&lt;li&gt;zdarzenia - możliwe jest skonfigurowanie Coherence tak by informował i wykonywał podane operacje gdy wybrane dane zostały zmienione&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Teraz możemy przejść do zabawy :)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;Ze strony &lt;a href="http://www.oracle.com/technetwork/middleware/coherence/downloads/index.html"&gt;Oracle Coherence Download&lt;/a&gt;&amp;nbsp;pobieramy paczkę "&lt;i&gt;Oracle Coherence for Java Version 3.6.0&lt;/i&gt;" i rozpakowujemy gdzie nam pasuje. Następnie uruchamiamy konsolę, przechodzimy do katalogu &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;coherence/bin&lt;/span&gt; i uruchamiamy skrypt &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cache-server&lt;/span&gt;. Po chwili powinien pojawić się napis "&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Started DefaultCacheServer...&lt;/span&gt;" - oznacza to, że węzeł Coherence został uruchomiony.&lt;br /&gt;
Ponieważ dzisiaj jest tylko takie małe wprowadzanie, nie będziemy używać Javy tylko wbudowanej konsoli, na początek starczy. Uruchamiamy skrypt &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;coherence&lt;/span&gt;. Na konsoli uruchomionego wcześniej węzła powinno na końcu pojawić się coś w stylu: "&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;2010-08-09 20:34:43.552/180.953 Oracle Coherence GE 3.6.0.0 &amp;lt;D5&amp;gt; (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1&lt;/span&gt;". Oznacza to, że konsola podłączyła się pod węzeł.&lt;br /&gt;
Korzystając z Coherence należy najpierw utworzyć cache w którym będą przechowywane będą obiekty. Można tworzyć ich wiele oraz (co trochę później) konfigurować zgodnie z wymaganiami. Z konsoli utworzenie cache wykonuje się poleceniem: &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;cache [nazwa]&lt;/span&gt;. Po utworzeniu jesteśmy automatycznie do niego podłączani. Co jest bardzo fajne - API korzystania z cache jest identyczne ze standardową mapą Javową. Aby coś włożyć do cache używamy &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;put [klucz] [wartosc]&lt;/span&gt;, aby wyciągnąć &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;get [klucz]&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;, aby wyp&lt;/span&gt;isać całą zawartość cache należy wpisać &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;list&lt;/span&gt;. Poniżej zamieszczam bardzo prostą sesję z użyciem Coherence:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_QQi5tGIQ1eA/TGBNofsJvVI/AAAAAAAAD7Q/cr_YSHF-Ooo/s1600/coherence_console_session.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://4.bp.blogspot.com/_QQi5tGIQ1eA/TGBNofsJvVI/AAAAAAAAD7Q/cr_YSHF-Ooo/s400/coherence_console_session.png" width="313" /&gt;&lt;/a&gt;&lt;/div&gt;To tyle słowem wstępu. Polecam pobawić się konsolą. Uruchomić nawet więcej niż jedną oraz więcej węzłów i sprawdzić jak to działa. Polecam testy z zamykaniem kolejno węzłów i sprawdzaniem czy jakieś obiekty straciliśmy.&lt;br /&gt;
&lt;br /&gt;
Więcej o tym jak Coherence działa i jak go używać w następnych odcinkach ;)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-3743089849587656512?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/MxMauI61S1w/oracle-coherence-zabawy-z-in-memory.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TDntbWewOEI/AAAAAAAAD64/IQ29JNaH0Qk/s72-c/coherence-grid.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/08/oracle-coherence-zabawy-z-in-memory.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-4654276380041251285</guid><pubDate>Thu, 08 Jul 2010 16:15:00 +0000</pubDate><atom:updated>2010-07-08T18:15:38.618+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">geecon</category><title>GeeCON 2011 - Kraków!</title><description>Na oficjalnej stronie &lt;a href="http://www.geecon.org/"&gt;GeeCONa&lt;/a&gt; pojawiła się informacja, że przyszłoroczna edycja konferencji odbędzie się w &lt;b&gt;Krakowie!&lt;/b&gt;&amp;nbsp;Wybrana data to 11 do 13 maja, więc podobny termin jak w tym i poprzednim roku.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TDX4mTC2UUI/AAAAAAAAD60/BJxTeK04Lyc/s1600/geecon-cracov-2011.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TDX4mTC2UUI/AAAAAAAAD60/BJxTeK04Lyc/s1600/geecon-cracov-2011.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Już teraz zapraszam serdecznie, bo znowu będzie baaaaardzo ciekawie :)&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;ps. to chyba pierwszy news w sieci o GeeCONie 2011 :)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-4654276380041251285?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/HRdHyPSDn48/geecon-2011-krakow.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TDX4mTC2UUI/AAAAAAAAD60/BJxTeK04Lyc/s72-c/geecon-cracov-2011.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/07/geecon-2011-krakow.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-8711129638219902595</guid><pubDate>Sun, 13 Jun 2010 08:11:00 +0000</pubDate><atom:updated>2010-06-13T10:11:00.670+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JMeter</category><category domain="http://www.blogger.com/atom/ns#">testy wydajnościowe</category><title>JMeter - losowe wartości w żądaniach/zapytaniach</title><description>Często zdarza się, że chcemy wywoływać strony z parametrami które mieszczą się w jakimś przedziale liczbowym, np. productView.php?id=XXX, gdzie XXX jest zmienną. W JMeter generowanie losowych wartości jest bardzo proste.&lt;br /&gt;
Dodajemy do planu testów &lt;i&gt;Thread Group&lt;/i&gt; a następnie do niego &lt;i&gt;Config Elements -&amp;gt; HTTP Request Defaults&lt;/i&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSKxH6qX4I/AAAAAAAAD6Y/pEBH9j-JK38/s1600/rand_httpdefaults.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="260" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSKxH6qX4I/AAAAAAAAD6Y/pEBH9j-JK38/s400/rand_httpdefaults.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Wpisujemy nazwę serwera oraz port na którym nasłuchuje.&lt;br /&gt;
Następnie dodajemy element odpowiedzialny za generowanie losowej liczby &lt;i&gt;Config Element -&amp;gt; Random Variable&lt;/i&gt;. Najważniejsze parametry jakie możemy dla niego ustawić to:&lt;br /&gt;
Name: nazwa elementu w drzewku&lt;br /&gt;
Variable name: nazwa po której będziemy się odwoływać do tej zmiennej&lt;br /&gt;
Output format: format w jakim ma być zwracana wartość. Można wpisać np. PROD_ID_000 wtedy będziemy otrzymywać wartości typu PROD_ID_435. Gdy pozostawi się to pole puste to będzie zwracana tylko liczba.&lt;br /&gt;
Minimum Value i Maximum Value jest chyba oczywiste&lt;br /&gt;
Per Thread(User)?: czy ten generator liczb ma być współdzielony między wszystkie wątki czy dla każdego utworzony osobny&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSOR8iS-hI/AAAAAAAAD6c/v3c0XSpYUr8/s1600/rand_randvariable.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="176" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSOR8iS-hI/AAAAAAAAD6c/v3c0XSpYUr8/s400/rand_randvariable.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Użycie jest bardzo proste. Wystarczy utworzyć nowe żądanie &lt;i&gt;Sampler -&amp;gt; HTTP Request&lt;/i&gt;&amp;nbsp;i odwołać się do losowej zmiennej poprzez &lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;${[&lt;/span&gt;&lt;i&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;Nazwa zmiennej]&lt;/span&gt;&lt;/i&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TBSPPJhbfmI/AAAAAAAAD6g/4I4SrqJXY6I/s1600/rand_request.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="336" src="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TBSPPJhbfmI/AAAAAAAAD6g/4I4SrqJXY6I/s400/rand_request.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Dla podanego na obrazku przykładu będą wywoływane adresy &lt;i&gt;localhost/jmeter/index.php?id=XXX&lt;/i&gt;, gdzie XXX jest zmienną losową.&lt;br /&gt;
Podobnie może ta zmienna być użyta w zapytaniach do bazy danych:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TBSRtRmW5UI/AAAAAAAAD6k/P3DDQ6aldVQ/s1600/rand_jdbcrequest.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="202" src="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TBSRtRmW5UI/AAAAAAAAD6k/P3DDQ6aldVQ/s400/rand_jdbcrequest.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;I w wielu innych miejscach gdzie potrzebna jest losowa wartość ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-8711129638219902595?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/kdo9JwwpB3M/jmeter-losowe-wartosci-w.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSKxH6qX4I/AAAAAAAAD6Y/pEBH9j-JK38/s72-c/rand_httpdefaults.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/06/jmeter-losowe-wartosci-w.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-8683902975525511695</guid><pubDate>Mon, 31 May 2010 15:31:00 +0000</pubDate><atom:updated>2010-05-31T17:46:48.239+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bazy danych</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><category domain="http://www.blogger.com/atom/ns#">db2</category><title>O skalowaniu baz danych słów kilka</title><description>Część druga o skalowalności. Dzisiaj trochę o bazach danych które sprawiają zawsze najwięcej problemów.&lt;br /&gt;
&lt;br /&gt;
Ze względu na naturę baz danych, to co najbardziej obrywa na serwerze to dyski. Wszelkie zmiany muszą być jak najszybciej utrwalane żeby można było zwolnić blokady i zapewnić trwałość danych. Obojętnie jaki wypas serwer by się nie posiadało i tak&amp;nbsp;w końcu&amp;nbsp;dojdzie do tego, że nie będzie już posiadał możliwości by przyjąć więcej obciążenia, a nas nie będzie stać na zakup lepszego. Trzeba będzie się przeskalować w poziomie co jest trochę hardcorowe :)&lt;br /&gt;
&lt;br /&gt;
Podejść jest kilka i chciałem omówić 3 najważniejsze z nich.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Master-Slave replication&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAPGQk2yo-I/AAAAAAAAD6A/bJG5Rmz4k2I/s1600/Master-slavereplication-schemat.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="197" src="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAPGQk2yo-I/AAAAAAAAD6A/bJG5Rmz4k2I/s400/Master-slavereplication-schemat.png" width="400" /&gt;&lt;/a&gt;W tym podejściu mamy jeden węzeł typu master oraz jeden lub więcej węzłów typu slave. Zadaniem węzła master jest tylko i wyłącznie przyjmowanie operacji modyfikacji danych. Ten serwer odpowiada za wszystkie zapytania typu INSERT, UPDATE i DELETE. Jest do tego specjalnie skonfigurowany by operacje te były jak najszybciej wykonywane. Węzły typu slave natomiast odpowiadają za wykonywanie zapytań typu SELECT. Może być ich kilka oczywiście. Aktualizują swoje dane poprzez asynchroniczną komunikację z węzłem master. Co określony czas przesyła on zgrupowane zapytania aktualizujące dane na węzłach slave.&lt;br /&gt;
Problemy związane z master-slave replication to:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;na dobrą sprawę to nie ma tutaj skalowania poziomego. Co prawda mamy więcej węzłów, ale ciągle istnieje tylko jeden master, który może stać się wąskim gardłem, gdy liczba modyfikacji które musi wykonać przekroczy jego możliwości&lt;/li&gt;
&lt;li&gt;synchronizacja aktualizowanych danych może powodować błędy. Jeśli klient coś zmodyfikuje i natychmiast to będzie chciał odczytać to może otrzymać błędne dane. To jednak można obejść stosując cache z polityką write-through&lt;/li&gt;
&lt;li&gt;wymagana jest modyfikacja logiki aplikacji aby kierować SELECTy do slave, a modyfikacje do master&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Podejście jest bardzo dobre, gdy mamy mało modyfikacji i dużo zapytań.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;b&gt;2. Database clustering&amp;nbsp;&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_QQi5tGIQ1eA/TAPGVF1FxbI/AAAAAAAAD6I/7IbUTCxTEII/s1600/Databaseclustering-schemat.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="323" src="http://4.bp.blogspot.com/_QQi5tGIQ1eA/TAPGVF1FxbI/AAAAAAAAD6I/7IbUTCxTEII/s400/Databaseclustering-schemat.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Klastrowanie bazy danych polega na utworzeniu wielu instancji bazy danych współdzielących jedną wspólną pamięć trwałą. Daje to dużo większą przepustowość i nie wymaga prawie zmian w logice aplikacji.&lt;br /&gt;
Jednak posiada też wady:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;SAN jest drogi i też ma swoje granice&lt;/li&gt;
&lt;li&gt;wymagana jest kosztowna synchronizacja między wszystkimi węzłami (blokady itp.). Może nawet dojść do momentu, gdy dodanie nowego węzła spowolni działanie całości&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;b&gt;3. Database sharding&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TAPGTcQ7GHI/AAAAAAAAD6E/k2YupGvnz1U/s1600/Databasesharding-schemat.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="211" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/TAPGTcQ7GHI/AAAAAAAAD6E/k2YupGvnz1U/s320/Databasesharding-schemat.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Bazę danych można też podzielić na wiele mniejszych baz i tak z nich korzystać. Najpierw należy przeanalizować dokładnie sposób jej używania a później znaleźć grupy tabel które są używane razem w zapytaniach. Na tej podstawie można dzielić ją na mniejsze.&lt;br /&gt;
Problemy:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;trzeba bardzo dobrze przemyśleć podział, każda późniejsza zmiana jest bardzo trudna do wprowadzenia&lt;/li&gt;
&lt;li&gt;gdy jedna z mniejszych baz zacznie działać niewydajnie trzeba będzie ją znowu dzielić. Może dojść do tego, że trzeba będzie mięć np. 3 bazy danych z produktami&lt;/li&gt;
&lt;li&gt;zapytania łączące z wielu baz są bardzo wolne&lt;/li&gt;
&lt;li&gt;zapytania modyfikujące wymagają rozproszonych transakcji&lt;/li&gt;
&lt;li&gt;wymaga znacznych zmian w logice aplikacji&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;To są tylko koncepcje, firmy w swoich produktach (tych "dużych" głównie) wprowadziły technologie, które ułatwiają skalowanie poziome. Np. w DB2 mamy &lt;a href="http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/c0021803.htm"&gt;Database Partitioning Feature&lt;/a&gt;, który jest połączeniem podejść database sharding i clustering i eliminuje kilka wad z nimi związanymi.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Problem jest jednak bardzo złożony i wymaga długich przemyśleń. Trzeba zawsze pamiętać aby wdrożone rozwiązanie spełniało wymagania &lt;a href="http://en.wikipedia.org/wiki/ACID"&gt;ACID&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-8683902975525511695?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/nt7t1wJXJX8/o-skalowaniu-baz-danych-sow-kilka.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAPGQk2yo-I/AAAAAAAAD6A/bJG5Rmz4k2I/s72-c/Master-slavereplication-schemat.png" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/05/o-skalowaniu-baz-danych-sow-kilka.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-426893044918407688</guid><pubDate>Sun, 30 May 2010 19:00:00 +0000</pubDate><atom:updated>2010-05-30T21:00:38.133+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><title>O skalowaniu aplikacji słów kilka</title><description>W niedługim czasie zamierzam trochę szerzej pisać o skalowalności, więc postanowiłem napisać kilka słów wstępnych na ten temat. Ale spokojnie, planuję bardziej o produktach i narzędziach niż teoriach jak dzisiaj;)&lt;br /&gt;
&lt;br /&gt;
Żeby później nie mylić trzeba sobie zdefiniować skalowalność. Jest to taka cecha oprogramowania która charakteryzuje jego zdolności do wydajnego działania przy wzrastającym obciążeniu. Np. załóżmy, że mamy super serwis randkowy który ma 1000 użytkowników i generuje strony w 50ms. Po jakimś czasie serwis robi się popularny i przychodzi do niego kolejnych 1000 użytkowników. Byłoby dobrze jakby strony generowały się w powiedzmy w czasie 100-200ms, ale generują się w 5000ms co niestety wskazuje na jego słabą skalowalność. Oczywiście ze wzrostem obciążenia zbliżamy się do limitu jaki może uciągnąć serwer, więc decydujemy się na wymianę starego ,zasłużonego na nowy, dwa razy lepszy. To jak aplikacja będzie się spisywać na nowym serwerze też określa jej skalowalność. Jeśli nadal strony będą się generować powoli przy takim obciążeniu to znaczy, że coś skopaliśmy przy implementacji, jeśli jest znowu fajnie i 50ms to znaczy, że aplikacja daje rade;) Podsumowując skalowalność to także łatwość w rozszerzaniu aplikacji lub jej architektury celem zwiększania wydajności.&lt;br /&gt;
&lt;br /&gt;
Są dwa podstawowe podejścia co do skalowania aplikacji: pionowe (scaling up) oraz poziome (scaling out).&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TAKY_hLmF6I/AAAAAAAAD5w/4c5_fowhDPc/s1600/Skalowanepionowe-schemat.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="307" src="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TAKY_hLmF6I/AAAAAAAAD5w/4c5_fowhDPc/s400/Skalowanepionowe-schemat.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;Podejście pionowe to po prostu wymiana lub dodawanie coraz to nowszego i szybszego sprzętu. Jak 12GB RAMu to już mało to dodajemy kolejne 12. Jak procesor nie wyrabia - dodajemy drugi itd. Sprawa jest niezwykle prosta i nie wymaga od nas w większości przypadków ingerencji w aplikację. Jednak posiada wady:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;koszty - zakup coraz to lepszego sprzętu odbija się na budżecie i gdy po raz kolejny przyjdzie nam wymienić serwer może się okazać, że nas na niego nie stać, lub zyski z tej wymiany mogą być znacznie mniejsze niż poniesione koszty&lt;/li&gt;
&lt;li&gt;bariera technologiczna - nawet jeśli mamy tyle kasy, że nas stać na każdy sprzęt na rynku to i tak w końcu dojdziemy do miejsca kiedy już nie będziemy mogli kupić lepszego sprzętu, bo po prostu nie on będzie istnieć&lt;/li&gt;
&lt;li&gt;niska odporność na awarie, jak serwer padnie to system znika z sieci&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Dlatego skalowanie pionowe jest dobre&amp;nbsp;do czasu, gdy wymiana sprzętu na lepszy się jeszcze opłaca, lub gdy wiemy jaka jest górna granica wydajności jaką potrzebuje aplikacja.&lt;/div&gt;&lt;div&gt;Podejście poziome to też dodawanie nowego sprzętu, ale tym razem powiększamy jego zbiór dodając go do sieci istniejących już maszyn działających ku dobru systemu. Gdy obciążenie rośnie to dostawiamy kolejny serwer który przejmuje część zadań. Potrzebny jest nam jakiś mechanizm równoważenia obciążenia (load balancer), który będzie rozkładać równo żądania do wszystkich serwerów.&amp;nbsp;&lt;/div&gt;&lt;div&gt;Oczywiście to podejście też posiada swoje wady:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;wyższe koszty administracji i konserwacji sprzetu&lt;/li&gt;
&lt;li&gt;trzeba (bardzo) dobrze przemyśleć architekturę (zwłaszcza w kwestii bazy danych)&lt;/li&gt;
&lt;li&gt;dodanie nowego węzła wcale nie musi przynieść wzrostu wydajności, możemy nawet zanotować spadek&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;No, ale mamy znacznie większą odporność na błędy. Jak jeden serwer padnie to mamy jeszcze kilka innych które po prostu przejmują jego ruch. Sprawa odporności na awarie to trochę inny wątek, więc może innym razem coś o tym napiszę.&lt;/div&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAKbhTCMe1I/AAAAAAAAD54/V66PtaGgScA/s1600/Skalowaniepoziome-schemat.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="231" src="http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAKbhTCMe1I/AAAAAAAAD54/V66PtaGgScA/s400/Skalowaniepoziome-schemat.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Skalowanie poziome po jakimś czasie jest naturalnym krokiem przy rozwoju systemu. Przynosi lepsze rezultaty i&amp;nbsp;przy dobrej architekturze może nam dać teoretycznie nieograniczoną skalowalność.&amp;nbsp;Poza tym trudno sobie wyobrazić by np. Google działał na jednym serwerze :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Dodawanie lub wymiana sprzętu to nie jedyna droga by przyspieszyć aplikację. W pierwszej kolejności powinna być wykonana dokładna analiza wszystkich komponentów czy możliwa jest ich optymalizacja. Wymaga to trochę czasu, ale przynosi rezultaty. Np. digg.com &lt;a href="http://highscalability.com/blog/2010/3/23/digg-4000-performance-increase-by-sorting-in-php-rather-than.html"&gt;zyskał 4000%, gdy przeniósł sortowanie z bazy danych do php&lt;/a&gt;. Optymalizacja to niestety niekończąca się podróż :)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Zainteresowanych tematem zachęcam do zaglądania do serwisu&amp;nbsp;&lt;a href="http://highscalability.com/"&gt;highscalability.com&lt;/a&gt;, gdzie można poczytać dużo artykułów od strony praktycznej. Ja postaram się też ciągnąć temat u siebie, bo jest o czym pisać ;)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-426893044918407688?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/K9rWmFA8vxU/o-skalowaniu-aplikacji-sow-kilka.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_QQi5tGIQ1eA/TAKY_hLmF6I/AAAAAAAAD5w/4c5_fowhDPc/s72-c/Skalowanepionowe-schemat.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/05/o-skalowaniu-aplikacji-sow-kilka.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-6643427094078511524</guid><pubDate>Tue, 25 May 2010 09:07:00 +0000</pubDate><atom:updated>2010-05-29T11:37:52.705+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JavaFX</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Dziwny wyjątek podczas uruchamiania skryptu JavaFX</title><description>Wczoraj w zamian za to, że nie mogłem pojawić się na &lt;a href="http://blog.lstachowiak.pl/2010/05/spotkanie-poznan-jug-processing.html"&gt;Poznańskim JUGu&lt;/a&gt;&amp;nbsp;(trochę się przeziębiłem),&amp;nbsp;zabrałem się za JavaFX. Bardzo mało o tym widzę na (Polskich) blogach, więc stwierdziłem, że może coś poczytam i może coś też popiszę u siebie. Niestety pierwsze wrażenie nie było zbyt miłe :P Przyszło mi walczyć kilka godzin z wyjątkiem który wyglądał jak błąd implementacji czegoś w JavaFX.&lt;br /&gt;
Plan był taki aby wziąć jeden z przykładów na stronie&amp;nbsp;&lt;a href="http://javafx.com/"&gt;JavaFX.com&lt;/a&gt;, zmodyfikować i zobaczyć co z tego wyjdzie. Jako środowiska użyłem oczywiście NetBeans IDE w wersji 6.8.&lt;br /&gt;
Na komputerze lokalnym mój&amp;nbsp;piękny&amp;nbsp;skrypt działał bez zarzutów (uruchamiałem w trybie run in browser), to samo na serwerze.... do czasu aż nie wyłączyłem NetBeans! Kiedy był wyłączony otrzymywałem w consoli javy taki wyjątek:&lt;br /&gt;
&lt;pre&gt;java.lang.NullPointerException
at sun.plugin2.applet.JNLP2Manager.initialize(Unknown Source)
at sun.plugin2.main.client.PluginMain.initManager(Unknown Source)
at sun.plugin2.main.client.PluginMain.access$300(Unknown Source)
at sun.plugin2.main.client.PluginMain$2.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Error while initializing manager: java.lang.NullPointerException, bail out&lt;/pre&gt;Ten problem występował także na moim laptopie i u znajomych. No to się zaczęło wielkie googlowanie i podmiany SDK/JDK na wszystkie możliwe wersje łącznie z instalacją bety NetBeans 6.9 (swoją drogą zapowiada się bardzo ciekawie!). Nic nie pomogło, nic się nie zmieniło :-/ Ostatecznie poległem i napisałem na forum NetBeans z prośbą o pomoc jakoś przed północą. Do rana nikt nie odpisał, ale dziś gdy wstałem wyjątek już był inny. Konsola zgłaszała, że brakuje pliku xxx_browser.jnlp który na 100% znajduje się zaraz obok JARa. Podejrzałem ten plik, a tam ujrzałem bardzo ładny i krótki XML:&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;jnlp spec="1.0+" codebase="http://localhost:8082/servlet/org.netbeans.modules.javafx.project.JnlpDownloadServlet/I%3A/workspace/NetBeans/WebSiteJavaFx/dist/" href="website_browser.jnlp"&amp;gt;
    &amp;lt;information&amp;gt;
        &amp;lt;title&amp;gt;website&amp;lt;/title&amp;gt;
        &amp;lt;vendor&amp;gt;wookasz&amp;lt;/vendor&amp;gt;
        &amp;lt;homepage href="http://localhost:8082/servlet/org.netbeans.modules.javafx.project.JnlpDownloadServlet/I%3A/workspace/NetBeans/WebSiteJavaFx/dist/"/&amp;gt;
        &amp;lt;description&amp;gt;website&amp;lt;/description&amp;gt;
        &amp;lt;offline-allowed/&amp;gt;
    &amp;lt;/information&amp;gt;
    &amp;lt;resources&amp;gt;
        &amp;lt;j2se version="1.5+"/&amp;gt;
        &amp;lt;extension name="JavaFX Runtime" href="http://dl.javafx.com/1.3/javafx-rt.jnlp"/&amp;gt;
        &amp;lt;jar href="website.jar" main="true"/&amp;gt;
    &amp;lt;/resources&amp;gt;
    &amp;lt;applet-desc name="website" main-class="com.sun.javafx.runtime.adapter.Applet" width="700" height="500"&amp;gt;
        &amp;lt;param name="MainJavaFXScript" value="pl.lstachowiak.javafx.website.WebSite"/&amp;gt;
    &amp;lt;/applet-desc&amp;gt;
    &amp;lt;update check="always"/&amp;gt;
&amp;lt;/jnlp&amp;gt;&lt;/pre&gt;No jak widać dwie ścieżki coś nie takie jakie powinny być. Podmieniłem na http://lstachowiak.pl i vuala! Działa!:)&amp;nbsp;plik ostatecznie wygląda następująco:&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;jnlp spec="1.0+" codebase="http://lstachowiak.pl/" href="website_browser.jnlp"&amp;gt;
    &amp;lt;information&amp;gt;
        &amp;lt;title&amp;gt;website&amp;lt;/title&amp;gt;
        &amp;lt;vendor&amp;gt;wookasz&amp;lt;/vendor&amp;gt;
        &amp;lt;homepage href="http://lstachowiak.pl/"/&amp;gt;
        &amp;lt;description&amp;gt;website&amp;lt;/description&amp;gt;
        &amp;lt;offline-allowed/&amp;gt;
    &amp;lt;/information&amp;gt;
    &amp;lt;resources&amp;gt;
        &amp;lt;j2se version="1.5+"/&amp;gt;
        &amp;lt;extension name="JavaFX Runtime" href="http://dl.javafx.com/1.3/javafx-rt.jnlp"/&amp;gt;
        &amp;lt;jar href="website.jar" main="true"/&amp;gt;
    &amp;lt;/resources&amp;gt;
    &amp;lt;applet-desc name="website" main-class="com.sun.javafx.runtime.adapter.Applet" width="700" height="500"&amp;gt;
        &amp;lt;param name="MainJavaFXScript" value="pl.lstachowiak.javafx.website.WebSite"/&amp;gt;
    &amp;lt;/applet-desc&amp;gt;
    &amp;lt;update check="always"/&amp;gt;
&amp;lt;/jnlp&amp;gt;&lt;/pre&gt;Szkoda, że nigdzie nie wyczytałem wcześniej, że ten plik jest plikiem tekstowym. Z pewnością zajrzałbym tam na początku i oszczędziłoby mi to trochę czasu i nerwów.&lt;br /&gt;
Zapraszam na&amp;nbsp;&lt;a href="http://lstachowiak.pl/"&gt;lstachowiak.pl&lt;/a&gt;, co prawda nie jest to dzieło sztuki, ale zawsze jakieś początki ;-)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;UPDATE:&lt;/b&gt;&lt;br /&gt;
A jednak ciągle nie działa :-/ Nie rozumiem tego zupełnie. Będę rozwijać wątek jak do czegoś dojdę. Może ktoś ma&amp;nbsp;jakieś&amp;nbsp;sugestie ?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;UPDATE2:&lt;/b&gt;&lt;br /&gt;
Dzięki bardzo Krzysztofowi Kula :) Skompilowałem za pomocą eclipsowej wtyczki i zaczęło działać.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-6643427094078511524?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/oqGsuX_52Sc/dziwny-wyjatek-podczas-uruchamiania.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>3</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/05/dziwny-wyjatek-podczas-uruchamiania.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-1834293976522957269</guid><pubDate>Thu, 20 May 2010 21:16:00 +0000</pubDate><atom:updated>2010-05-20T23:45:28.928+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Poznań-JUG</category><title>Spotkanie Poznań JUG - Processing [24.05.2010]</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lstachowiak.pl/poznan-jug/poznan_jug_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://lstachowiak.pl/poznan-jug/poznan_jug_logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;Znowu info z Poznania :) Kolejne spotkanie się szykuje! W najbliższy poniedziałek posłuchamy o &lt;a href="http://pl.wikipedia.org/wiki/Processing"&gt;Processing&lt;/a&gt;&amp;nbsp;-środowisku do tworzenia sztuki elektronicznej. Zapowiada się bardzo widowiskowo:) Oto krótkie streszczenie od prelegenta Marcina Ignaca:&lt;br /&gt;
&lt;blockquote&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; color: #555555; font-family: Arial, sans-serif; font-size: 12px; font-style: italic; line-height: 16px;"&gt;Przedstawie swoje doświadczenia z pracy ze środowiskiem Processing. Prezentacje rozpoczne krótkim wyjaśnienie czym jest Processing oraz wprowadzeniem do sposobu pracy z tym środowiskiem. W dalszej części spotkania możecie się spodziewać projektów z obszarów grafiki generatywnej, przez interaktywne instalacje aż do multimedialnych projekcji w przestrzeni publicznej. Od fazy konceptualnej przez prototypowanie aż do finalnego produktu – Processing sprawdza się na każdym kroku. Opowiem również o wadach i zaletach tego narzędzia, a także jak “szkicowanie w kodzie” (sketching in software) zmieniło moje podejście do programowania.&lt;/span&gt;&lt;/blockquote&gt;Aby zapoznać wstępnie z tematem zapraszam na stronę prelegenta pod &lt;a href="http://marcinignac.com/blog/tag/processingorg/"&gt;tag processing.org&lt;/a&gt;.&lt;br /&gt;
To mi się bardzo spodobało:&lt;br /&gt;
&lt;object height="300" width="400"&gt;&lt;param name="allowfullscreen" value="true" /&gt;&lt;param name="allowscriptaccess" value="always" /&gt;&lt;param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=4842407&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" /&gt;&lt;embed src="http://vimeo.com/moogaloop.swf?clip_id=4842407&amp;amp;server=vimeo.com&amp;amp;show_title=1&amp;amp;show_byline=1&amp;amp;show_portrait=0&amp;amp;color=&amp;amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;
&lt;a href="http://vimeo.com/4842407"&gt;MSAFluid with motion tracking&lt;/a&gt; from &lt;a href="http://vimeo.com/marcinignac"&gt;Marcin Ignac&lt;/a&gt; on &lt;a href="http://vimeo.com/"&gt;Vimeo&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Nie muszę już raczej nikogo namawiać aby się zjawić! ;)&lt;br /&gt;
&lt;br /&gt;
Szczegóły:&lt;br /&gt;
&lt;b&gt;Poniedziałek&amp;nbsp;&lt;/b&gt;24.05.2010&lt;br /&gt;
Siedziba Cognifide - Aleje Wielkopolskie 4, Poznań&lt;br /&gt;
Godzina 18:00&lt;br /&gt;
Na spotkanie wymagana jest&amp;nbsp;&lt;b&gt;&lt;a href="http://oiola.com/e/606-spotkanie-poznan-jug-processing-24052010/reg/"&gt;rejestracja&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Do zobaczenia !&lt;br /&gt;
&lt;br /&gt;
ps. ostatnio u mnie czysto informacyjne, ale postaram się niedługo to nadrobić ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-1834293976522957269?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/x3H3EzE9gWM/spotkanie-poznan-jug-processing.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/05/spotkanie-poznan-jug-processing.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-1217408279671750478</guid><pubDate>Sun, 16 May 2010 20:02:00 +0000</pubDate><atom:updated>2010-05-16T22:02:02.174+02:00</atom:updated><title>Zmiana adresu bloga na blog.lstachowiak.pl</title><description>Drobny post informacyjny. Jutro zmieniam adres bloga na &lt;a href="http://blog.lstachowiak.pl/"&gt;blog.lstachowiak.pl&lt;/a&gt;&amp;nbsp;Nie wiem jak to się odbije na dostępie do niego ze starego adresu (Google twierdzi, że powinno być spoko) oraz RSS (to też podobno) dlatego jeśli byłyby jakieś problemy to proszę tylko zupdatować sobie adres.&lt;br /&gt;
&lt;br /&gt;
ps. testy wypadły poprawnie ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-1217408279671750478?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/XxP0g6iZvJY/zmiana-adresu-bloga-na.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/05/zmiana-adresu-bloga-na.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-462737364038633875</guid><pubDate>Tue, 11 May 2010 10:49:00 +0000</pubDate><atom:updated>2010-05-11T12:58:13.163+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">konferencje</category><category domain="http://www.blogger.com/atom/ns#">eclipse</category><title>Eclipse DemoCamp Helios 2010 - Poznań [10.06.2010]</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://wiki.eclipse.org/images/8/89/Eclipse-camp.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://wiki.eclipse.org/images/8/89/Eclipse-camp.gif" /&gt;&lt;/a&gt;&lt;/div&gt;Dużo się dzieje ostatnio w Poznaniu! Bardzo dużo! &lt;a href="http://wookasz.blogspot.com/2010/05/geecon-juz-w-poznaniu.html"&gt;GeeCON&lt;/a&gt;, &lt;a href="http://wookasz.blogspot.com/2010/05/spotkanie-jugsgeecon-12052010.html"&gt;spotkanie PJUG&lt;/a&gt; a teraz dochodzi jeszcze Eclipse DemoCamp. Parę dni temu&amp;nbsp;zaczęły&amp;nbsp;się zapisy oraz Call for Papers. Jeśli pracujesz z Eclipsem i chcesz podzielić się swoimi doświadczeniami nie wahaj się tylko zgłoś jako prelegent!&lt;br /&gt;
Na tę chwilę zgłosiły się już 3 osoby ze swoimi tematami:&lt;br /&gt;
&lt;br /&gt;
&lt;ol style="line-height: 1.5em; list-style-image: none; margin-bottom: 0px; margin-left: 3.2em; margin-right: 0px; margin-top: 0.3em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;li style="list-style-image: none !important; list-style-type: decimal; margin-bottom: 0.1em;"&gt;Krzysztof Daniel/IBM Eclipse Support Center, EMF supports GWT or Eclipse Extended Preferences&lt;/li&gt;
&lt;li style="list-style-image: none !important; list-style-type: decimal; margin-bottom: 0.1em;"&gt;Krzysztof Kazmierczyk, OSGI in the cloud&lt;/li&gt;
&lt;li style="list-style-image: none !important; list-style-type: decimal; margin-bottom: 0.1em;"&gt;Jacek&amp;nbsp;Pospychała&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;Osoby które jeszcze nie są pewne co by mogły przedstawić jak i te co się zdecydowały muszą się dopisać do listy uczestników na wiki Eclipsa:&amp;nbsp;&lt;a href="http://wiki.eclipse.org/Eclipse_DemoCamps_Helios_2010/Poznan"&gt;wiki.eclipse.org/Eclipse_DemoCamps_Helios_2010/Poznan&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;Impreza odbędzie się 10 czerwca na terenie Centrum Wykładowego Politechniki Poznańskiej w salach 6 i 8.&lt;br /&gt;
Rozpoczęcie zaplanowano na godzinę 18:00.&lt;br /&gt;
Pizza oczywiście będzie :)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Serdecznie zapraszam!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
ps. jak tak dalej pójdzie to Poznań powalczy o miano stolicy Javowej społeczności w Polsce ;-P&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-462737364038633875?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/VJ-njRbyoBo/eclipse-democamp-helios-2010-poznan.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/05/eclipse-democamp-helios-2010-poznan.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-8311758818373830605</guid><pubDate>Sun, 09 May 2010 20:01:00 +0000</pubDate><atom:updated>2010-07-09T11:22:36.247+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">geecon</category><category domain="http://www.blogger.com/atom/ns#">Poznań-JUG</category><title>Spotkanie JUGs@GeeCON [12.05.2010]</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://lstachowiak.pl/poznan-jug/poznan_jug_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://lstachowiak.pl/poznan-jug/poznan_jug_logo.png" /&gt;&lt;/a&gt;&lt;/div&gt;Poznań JUG w wydaniu specjalnym! Z okazji zbliżającego się GeeCONa odbędzie się spotkanie zorganizowane we współpracy z Polish Java User Group. A na nim wystąpi aż trzech prelegentów z różnych miejsc na świecie:&lt;br/&gt;&lt;br /&gt;
&lt;b&gt;Geertjan Wielenga&lt;/b&gt;:&lt;br /&gt;
&lt;blockquote&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 12px; font-style: italic; line-height: 16px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;The NetBeans Platform is the framework that underlies the NetBeans IDE – and many other desktop applications, some of which you may have already used. The Platform saves years of development time in building any significant desktop application, by providing a modular framework that simplifies both developing and updating desktop applications. It is used by vendors as diverse as Nokia (NetACT – cellular network monitoring and management) and Boeing (engineering materials analysis), UNESCO and many others, to develop applications as diverse as photo library management, satellite network management, semiconductor testing, planning oil drilling and music composition.&lt;br /&gt;
&lt;br /&gt;
The NetBeans Platform is based on pure Java and uses the Java standard Swing toolkit, making applications based on it portable – and even deliverable via Java WebStart directly via the web. This talk will provide a comprehensive overview of the NetBeans Platform, how it works, and how to get started using it.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;b&gt;Chris Aniszczyk&lt;/b&gt;:&lt;br /&gt;
&lt;blockquote&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 12px; font-style: italic; line-height: 16px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Eclipse e4 brings a new set of technologies into the existing Eclipse platform that make Eclipse applications easier to write, more configurable by developers and integrators and easier to reuse in a variety of runtime environments.&lt;br style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;" /&gt;In the end, attendees will be introduced to Eclipse e4 and learn about the future of the Eclipse platform.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;b&gt;Ed Burns&lt;/b&gt;:&lt;br /&gt;
&lt;blockquote&gt;&lt;span class="Apple-style-span" style="-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 12px; font-style: italic; line-height: 16px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Trebuchet MS', sans-serif;"&gt;Ed has developed a 50 minute audio-visual presentation recounting his experience in writing the book. This presentation includes audio clips from the programmers themselves, including subtitles for those for whom English is not their native language, together with insight to tie it all together.&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;Myślę, że nie muszę nikogo przekonywać do tego, że tego spotkania JUGa przegapić nie można :)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Uwaga!&lt;/b&gt; Wyjątkowo spotkanie odbędzie się w innym miejscu - Poznańskim Ośrodku Nauki znajdującym się na ul. Wieniawskiego 17/19, sala 312. Miejsce to zaznaczone jest na &lt;a href="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=pl&amp;amp;msa=0&amp;amp;msid=112309476758311609973.00048603d834f284c5e17&amp;amp;ll=52.412572,16.909676&amp;amp;spn=0.085194,0.222988&amp;amp;z=13"&gt;GeeCONowej mapce&lt;/a&gt;:&lt;br /&gt;
&lt;iframe frameborder="0" height="350" marginheight="0" marginwidth="0" scrolling="no" src="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=pl&amp;amp;msa=0&amp;amp;msid=112309476758311609973.00048603d834f284c5e17&amp;amp;ll=52.414357,16.918044&amp;amp;spn=0.009162,0.018239&amp;amp;z=15&amp;amp;iwloc=0004862bfd38f5ed84d2c&amp;amp;output=embed" width="425"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;small&gt;Pokaż &lt;a href="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=pl&amp;amp;msa=0&amp;amp;msid=112309476758311609973.00048603d834f284c5e17&amp;amp;ll=52.414357,16.918044&amp;amp;spn=0.009162,0.018239&amp;amp;z=15&amp;amp;iwloc=0004862bfd38f5ed84d2c&amp;amp;source=embed" style="color: blue; text-align: left;"&gt;GeeCON in Poznan&lt;/a&gt; na większej mapie&lt;/small&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Godzinę rozpoczęcia zaplanowano na 18:00. Do uczestnictwa wymagana jest rejestracja &lt;a href="http://oiola.com/e/598-jugsgeecon/reg/"&gt;pod tym adresem&lt;/a&gt;.&lt;br /&gt;
Do zobaczenia!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-8311758818373830605?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/qTdbOdaxSO8/spotkanie-jugsgeecon-12052010.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/05/spotkanie-jugsgeecon-12052010.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-7343133072348688009</guid><pubDate>Sat, 08 May 2010 14:39:00 +0000</pubDate><atom:updated>2010-05-09T10:13:53.851+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">konferencje</category><category domain="http://www.blogger.com/atom/ns#">geecon</category><title>GeeCON już w Poznaniu!</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://img696.imageshack.us/img696/374/20100507020.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="480" src="http://img696.imageshack.us/img696/374/20100507020.jpg" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;GeeCONowy&lt;/b&gt; baner już uświetnia Poznańskie Multikino, gdzie za kilka dni odbędzie się konferencja.&lt;br /&gt;
Rozpiska tego co, kto i gdzie dostępna jest tutaj -&amp;gt;&amp;nbsp;&lt;a href="http://2010.geecon.org/site/schedule"&gt;geecon.org/site/schedule&lt;/a&gt;. Jak widać udało się nam zaprosić wiele gwiazd świata Javowego i nie tylko - nie można tego przegapić!&lt;br /&gt;
Jeśli jeszcze się nie &lt;a href="http://2010.geecon.org/site/register"&gt;zarejestrowałeś/zarejestrowałaś&lt;/a&gt; to zostały już ostatnie chwile! Spiesz się!&lt;br /&gt;
Można także zapisać się na&amp;nbsp;&lt;a href="http://2010.geecon.org/site/university"&gt;&lt;b&gt;University Day&lt;/b&gt;&lt;/a&gt;&amp;nbsp;gdzie czeka kilka bardzo ciekawych szkoleń :)&lt;br /&gt;
&lt;br /&gt;
Zapraszam i do zobaczenia na &lt;a href="http://www.geecon.org/"&gt;&lt;b&gt;GeeCONie&lt;/b&gt;&lt;/a&gt;!!&lt;br /&gt;
&lt;br /&gt;
GeeCON w sieci:&lt;br /&gt;
www:&amp;nbsp;&lt;a href="http://www.geecon.org/"&gt;www.geecon.org&lt;/a&gt;&lt;br /&gt;
twitter:&amp;nbsp;&lt;a href="http://twitter.com/Geecon_news"&gt;twitter.com/Geecon_news&lt;/a&gt;&lt;br /&gt;
facebook:&amp;nbsp;&lt;a href="http://www.facebook.com/pages/GeeCON/354953985700"&gt;www.facebook.com/pages/GeeCON/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-7343133072348688009?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/i9sYuGrefo0/geecon-juz-w-poznaniu.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/05/geecon-juz-w-poznaniu.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-7316626475592993133</guid><pubDate>Fri, 23 Apr 2010 14:56:00 +0000</pubDate><atom:updated>2010-04-23T17:02:25.678+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JMeter</category><category domain="http://www.blogger.com/atom/ns#">testy wydajnościowe</category><title>Rozproszone testy wydajnościowe z użyciem Apache JMeter</title><description>&lt;a href="http://wookasz.blogspot.com/2010/04/testy-wydajnosciowe-bazy-danych-z.html"&gt;Kolejny&lt;/a&gt; wpis o &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt;. Bardzo przydatne narzędzie :)&lt;br /&gt;
Dzisiaj chciałem pokazać jak wykonywać rozproszone testy wydajnościowe. Do tego będzie nam potrzebne kilka maszyn z kopią JMeter. Ważne by na każdej maszynie były takie same wersje aplikacji.&lt;br /&gt;
Moje środowisko testowe wygląda następująco: (Paint wymiata;)&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GdObD-z2I/AAAAAAAAD3Y/fIKz_YEgMow/s1600/schemat.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="420" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GdObD-z2I/AAAAAAAAD3Y/fIKz_YEgMow/s640/schemat.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Zadaniem węzła master jest uruchomienie testów na wszystkich slaveach oraz odbieraniem od nich informacji o wynikach pomiarów. Slave natomiast bombarduje cel żądaniami zdefiniowanymi i przesłanymi przez Master.&lt;br /&gt;
Aby uruchomić slave należy na każdej węźle uruchomić Server JMeter -&amp;gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; JMETER_HOME/bin/jmeter-server.bat&lt;/span&gt;&lt;br /&gt;
Tutaj należy uważać, bo z tego co zauważyłem jest wybierany losowy port a nie jakiś stały przez co mogą wystąpić problemy z firewallem. Jeśli wszystko poszło dobrze coś podobnego do tego powinno się pojawić w konsoli:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GgdEYPAzI/AAAAAAAAD3g/4t7-V-9xz8I/s1600/jmeter_server_console.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="104" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GgdEYPAzI/AAAAAAAAD3g/4t7-V-9xz8I/s640/jmeter_server_console.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
To wszystko co należy zrobić na tych węzłach. W węźle master należy otworzyć do edycji plik &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;JMETER_HOME/bin/jmeter.properties&lt;/span&gt;. W linii &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;remote_host=127.0.0.1&lt;/span&gt; należy wpisać adresy serwerów slave. W moim przypadku będzie to wyglądać następująco:&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;remote_hosts=192.168.0.6,192.168.0.7,192.168.0.4,192.168.0.15&lt;/span&gt;&lt;br /&gt;
Po uruchomieniu JMeter w menu &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Run-&amp;gt; Remote Start -&amp;gt;&lt;/span&gt; powinna pojawić się lista serwerów które dodaliśmy. Możemy odpalać je pojedynczo lub wszystkie jednocześnie za pomocą &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;Remote Start All&lt;/span&gt;. Wystarczy już tylko przygotować jakiś plan testów i odpalić. Konsola na węzłach Slave powinna nas informować o rozpoczęciu i zakończeniu testów:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_QQi5tGIQ1eA/S9GykpQH3vI/AAAAAAAAD3o/-J7sYG4TiGc/s1600/remote_tests_console.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="204" src="http://1.bp.blogspot.com/_QQi5tGIQ1eA/S9GykpQH3vI/AAAAAAAAD3o/-J7sYG4TiGc/s640/remote_tests_console.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;W przypadku jakiś problemów polecam sprawdzić plik &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;jmeter.log&lt;/span&gt; w ktalogu &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/bin/&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Podoba mi się to narzędzie:) Bardzo szybko i prosto można skonfigurować duże źródło ruchu dla testowanego środowiska. Jedna maszyna do zastosować domowych może spokojnie symulować ponad 2000 wirtualnych użytkowników. W zupełności mi to wystarcza dla testowanych przeze mnie projektów.&lt;br /&gt;
Postaram się niedługo napisać coś więcej na temat skalowalności JMeter i tego kiedy on może stać się wąskim gardłem, a nie aplikacja lub przepustowość sieci w środowisku.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-7316626475592993133?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/grAd7uZv_XY/rozproszone-testy-z-uzyciem-apache.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GdObD-z2I/AAAAAAAAD3Y/fIKz_YEgMow/s72-c/schemat.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/04/rozproszone-testy-z-uzyciem-apache.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-8841276175995279736</guid><pubDate>Sun, 18 Apr 2010 08:40:00 +0000</pubDate><atom:updated>2010-04-26T19:13:04.311+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">recenzja</category><title>Recenzja - "Wydajne witryny internetowe - Przyspieszanie działania serwisów WWW"</title><description>&lt;span style="font-family: inherit; font-size: small;"&gt;Tematyka optymalizacji oraz skalowania aplikacji WWW jest obiektem moich zainteresowań przez dłuższy już czas. Nie tylko ze względu na temat pracy magisterskiej, ale także ze względu na projekt nad którym aktualnie pracuję, &lt;/span&gt;oraz (tak po prostu;) zwykłą ciekawość co i gdzie poprzestawiać by było szybciej, ładniej i wydajniej :)&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://helion.pl/okladki/326x466/oprzep.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://helion.pl/okladki/326x466/oprzep.jpg" width="222" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Przeglądałem parę dni temu zasoby biblioteki na PP i natrafiłem na książkę o interesującym dla mnie tytule "Wydajne witryny internetowe - Przyspieszanie działania serwisów WWW", której autorem jest &lt;a href="http://stevesouders.com/bio.php"&gt;Steve Souders&lt;/a&gt;. Pomyślałem sobie, że to będzie kolejna książka o tym czy używać for czy while oraz, że w php szybsze jest isset od is_null. Jednak zamówiłem, odebrałem i przeczytałem z przyjemnością !&lt;br /&gt;
Co ciekawe książka nie zawiera odniesienia do żadnego języka programowania (bezpośrednio przynajmniej) i nie mówi o żadnych wzorcach projektowych. Jej tematem jest optymalizacja bardziej etapu dostarczania strony www do klienta niż logiki biznesowej aplikacji. Jest w niej mowa m.in. o ograniczaniu połączeń TCP, kompresji dokumentów HTML czy buforowaniu zapytań asynchronicznych - prawie nic z programowania.&lt;br /&gt;
Wg badań autora sama faza dostarczania dokumentu HTML to około 10-20% całego czasu przesyłania odpowiedzi, reszta czyli ok 80-90% to pobieranie obrazków, cssów jsów i przekierowania. I właśnie te 80-90% jest przez większość lektury przedmiotem optymalizacji.&lt;br /&gt;
Książka podzielona została na 17 części z czego 14 to opisane reguły (wraz z przykładami) po których zastosowaniu nasza strona powinna ładować się szybciej - od 25 do 50%, niezły wynik jak na 160 stronicową książkę :)&lt;br /&gt;
Oto te reguły posortowane wg autora od najbardziej znaczącej:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Wykonywania mniejszej liczby żądań HTTP&lt;/li&gt;
&lt;li&gt;Używanie Content Delivery Network (to rozwiązanie raczej dla bogatszych ;)&lt;/li&gt;
&lt;li&gt;Używanie nagłówka Expires&lt;/li&gt;
&lt;li&gt;Kompresja gzip&lt;/li&gt;
&lt;li&gt;Umieszczanie arkuszy stylów na początku dokumentu&lt;/li&gt;
&lt;li&gt;Umieszczanie skryptów na końcu dokumentu&lt;/li&gt;
&lt;li&gt;Unikanie wyrażeń CSS&lt;/li&gt;
&lt;li&gt;Używanie zewnętrznych plików JavaScript i CSS&lt;/li&gt;
&lt;li&gt;Redukcja liczby zapytań DNS&lt;/li&gt;
&lt;li&gt;Zmniejszenie objętości kodu JavaScript&lt;/li&gt;
&lt;li&gt;Unikanie przekierowań&lt;/li&gt;
&lt;li&gt;Usuwanie duplikujących się skryptów&lt;/li&gt;
&lt;li&gt;Konfiguracja nagłówka ETag&lt;/li&gt;
&lt;li&gt;Buforowanie zapytań Ajax&lt;/li&gt;
&lt;/ol&gt;Trzeba przyznać, że Pan Souders posiada bardzo dużą wiedzę w tej dziedzinie, za każdym razem dane zagadnienie przedstawione jest z dokładnym uzasadnieniem, stosownym przykładem oraz wynikami pomiarów jakie otrzymał. Bardzo dużo wspominane jest o portalu Yahoo! gdzie pracował przy jego optymalizacji, więc przykłady trafiają się także z "dużych" witryn. W ostatnim rozdziale ponadto poddano analizie 10 jednych z największych serwisów internetowych (YouTube, Google, MSN, Amazon, CNN, Wikipedia, AOL, Amazon, Yahoo!, eBay), gdzie zostają wytknięte wszystkie ich słabości. Swoją drogą ten rozdział mógłby być dedykowany administratorom tych serwisów:)&lt;br /&gt;
Z czystym sercem polecam tę książkę każdemu webmasterowi, administratorowi, programiście witryn i komukolwiek kto ma do czynienia z WWW. Te 160 stron może przynieść bardzo duże oszczędności finansowe, gdy serwis zacznie się rozrastać. A co najlepsze - książka kosztuje tylko 29,00 zł !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-8841276175995279736?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/pu7jSCCdNW8/recenzja-wydajne-witryny-internetowe.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>4</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/04/recenzja-wydajne-witryny-internetowe.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-8981144537531451940</guid><pubDate>Sat, 17 Apr 2010 09:58:00 +0000</pubDate><atom:updated>2010-04-17T11:58:14.995+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JMeter</category><category domain="http://www.blogger.com/atom/ns#">bazy danych</category><category domain="http://www.blogger.com/atom/ns#">testy wydajnościowe</category><category domain="http://www.blogger.com/atom/ns#">db2</category><title>Testy wydajnościowe bazy danych z Apache JMeter</title><description>Dzisiaj na tablicy od rana mam &lt;a href="http://jakarta.apache.org/jmeter/" target="_blank"&gt;Apache JMeter&lt;/a&gt; - świetne i darmowe narzędzie do testowania obciążenia. Kto by chciał się zapoznać z tym jak testować swoje witryny za pomocą tego narzędzia zapraszam (który to już raz?;]) na blog Mateusza Zięby -&amp;gt; &lt;a href="http://na-jawie.blogspot.com/2010/02/perwszy-test-z-apache-jmeter.html" target="_blank"&gt;&lt;b&gt;&lt;i&gt;Na Jawie - perwszy test z Apache JMeter.&lt;/i&gt;&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
U mnie potestujemy za to jak sprawuje się silnik bazy danych dla zapytań używanych w tworzonej przez nas aplikacji.&lt;br /&gt;
Pobrać JMeter można &lt;a href="http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi" target="_blank"&gt;tutaj&lt;/a&gt;. Po ściągnięciu, ale &lt;b&gt;przed uruchomieniem należy przegrać sterownik JDBC bazy danych której będziemy używać do katalogu &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;/lib/&lt;/span&gt;&lt;/b&gt; znajdujący się w katalogu głównym aplikacji. W moim przypadku bazą danych będzie DB2, więc kopiuję tam plik &lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;db2jcc4.jar&lt;/span&gt;.&lt;br /&gt;
&amp;nbsp;Po uruchomieniu programu zabieramy się za tworzenie testu. Do węzła "Test Plan" po prawej stronie dodajemy &lt;i&gt;Add -&amp;gt; Thread Group&lt;/i&gt;. Grupa wątków definiuje ilu użytkowników będzie symulować test, ile razy każdy z nich będzie wykonywać wszystkie zdefiniowane żądania oraz co jaki czas powinien startować kolejny użytkownik. Dla przykładowego testu ustawiłem następujące wartości:&lt;br /&gt;
&lt;i&gt;Number of threads&lt;/i&gt;: 8&lt;br /&gt;
&lt;i&gt;Ramp-Up Period&lt;/i&gt;: 0 (startują wszyscy od razu)&lt;br /&gt;
&lt;i&gt;Loop count&lt;/i&gt;: 20&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S8l87r0d0KI/AAAAAAAAD2s/FHmzPUueQgM/s1600/ThreadGroup.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="307" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S8l87r0d0KI/AAAAAAAAD2s/FHmzPUueQgM/s640/ThreadGroup.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Teraz do grupy wątków należy dodać konfigurację połączenia z bazą danych: &lt;i&gt;Add -&amp;gt; Config Element -&amp;gt; JDBC Connection Configuration&lt;/i&gt;.W tym oknie uzupełniamy:&lt;br /&gt;
&lt;i&gt;Variable Name&lt;/i&gt;: (tutaj dowolna nazwa, u mnie: DB2_SAMPLE)&lt;br /&gt;
&lt;i&gt;Database URL&lt;/i&gt;: (ścieżka połączenia do bazy danych, u mnie: jdbc:db2://localhost:5000/SAMPLE)&lt;br /&gt;
&lt;i&gt;JDBC Driver class&lt;/i&gt;: (klasa sterownika, u mnie&amp;nbsp; com.ibm.db2.jcc.DB2Driver&lt;br /&gt;
&lt;i&gt;Username&lt;/i&gt;: użytkownik&lt;br /&gt;
&lt;i&gt;Password&lt;/i&gt;: hasło&lt;br /&gt;
Bardzo ważne jest uzupełnione przez nas pole &lt;i&gt;Variable Name&lt;/i&gt; ponieważ to na podstawie tej nazwy będziemy się odwoływać do tego połączenia przy tworzeniu zapytań. Możliwe jest utworzenie wielu połączeń i korzystanie z nich w różnych zapytaniach, właśnie na podstawie tej nazwy (musi być ona unikalna!).&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S8mAtji18mI/AAAAAAAAD20/OXFD2d1zWIc/s1600/jdbcconnection.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="378" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S8mAtji18mI/AAAAAAAAD20/OXFD2d1zWIc/s640/jdbcconnection.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Teraz należy dodać zapytania które będą wykonywane: &lt;i&gt;Add -&amp;gt; Sampler -&amp;gt; JDBC Request&lt;/i&gt;. Ja do testów podałem dwa bardzo proste zapytania zwracające listę pracowników oraz listę departamentów z przykładowej bazy w DB2.&lt;br /&gt;
EmpoyeeList:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_QQi5tGIQ1eA/S8mCFiPDlDI/AAAAAAAAD28/N7BSys0xHtk/s1600/employeeList.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="236" src="http://1.bp.blogspot.com/_QQi5tGIQ1eA/S8mCFiPDlDI/AAAAAAAAD28/N7BSys0xHtk/s640/employeeList.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;DepartmentList:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S8mCOBWjJoI/AAAAAAAAD3E/3Ryl07c5zkA/s1600/departmentList.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="232" src="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S8mCOBWjJoI/AAAAAAAAD3E/3Ryl07c5zkA/s640/departmentList.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;Należy pamiętać by w obu zapytaniach pole Variable Name miało wartość taką jak nazwa puli połączeń z konfiguracji połączenia&lt;/b&gt;. W moim wypadku jest to DB2_SAMPLE.&lt;br /&gt;
No to już praktycznie wszystko gotowe. Dodajmy jeszcze &lt;i&gt;Add -&amp;gt; Listeners -&amp;gt; Summary Report&lt;/i&gt; do wyświetlenia wyników podsumowujących testy.&lt;br /&gt;
I można startować z testem: &lt;i&gt;Run -&amp;gt; Start&lt;/i&gt; :) Podczas symulacji łącznie powinno zostać wykonanych: &lt;i&gt;liczba użytkowników * liczba powtórzeń * liczba zapytań SQL&lt;/i&gt; żądań.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_QQi5tGIQ1eA/S8mEnCLZPqI/AAAAAAAAD3M/t6msU6akEx4/s1600/summaryreport.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="192" src="http://1.bp.blogspot.com/_QQi5tGIQ1eA/S8mEnCLZPqI/AAAAAAAAD3M/t6msU6akEx4/s640/summaryreport.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Miłego testowania !&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-8981144537531451940?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/xvwqvi2F4FM/testy-wydajnosciowe-bazy-danych-z.html</link><author>noreply@blogger.com (WooKasZ)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_QQi5tGIQ1eA/S8l87r0d0KI/AAAAAAAAD2s/FHmzPUueQgM/s72-c/ThreadGroup.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/04/testy-wydajnosciowe-bazy-danych-z.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-4521740139902912196</guid><pubDate>Fri, 16 Apr 2010 20:52:00 +0000</pubDate><atom:updated>2010-04-16T22:52:43.670+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">JSF</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>Mapowanie parametrów GET w JSF</title><description>Jak miło można "pobierać" wartości GET z URL w JSF - praktycznie samo się robi. Wystarczy powiązać w faces-config.xml nazwę pola w GET z polem w zarządzanym ziarnie &lt;br /&gt;
Dla przykładowego linka:&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt; /employeeView.faces?employeeId=000010&lt;/span&gt;&lt;br /&gt;
&lt;i&gt;faces-config.xml&lt;/i&gt;:&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;managed-bean&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;managed-bean-name&amp;gt;employeeBean&amp;lt;/managed-bean-name&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;managed-bean-class&amp;gt;com.sampleproject.jsf.EmployeeBean&amp;lt;/managed-bean-class&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;managed-bean-scope&amp;gt;request&amp;lt;/managed-bean-scope&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;managed-property&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;property-name&amp;gt;employeeId&amp;lt;/property-name&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;value&amp;gt;#{param.employeeId}&amp;lt;/value&amp;gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/managed-property&amp;gt;
&amp;lt;/managed-bean&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
I nie trzeba się o nic martwić, bo zrobi się samo. Co jest bardzo dobre JSF nie rzuca wyjątkami gdy brakuje wartości w GET tylko wstawia null.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-4521740139902912196?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/BPfEBd55skQ/mapowanie-parametrow-get-w-jsf.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/04/mapowanie-parametrow-get-w-jsf.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-7013878791022273926</guid><pubDate>Wed, 07 Apr 2010 11:27:00 +0000</pubDate><atom:updated>2010-04-26T19:18:20.301+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">bazy danych</category><category domain="http://www.blogger.com/atom/ns#">dbMonster</category><category domain="http://www.blogger.com/atom/ns#">db2</category><title>Karmimy bazę danych - dbMonster</title><description>&lt;a href="http://dbmonster.kernelpanic.pl/" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://dbmonster.kernelpanic.pl/gfx/dbmonster-logo.png" /&gt;&lt;/a&gt;Przez ostatni czas szukałem narzędzia do generowania dużej ilości danych dla baz danych.&lt;br /&gt;
Natrafiłem na dość sporo ich w sieci ale niestety znaczna większość była komercyjna a ich wersje trialowe umożliwiały generowanie np. tylko 40 rekordów. Ale na szczęście udało mi się także napotkać na miły program autorstwa Polaka &lt;b&gt;Piotra Maja&lt;/b&gt; - &lt;a href="http://dbmonster.kernelpanic.pl/"&gt;&lt;b&gt;dbMonster&lt;/b&gt;&lt;/a&gt;. Narzędzie to obsługuje się z poziomu (niestety) konsoli i wymaga stworzenia mapowania w pliku XML oraz prostej konfiguracji.&lt;br /&gt;
Zacznijmy od stworzenia tabeli w bazie danych którą później zapchamy danymi:&lt;br /&gt;
&lt;pre class="sql" name="code"&gt;CONNECT TO DBMNTEST;
CREATE TABLE WOOKASZ.PRODUKTY ( 
ID_PRODUKTU BIGINT  NOT NULL  GENERATED ALWAYS AS IDENTITY (START WITH 0, INCREMENT BY 1, NO CACHE ), 
NAZWA VARCHAR (80)  NOT NULL, 
CENA DECIMAL (9, 2)  NOT NULL, 
CONSTRAINT CC1270576608403 PRIMARY KEY (ID_PRODUKTU)
);
CONNECT RESET;
&lt;/pre&gt;W konfiguracji podajemy podstawowe dane do połączenia i kilka parametrów potrzebnych do pracy dbMonster.&lt;br /&gt;
&lt;i&gt;test.properties:&lt;/i&gt;&lt;br /&gt;
&lt;pre&gt;# podstawowe dane do połączenia
dbmonster.jdbc.driver=com.ibm.db2.jcc.DB2Driver
dbmonster.jdbc.url=jdbc:db2://127.0.0.1:50000/dbmntest
dbmonster.jdbc.username=WOOKASZ
dbmonster.jdbc.password=password
# po ilu insertach wykonywać commit
dbmonster.jdbc.transaction.size=1000

# nazwa schematu dla takich baz jak Oracle lub DB2
dbmonster.jdbc.schema=WOOKASZ

# ile razy próbować wygenerować unikalny klucz
dbmonster.max-tries=1000

# domyślna liczba wierszy dla SchemaGrabber (o tym innym razem;)
dbmonster.rows=1000

# klasa wizualizująca progress bar
dbmonster.progress.monitor=pl.kernelpanic.dbmonster.ProgressMonitorAdapter
&lt;/pre&gt;Myślę, że tak konfiguracja jest dość prosta i nie trzeba jej głębiej omawiać.&lt;br /&gt;
Teraz czas dla schematu w którym opisana jest struktura tabel dla których generowane będą dane. W naszym przypadku jest to tylko jedna tabela PRODUKTY.&lt;br /&gt;
&lt;i&gt;testSchema.xml&lt;/i&gt;:&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;?xml version="1.0" encoding="iso-8859-1"?&amp;gt;
&amp;lt;!DOCTYPE dbmonster-schema PUBLIC
    "-//kernelpanic.pl//DBMonster Database Schema DTD 1.1//EN"
    "http://dbmonster.kernelpanic.pl/dtd/dbmonster-schema-1.1.dtd"&amp;gt;
&amp;lt;dbmonster-schema&amp;gt;
   &amp;lt;name&amp;gt;DB Monster Test Schema ! ^^&amp;lt;/name&amp;gt;
    &amp;lt;table name="PRODUKTY" rows="15000"&amp;gt;
        &amp;lt;key databaseDefault="true"&amp;gt;
           &amp;lt;generator type="pl.kernelpanic.dbmonster.generator.MaxKeyGenerator"&amp;gt;
               &amp;lt;property name="columnName" value="ID_PRODUKTU"/&amp;gt;
           &amp;lt;/generator&amp;gt;
        &amp;lt;/key&amp;gt;
        &amp;lt;column name="nazwa"&amp;gt;
            &amp;lt;generator type="pl.kernelpanic.dbmonster.generator.StringGenerator"&amp;gt;
                &amp;lt;property name="nulls" value="0"/&amp;gt;
                &amp;lt;property name="minLength" value="4"/&amp;gt;
                &amp;lt;property name="maxLength" value="80"/&amp;gt;
                &amp;lt;property name="allowSpaces" value="true"/&amp;gt;
            &amp;lt;/generator&amp;gt;
        &amp;lt;/column&amp;gt;
        &amp;lt;column name="cena"&amp;gt;
            &amp;lt;generator type="pl.kernelpanic.dbmonster.generator.NumberGenerator"&amp;gt;
                &amp;lt;property name="nulls" value="0"/&amp;gt;
                &amp;lt;property name="minValue" value="10"/&amp;gt;
                &amp;lt;property name="maxValue" value="30000"/&amp;gt;
                &amp;lt;property name="returnedType" value="numeric"/&amp;gt;
    &amp;lt;property name="scale" value="2"/&amp;gt;
            &amp;lt;/generator&amp;gt;
        &amp;lt;/column&amp;gt;
    &amp;lt;/table&amp;gt;
&amp;lt;/dbmonster-schema&amp;gt;&lt;/pre&gt;Opis struktury tabeli zawiera się w znaczniku &lt;i&gt;table&lt;/i&gt; którego pierwszy atrubuty &lt;i&gt;name&lt;/i&gt; musi zawierać poprawną nazwę tabeli, a drugi &lt;i&gt;rows&lt;/i&gt; liczbę wierszy ile ma być wygenerowanych dla tej tabeli. dbMonster obsługuje klucze główne tabel, informacje o nich zawiera się w znaczniku &lt;i&gt;key&lt;/i&gt;. W tym przypadku nie używamy generatora udostępnianego przez dbMonster do generowania wartości dla kluczy (używane są &lt;i&gt;identity columns&lt;/i&gt;) dlatego atrybut &lt;i&gt;databaseDefault&lt;/i&gt; ma wartość &lt;i&gt;true&lt;/i&gt;. Dalej umieszczone zostały definicje kolumn. Każda kolumna zawiera parametry do generowania, zależne są one od tego jakiego typu generatora używamy. Listą dostępnych generatorów wraz z opisem parametrów dostępna jest &lt;a href="http://dbmonster.kernelpanic.pl/manual/data-generators.html"&gt;tutaj&lt;/a&gt;. Co jest bardzo miłe dostępne jest &lt;a href="http://dbmonster.kernelpanic.pl/apidocs/"&gt;pełne API&lt;/a&gt; który pozwala na tworzenie własnych generatorów.&lt;br /&gt;
Co mi się bardzo spodobało &lt;a href="http://dbmonster.kernelpanic.pl/manual/string-generator.html"&gt;StringGenerator&lt;/a&gt; nie generuje dziwnego zlepku losowych liter tylko normalne słowa z dostępnego dla niego słownika:) Dlatego nazwą produktu nie będzie np. "AhT8ddnoJuuTQpp" ale np. "keypad's tingle". Wiem, że to i tak bez sensu (a może to coś znaczy ?) ale lepiej to wygląda gdy prezentujemy nasz system.&lt;br /&gt;
Zanim będzie można uruchomić generację należy przekopiować do katalogu /lib/ sterownik JDBC dla używanej bazy danych.&lt;br /&gt;
Teraz możemy użyć gotowego skryptu bat z katalogu /bin/ aby uruchomić generację:&lt;br /&gt;
&lt;pre&gt;dbmonster -c test.properties -s testSchema.xml

rem Batch file to run dbmonster under Windows

rem Contributed by Peter De Bruycker
2010-04-07 12:21:55,776 INFO  DBMonster - Let's feed this hungry database.
2010-04-07 12:21:56,257 INFO  DBCPConnectionProvider - Today we are feeding: DB2/NT SQL09070
2010-04-07 12:21:56,465 INFO  Schema - Generating schema &lt;db !="" ^^="" monster="" schema="" test=""&gt;.
2010-04-07 12:21:56,473 INFO  Table - Generating table &amp;lt;PRODUKTY&amp;gt;.
2010-04-07 12:22:28,570 INFO  Table - Generation of table &amp;lt;PRODUKTY&amp;gt; finished.
2010-04-07 12:22:28,574 INFO  Schema - Generation of schema &amp;lt;DB Monster Test Schema ! ^^&amp;gt; finished.
2010-04-07 12:22:28,579 INFO  DBMonster - Finished in 32 sec. 804 ms.
&lt;/db&gt;&lt;/pre&gt;I mamy tabelę pełną danych:)&lt;br /&gt;
Dodam jeszcze, że tworzenie schematu nie jest konieczne, gdy w tabelach znajdują się jakieś dane. Można użyć tzw. SchemaGrabber aby wygenerować schemat xml. Jednak jeszcze nie udało mi się tego dokonać, ciągle otrzymuję pustą definicję tabeli. Jak mi się to uda to postaram się opisać.&lt;br /&gt;
&lt;br /&gt;
Narzędzie jest bardzo dobre gdy nie mamy jakiś skomplikowanych warunków do tego jakie dane mają być składowane w bazie danych, do prostych zastosować idealne. Szkoda tylko, że projekt ten już od 2006 roku nie jest rozwijany, według mnie ma solidne podstawy do tego by konkurować z komercyjnymi rozwiązaniami. Może ktoś przejmie pałeczkę i zajmie się rozbudową dbMonster ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/928894612202750731-7013878791022273926?l=blog.lstachowiak.pl' alt='' /&gt;&lt;/div&gt;</description><link>http://feedproxy.google.com/~r/wookasz/~3/uOUX5EuLYZ0/karmimy-baze-danych-dbmonster.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.lstachowiak.pl/2010/04/karmimy-baze-danych-dbmonster.html</feedburner:origLink></item></channel></rss>

