<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-928894612202750731</atom:id><lastBuildDate>Sat, 06 Jun 2020 20:08:21 +0000</lastBuildDate><category>programowanie</category><category>Java</category><category>humor</category><category>Java ME</category><category>Poznań-JUG</category><category>kabaret</category><category>NetBeans</category><category>bazy danych</category><category>głupoty</category><category>konferencje</category><category>Internet</category><category>Muzyka</category><category>php</category><category>skalowalność</category><category>Świat</category><category>O mnie</category><category>Google</category><category>JSF</category><category>Web services</category><category>db2</category><category>geecon</category><category>ludzie</category><category>Java 7</category><category>OpenBaseMovil-db</category><category>eclipse</category><category>szkoła</category><category>Glassfish</category><category>JMeter</category><category>JPA</category><category>Oracle Coherence</category><category>film</category><category>testy wydajnościowe</category><category>EJB</category><category>Facelets</category><category>Hadoop</category><category>JMX</category><category>LWUIT</category><category>Spring Security</category><category>firebird</category><category>jDeveloper</category><category>linux</category><category>niesamowite</category><category>samochody</category><category>software craftsmanship</category><category>Agile</category><category>JavaFX</category><category>Spring Framework</category><category>VoIP</category><category>dbMonster</category><category>koncerty</category><category>recenzja</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>159</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-7978536915740118376</guid><pubDate>Wed, 21 Nov 2012 12:58:00 +0000</pubDate><atom:updated>2012-11-21T18:36:14.370+01: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#">software craftsmanship</category><title>Enkapsuluj swoje wyjątki</title><description>Tyle o tej enkapsulacji, a mało kto pisze o tym w kontekście wyjątków.&lt;br /&gt;Może najpierw trochę o tym jakie wyjątki rzucać. Zgodnie z arkanami sztuki metoda powinna rzucać wyjątki _tylko_i_wyłącznie_ &lt;b&gt;istotne&lt;/b&gt; z punktu widzenia interfejsu jaki reprezentuje. Biorąc za przykład:&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;interface UserRepository {&lt;br /&gt;    List&amp;lt;User&amp;gt; activeUsers() throws DataAccessException;&lt;br /&gt;}&lt;/pre&gt;Metoday &lt;i&gt;activeUsers&lt;/i&gt; zwraca listę użytkowników i jest zupełnie sensownym to, że zgłosi wyjątek DataAccessException, gdy pojawi się błąd z dostępem do danych. Zgłaszanie wyjątku typu BufferOverflowException, albo DOMException nie da klientowi żadnej użytecznej informacji na temat tego co się stało. Klienta interesuje to, że repozytorium ma problem z dostępem do danych, a nie to, że w środku jakiś bufor się przepełnił, albo przetwarza błędny dokument DOM.&lt;br /&gt;&lt;br /&gt;To prowadzi do myśli o enkapsulacji. Gdybyśmy sprzedawali bułki w sklepie, a nasz piekarz wstrzymałby dostawę na parę dni, ponieważ w jego piekarni pojawił mklik próchniczek - nie informowalibyśmy o tym naszych klientów, bo już więcej by się nie pojawili. Taką informację zachowamy dla siebie, zmienimy piekarza, a klientowi powiemy, że mamy problemy z dostawą na parę dni. I tak też powinniśmy robić w świecie Javy. Metoda &lt;i&gt;activeUsers()&lt;/i&gt; nie powinna zwracać wyjątku typu SQLException czy FileNotFoundException. Klienta to nie interesuje skąd repozytorium bierze dane. Klient po prostu chce te dane!&lt;br /&gt;Wyjątki powinny być enkapsulowane przed rzuceniem ich dalej. Przykładowa implementacja metody &lt;i&gt;activeUsers&lt;/i&gt;:&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;public List&amp;lt;User&amp;gt; activeUsers() throws DataAccessException {&lt;br /&gt;    try {&lt;br /&gt;        // wyciąganie danych z bazy&lt;br /&gt;    } catch (SQLException e) {&lt;br /&gt;        throw new DataAccessException(e);&lt;br /&gt;    }    &lt;br /&gt;    return users;&lt;br /&gt;}&lt;/pre&gt;DataAccessException ładnie enkapsuluje w sobie co się stało w metodzie activeUsers. Użytkownik repozytorium jest wolny od tej implementacji i wymiana na inne źródło danych nie pociąga za sobą daleko idących zmian w kodzie.&lt;br /&gt;Jeśli to repozytorium byłoby wystawiane np. przez webservice do zdalnych klientów to implementacja może wyglądać tak:&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;public List&amp;lt;User&amp;gt; activeUsers() throws DataAccessException {&lt;br /&gt;    try {&lt;br /&gt;        // wyciąganie danych z bazy&lt;br /&gt;    } catch (SQLException e) {&lt;br /&gt;        logger.error(e);&lt;br /&gt;        throw new DataAccessException(&quot;Error during data fetching&quot;);&lt;br /&gt;    }    &lt;br /&gt;    return users;&lt;br /&gt;}&lt;/pre&gt;W takim wypadku klient nie ma zupełnie wiedzy o tym czego używamy do przechowywania danych, a my nie tracimy informacji o błędzie.</description><link>http://blog.lstachowiak.pl/2012/11/enkapsuluj-swoje-wyjatki.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>4</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-6821373391266234955</guid><pubDate>Tue, 30 Oct 2012 19:00:00 +0000</pubDate><atom:updated>2012-11-21T13:59:33.523+01: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#">software craftsmanship</category><title>Nie zwracaj nulla!</title><description>Po raz kolejny siedzę w czyimś kodzie w którym co chwilą jest if:&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;public List &amp;lt;User&amp;gt; usersList() {&lt;br /&gt;    List&amp;lt;Object[]&amp;gt; users = db.query(&quot;SELECT id, name, email FROM users&quot;);&lt;br /&gt;    if (users == null);&lt;br /&gt;        return null;&lt;br /&gt;    //...&lt;br /&gt;    // mapowanie na obiekty i zwrot wyników&lt;/pre&gt;I dalej gdzieś w serwisie czy czymś:&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;List&amp;lt;User&amp;gt; users = usersRepo.usersList();&lt;br /&gt;if (users == null)&lt;br /&gt;    return null; // i zabawa trwa dalej!&lt;/pre&gt;Takie IFy mają tendencje do ciągnięcia się przez wszystkie warstwy sięgając nawet samego widoku. Pozbycie się tego nie tylko poprawi wygląd kodu, zmniejszy złożoność, ale też ograniczy możliwość wystąpienia NullPointerException. A rozwiązanie tego jest proste - zwracać tzw. &lt;a href=&quot;http://en.wikipedia.org/wiki/Null_Object_pattern&quot; target=&quot;_blank&quot;&gt;NullObject&lt;/a&gt;. Koncepcja prosta jak &lt;a href=&quot;http://pl.wikipedia.org/wiki/Cep_(narz%C4%99dzie)#Budowa&quot;&gt;budowa cepa&lt;/a&gt;. W tym przypadku możemy szybko zmienić by obiekt zwracał pustą listę: &lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;public List &amp;lt;User&amp;gt; usersList() {&lt;br /&gt;    List&amp;lt;Object[]&amp;gt; users = db.query(&quot;SELECT id, name, email FROM users&quot;);&lt;br /&gt;    if (users == null);&lt;br /&gt;        return Collections.&amp;lt;User&amp;gt;emptyList();&lt;br /&gt;    //...&lt;br /&gt;    // mapowanie na obiekty i zwrot wyników&lt;/pre&gt;I już nie trzeba się bać o NPE i kod robi to co powinien (czyli zwrócić _listę_). Ciekawszym przykładem będzie, gdy zaczniemy mieć różne implementacje jakieś funkcjonalności. Np. gdy mamy odpowiednią klasę odpowiedzialną za kolorowanie obramowania, ale czasami nie musimy go kolorować. Najpierw wersja &#39;brzydka&#39;:&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;public interface BorderPainter {&lt;br /&gt;    void paint(Element element);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class BorderPainterFactory {&lt;br /&gt;    public static BorderFactory get(BorderType type) {&lt;br /&gt;        switch (type) {&lt;br /&gt;            case BOLDED:&lt;br /&gt;                return new BoldetBorderPainter();&lt;br /&gt;            case DOTTED:&lt;br /&gt;                return new DottedBorderPainter();&lt;br /&gt;            case NONE:&lt;br /&gt;                return null;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// i użycie&lt;br /&gt;BorderPainter painter = BorderFactory.get(type);&lt;br /&gt;// albo gorsze - sprawdzać czy type jest typu NONE przed wywołaniem factorki&lt;br /&gt;if (painter != null) { &lt;br /&gt;    painter.paint(someElement);&lt;br /&gt;}&lt;/pre&gt;A lepiej sobie wprowadzić implementację BorderPainter która najzwyczajniej w świecie nic nie robi :)&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;public NoBorderPainter implements BorderPainter {&lt;br /&gt;    public void paint(Element element) {}&lt;br /&gt;}&lt;br /&gt;// i wywołanie jest zawsze takie samo:&lt;br /&gt;BorderPainter painter = BorderFactory.get(type);&lt;br /&gt;painter.paint(someElement);&lt;/pre&gt;Takie podejście jest dużo bardziej object oriented, zmniejsza złożoność, zwiększa elastyczność, czytelność, stabilność i testowalność kodu. Oczywiście nie zawsze jest to możliwe, by takowy NullObject skontruować i wprowadzić. Ale z doświadczenia widzę, że około 90% takich konstrukcji może zostać zrefaktoryzowanych.&lt;br /&gt;&lt;br /&gt;Piękna prezentacja na temat usuwania IFów z kodu autorstwa Misko Heverego (co mocno rozszerza mój wątek o null objectach) można zobaczyć poniżej. POLECAM!&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&#39;allowfullscreen&#39; webkitallowfullscreen=&#39;webkitallowfullscreen&#39; mozallowfullscreen=&#39;mozallowfullscreen&#39; width=&#39;320&#39; height=&#39;266&#39; src=&#39;https://www.youtube.com/embed/4F72VULWFvc?feature=player_embedded&#39; frameborder=&#39;0&#39; /&gt;&lt;/div&gt;&lt;br /&gt;</description><link>http://blog.lstachowiak.pl/2012/10/nie-zwracaj-nulla.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>2</thr:total></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-928894612202750731.post-1753946789312466350</guid><pubDate>Mon, 26 Mar 2012 18:42:00 +0000</pubDate><atom:updated>2012-03-26T20:42:33.764+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">geecon</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">konferencje</category><title>GeeCON 2012 [Film:]</title><description>&lt;br /&gt;Czwarta edycja&lt;b&gt; &lt;a href=&quot;http://www.geecon.org/&quot; target=&quot;_blank&quot;&gt;GeeCONa&lt;/a&gt;&lt;/b&gt; zbliża się wielkimi krokami! Dla tych co jeszcze nie wiedzą odbędzie się w pomiędzy &lt;b&gt;16 a 18 Maja w Poznaniu&lt;/b&gt;.&lt;br /&gt;&lt;div&gt;Dzisiaj na twitterze szumu narobił nowy film promocyjny podsumowujący zeszłoroczną edycję:&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;b&gt;The laws of GeeCON&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&#39;allowfullscreen&#39; webkitallowfullscreen=&#39;webkitallowfullscreen&#39; mozallowfullscreen=&#39;mozallowfullscreen&#39; width=&#39;320&#39; height=&#39;266&#39; src=&#39;https://www.youtube.com/embed/8MTNrOPG6os?feature=player_embedded&#39; frameborder=&#39;0&#39; /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Jak widać warto tam być! W tym roku wśród gwiazd konferencji znajdą się:&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Bruce Eckel&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Gavin King&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Ivar Jacobson&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Adam Bien&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Kevlin Henney&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Pete Muir&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;a z polskich znanych twarzy:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Jacek Laskowski&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Dawid Weiss&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Tomek Kaczanowski&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;Piotr Walczyszyn&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;a href=&quot;http://2012.geecon.org/speakers&quot; target=&quot;_blank&quot;&gt;i inni .. ;-)&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://2012.geecon.org/schedule&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;Schedule&lt;/b&gt;&lt;/a&gt; jest już znany, więc można powoli planować ścieżkę prezentacji podczas konferencji.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Jak ktoś już się zapisał to można sobie na bloga wrzucić ładnego &lt;a href=&quot;http://2012.geecon.org/banners&quot; target=&quot;_blank&quot;&gt;bannerka&lt;/a&gt; :-)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Do zobaczenia!&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;</description><link>http://blog.lstachowiak.pl/2012/03/geecon-2012-film.html</link><author>noreply@blogger.com (Anonymous)</author><thr:total>0</thr:total></item><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=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;a href=&quot;http://upload.wikimedia.org/wikipedia/en/archive/8/85/20090127225152!Scala_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;46&quot; src=&quot;http://upload.wikimedia.org/wikipedia/en/archive/8/85/20090127225152!Scala_logo.png&quot; width=&quot;320&quot; /&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=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Scala ostatnio robi się dość popularna, więc warto przyjść i &quot;liznąć&quot; trochę z tego języka. Bez przedłużania dane szczegółowe:&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Data: &lt;b&gt;09.07.2011 (sobota)&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Godzina: &lt;b&gt;10:00&lt;/b&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;Rejestracja:&amp;nbsp;&lt;b&gt;&lt;a href=&quot;http://oiola.com/e/738-warsztaty-z-jezyka-scala/reg/&quot;&gt;tutaj&lt;/a&gt;&amp;nbsp;(wymagana, liczba miejsc ograniczona!)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Wymagane jest posiadanie własnego laptopa (prosimy zabrać listwy zasilające;) z JDK 6.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Opis warsztatów nadesłany od autora:&lt;/div&gt;&lt;blockquote&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;Zakres: od podstaw do .... - nie wiem, zależy na ile czas&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;pozwoli.Poniżej kolejne tematy które mogłyby być omawiane, ale nie&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;wydaje mi się żeby było możliwe omówienie wszystkiego - ze względów&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;czasowych: wprowadzenie, podstawy składni, podstawowe typy danych,&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;wyrażenia sterujące, klasy, cechy, metody, obiekty, typy ogólne,&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;standardowe typy ogólne, funkcje, dopasowywanie wzorców, klasy i&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;obiekty przypadków, pakiety, klauzule importu, uprawnienia, wyjątki i&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;wyrażenie return, modyfikator implicit, kolekcje, pętla for, XML,&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;programowanie interfejsów graficznych, programowanie współbieżne,&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-size: 12px;&quot;&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;</description><link>http://blog.lstachowiak.pl/2011/07/poznan-jug-warsztaty-z-jezyka-scala.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total></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#">Java 7</category><category domain="http://www.blogger.com/atom/ns#">programowanie</category><title>(Prawdopodobnie ostatnie) Podsumowanie nowości w Java 7</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-8IpObTKwMhI/Sbzz9OuVopI/AAAAAAAADDM/TLLVOTBiNZA/s1600/duke.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-8IpObTKwMhI/Sbzz9OuVopI/AAAAAAAADDM/TLLVOTBiNZA/s1600/duke.png&quot; /&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=&quot;http://blog.lstachowiak.pl/search/label/Java%207&quot;&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=&quot;http://www.jcp.org/en/jsr/detail?id=336&quot;&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=&quot;http://blog.lstachowiak.pl/search/label/Java%207&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Collections.emptyIterator()&lt;/span&gt; oraz &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Collection&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: nowrap;&quot;&gt;s.&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;white-space: nowrap;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;http://jcp.org/en/jsr/detail?id=203&quot;&gt;JSR 203&lt;/a&gt; :-) Wsparcie dla POSIX i ACL, nowy pakiet &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;http://jcp.org/en/jsr/summary?id=334&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;tym wiadomo dodatki/usprawnienia w API (w tym już chyba sławny&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px;&quot;&gt;&lt;em style=&quot;font-style: normal;&quot;&gt;java&lt;/em&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px;&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px;&quot;&gt;&lt;em style=&quot;font-style: normal;&quot;&gt;util&lt;/em&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 19px;&quot;&gt;&lt;em style=&quot;font-style: normal;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Objects&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;java.util.logging&lt;/span&gt;,&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;java.util.regex&lt;/span&gt;, &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;java.net&lt;/span&gt;, JMX, &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;http://jcp.org/en/jsr/detail?id=337&quot;&gt;Javy 8&lt;/a&gt;... :-/</description><link>http://blog.lstachowiak.pl/2011/06/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></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#">Hadoop</category><category domain="http://www.blogger.com/atom/ns#">Java</category><category domain="http://www.blogger.com/atom/ns#">programowanie</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=&quot;http://netbeans.org/&quot;&gt;NetBeansa&lt;/a&gt; i polecam wtyczkę &lt;a href=&quot;http://www.karmasphere.com/Download/register-for-community-edition.html&quot;&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 &#39;update sites&#39; 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=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;br /&gt;  xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&amp;gt;&lt;br /&gt;    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;groupId&amp;gt;pl.lstachowiak&amp;lt;/groupId&amp;gt;&lt;br /&gt;    &amp;lt;artifactId&amp;gt;HadoopSamples&amp;lt;/artifactId&amp;gt;&lt;br /&gt;    &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;&lt;br /&gt;    &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;name&amp;gt;HadoopSamples&amp;lt;/name&amp;gt;&lt;br /&gt;    &amp;lt;url&amp;gt;http://blog.lstachowiak.pl&amp;lt;/url&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;properties&amp;gt;&lt;br /&gt;        &amp;lt;project.build.sourceEncoding&amp;gt;UTF-8&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;br /&gt;    &amp;lt;/properties&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;dependencies&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;junit&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;junit&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;4.8&amp;lt;/version&amp;gt;&lt;br /&gt;            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;org.apache.mahout.hadoop&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;hadoop-core&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;0.20.1&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;        &amp;lt;dependency&amp;gt;&lt;br /&gt;            &amp;lt;groupId&amp;gt;commons-logging&amp;lt;/groupId&amp;gt;&lt;br /&gt;            &amp;lt;artifactId&amp;gt;commons-logging&amp;lt;/artifactId&amp;gt;&lt;br /&gt;            &amp;lt;version&amp;gt;1.1.1&amp;lt;/version&amp;gt;&lt;br /&gt;        &amp;lt;/dependency&amp;gt;&lt;br /&gt;    &amp;lt;/dependencies&amp;gt;&lt;br /&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-K4K4n7LgVYc/Tf2-HULOJ3I/AAAAAAAAECQ/er6OzwuYfXM/s1600/MapReduceSample1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;121&quot; src=&quot;http://2.bp.blogspot.com/-K4K4n7LgVYc/Tf2-HULOJ3I/AAAAAAAAECQ/er6OzwuYfXM/s640/MapReduceSample1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Czyli:&lt;br /&gt;- Hadoop wczytuje i dzieli plik na tzw &#39;&lt;b&gt;input splits&lt;/b&gt;&#39;&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=&quot;java&quot; name=&quot;code&quot;&gt;package pl.lstachowiak.hadoop.sample1;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import org.apache.hadoop.io.IntWritable;&lt;br /&gt;import org.apache.hadoop.io.LongWritable;&lt;br /&gt;import org.apache.hadoop.io.Text;&lt;br /&gt;import org.apache.hadoop.mapreduce.Mapper;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class HttpMethodMapper extends Mapper&amp;lt;LongWritable, Text, Text, IntWritable&amp;gt; { // 1&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {&lt;br /&gt;        HttpMethod method = getMethodFromLine(value); // 2&lt;br /&gt;        context.write(new Text(method.name()), new IntWritable(1)); // 3&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    HttpMethod getMethodFromLine(Text value) {&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.CONNECT.name()) != -1) {&lt;br /&gt;            return HttpMethod.CONNECT;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.DELETE.name()) != -1) {&lt;br /&gt;            return HttpMethod.DELETE;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.GET.name()) != -1) {&lt;br /&gt;            return HttpMethod.GET;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.HEAD.name()) != -1) {&lt;br /&gt;            return HttpMethod.HEAD;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.OPTIONS.name()) != -1) {&lt;br /&gt;            return HttpMethod.OPTIONS;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.PATH.name()) != -1) {&lt;br /&gt;            return HttpMethod.PATH;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.POST.name()) != -1) {&lt;br /&gt;            return HttpMethod.POST;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.PUT.name()) != -1) {&lt;br /&gt;            return HttpMethod.PUT;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        if (value.find(HttpMethod.TRACE.name()) != -1) {&lt;br /&gt;            return HttpMethod.TRACE;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        return HttpMethod.UNKNOWN;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&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=&quot;java&quot; name=&quot;code&quot;&gt;package pl.lstachowiak.hadoop.sample1;&lt;br /&gt;&lt;br /&gt;import java.io.IOException;&lt;br /&gt;import org.apache.hadoop.io.IntWritable;&lt;br /&gt;import org.apache.hadoop.io.Text;&lt;br /&gt;import org.apache.hadoop.mapreduce.Reducer;&lt;br /&gt;import org.apache.hadoop.mapreduce.Reducer.Context;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class HttpMethodReducer extends Reducer&amp;lt;Text, IntWritable, Text, IntWritable&amp;gt; { // 1&lt;br /&gt;&lt;br /&gt;    @Override&lt;br /&gt;    protected void reduce(Text key, Iterable&amp;lt;IntWritable&amp;gt; values, Context context) throws IOException, InterruptedException { // 2&lt;br /&gt;        int counter = countValues(values); // 3&lt;br /&gt;        context.write(key, new IntWritable(counter)); // 4&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &amp;lt;T&amp;gt; int countValues(Iterable&amp;lt;T&amp;gt; values) {&lt;br /&gt;        int counter = 0;&lt;br /&gt;        for (T value : values) {&lt;br /&gt;            counter++;&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        return counter;&lt;br /&gt;    }&lt;br /&gt;}&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=&quot;java&quot; name=&quot;code&quot;&gt;package pl.lstachowiak.hadoop.sample1;&lt;br /&gt;&lt;br /&gt;import org.apache.hadoop.fs.Path;&lt;br /&gt;import org.apache.hadoop.io.IntWritable;&lt;br /&gt;import org.apache.hadoop.io.Text;&lt;br /&gt;import org.apache.hadoop.mapreduce.Job;&lt;br /&gt;import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;&lt;br /&gt;import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;public class HttpMethodJob {&lt;br /&gt;    &lt;br /&gt;    public static void main(String[] args) throws Exception {&lt;br /&gt;        &lt;br /&gt;        if (args.length != 2) {&lt;br /&gt;            System.err.println(&quot;Usage: HttpMethodJob &amp;lt;input path&amp;gt; &amp;lt;output path&amp;gt;&quot;);&lt;br /&gt;            System.exit(-1);&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;        Job job = new Job();&lt;br /&gt;        job.setJarByClass(HttpMethodJob.class); // 1&lt;br /&gt;        &lt;br /&gt;        FileInputFormat.addInputPath(job, new Path(args[0])); // 2&lt;br /&gt;        FileOutputFormat.setOutputPath(job, new Path(args[1])); // 3&lt;br /&gt;        &lt;br /&gt;        job.setMapperClass(HttpMethodMapper.class); // 4&lt;br /&gt;        job.setReducerClass(HttpMethodReducer.class); // 5&lt;br /&gt;        &lt;br /&gt;        job.setOutputKeyClass(Text.class); // 6&lt;br /&gt;        job.setOutputValueClass(IntWritable.class); // 7&lt;br /&gt;        &lt;br /&gt;        System.exit(job.waitForCompletion(true) ? 0 : 1); // gogogo!&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;}&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=&quot;http://www.twoquail.com/logs/access.log&quot;&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 &#39;Hadoop Job from pre-existing JAR file&#39;.&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-JB4NEyIekpg/Tf3L6_XfDdI/AAAAAAAAECU/1gLIc1HVw10/s1600/newHadoopJob1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;277&quot; src=&quot;http://2.bp.blogspot.com/-JB4NEyIekpg/Tf3L6_XfDdI/AAAAAAAAECU/1gLIc1HVw10/s400/newHadoopJob1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Następnie wpisujemy ścieżkę do JARa (ja podałem z targeta) oraz klasę z funkcją main.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-NYysWy9xCGA/Tf3MWDTX1pI/AAAAAAAAECY/lqNirsQqdrE/s1600/newHadoopJob2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;213&quot; src=&quot;http://2.bp.blogspot.com/-NYysWy9xCGA/Tf3MWDTX1pI/AAAAAAAAECY/lqNirsQqdrE/s400/newHadoopJob2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-E-JqVPewTCg/Tf3MrnM6ObI/AAAAAAAAECc/iRXyfx3LH_0/s1600/newHadoopJob3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;212&quot; src=&quot;http://4.bp.blogspot.com/-E-JqVPewTCg/Tf3MrnM6ObI/AAAAAAAAECc/iRXyfx3LH_0/s400/newHadoopJob3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;I klikamy &#39;finish&#39; :-)&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Teraz możemy odpalać!&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Prawy guzik na nowego Joba -&amp;gt; Run Job -&amp;gt; Run.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&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&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient: Counters: 12&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:   FileSystemCounters&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     FILE_BYTES_READ=18153346&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     FILE_BYTES_WRITTEN=9462349&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:   Map-Reduce Framework&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Reduce input groups=4&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Combine output records=0&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Map input records=17484&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Reduce shuffle bytes=0&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Reduce output records=4&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Spilled Records=34968&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Map output bytes=142014&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Combine input records=0&lt;br /&gt;11/06/19 11:53:26 INFO mapred.JobClient:     Map output records=17484&lt;br /&gt;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&lt;br /&gt;HEAD 1744&lt;br /&gt;POST 398&lt;br /&gt;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=&quot;https://bitbucket.org/lstachowiak/hadoopsamples&quot;&gt;tutaj&lt;/a&gt;.</description><link>http://blog.lstachowiak.pl/2011/06/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></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=&quot;http://www.jug.poznan.pl/materialy-ze-spotkan/materialy/1-poznanski-code-retreat/&quot;&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=&quot;http://bloggodiscover.wordpress.com/&quot;&gt;Zbigniew Wantuch&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;Zapraszam do obejrzenia:&lt;br /&gt;&lt;p&gt;&lt;embed src=&quot;http://blip.tv/play/AYK_hV0C&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;480&quot; height=&quot;306&quot; wmode=&quot;transparent&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; &gt;&lt;/embed&gt;&lt;/p&gt;&lt;br /&gt;Źródło: &lt;a href=&quot;http://www.jug.poznan.pl/2011/06/video-z-pierwszego-poznanskiego-code-retreat/&quot;&gt;Poznań JUG&lt;/a&gt;</description><link>http://blog.lstachowiak.pl/2011/06/wideo-z-poznanskiego-code-retreat.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>1</thr:total></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#">Hadoop</category><category domain="http://www.blogger.com/atom/ns#">linux</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><title>Szybka instalacja Apache Hadoop dzięki dystrybucji Cloudera</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-mR9bdgeq7n8/Tfj5vy6_IhI/AAAAAAAAD_k/aTjxkg2cE3k/s1600/hadoop-logo.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-mR9bdgeq7n8/Tfj5vy6_IhI/AAAAAAAAD_k/aTjxkg2cE3k/s1600/hadoop-logo.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Mając w pamięci trudne doświadczenia z czasów studiów z &lt;a href=&quot;http://hadoop.apache.org/&quot;&gt;frameworkiem Hadoop&lt;/a&gt;, postanowiłem wrócić do tematu dzięki &lt;a href=&quot;http://ciurana.eu/GeeCON-2011/&quot;&gt;prezentacji Eugiene Ciurana&lt;/a&gt; podczas tegorocznego &lt;a href=&quot;http://geecon.org/&quot;&gt;GeeCONa&lt;/a&gt;. Eugienie opowiedział trochę o firmie&amp;nbsp;&lt;a href=&quot;http://www.cloudera.com/&quot;&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&lt;br /&gt;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&lt;br /&gt;apt-cache search hadoop&lt;br /&gt;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&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient: Counters: 14&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:   FileSystemCounters&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     FILE_BYTES_READ=1642249&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     FILE_BYTES_WRITTEN=2108417&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:   Map-Reduce Framework&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Reduce input groups=2&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Combine output records=0&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Map input records=10&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Reduce shuffle bytes=0&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Reduce output records=0&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Spilled Records=40&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Map output bytes=180&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Map input bytes=240&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Combine input records=0&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Map output records=20&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     SPLIT_RAW_BYTES=1110&lt;br /&gt;11/06/15 21:09:07 INFO mapred.JobClient:     Reduce input records=20&lt;br /&gt;Job Finished in 2.361 seconds&lt;br /&gt;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!</description><link>http://blog.lstachowiak.pl/2011/06/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>1</thr:total></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#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">konferencje</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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-s6Dww106DZI/Td1sSVij7PI/AAAAAAAAD_E/HwmyymFi_1I/s1600/eclipse-demo-camp-final-2011.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;http://1.bp.blogspot.com/-s6Dww106DZI/Td1sSVij7PI/AAAAAAAAD_E/HwmyymFi_1I/s400/eclipse-demo-camp-final-2011.png&quot; width=&quot;282&quot; /&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=&quot;http://wiki.eclipse.org/Eclipse_DemoCamps_Indigo_2011/Poznan&quot;&gt;link&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Rejestracja&lt;/b&gt;:&amp;nbsp;&lt;a href=&quot;http://oiola.com/e/732-8-eclipse-democamp-poznan/&quot;&gt;link&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Do zobaczenia!</description><link>http://blog.lstachowiak.pl/2011/05/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></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#">skalowalność</category><category domain="http://www.blogger.com/atom/ns#">Spring Framework</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=&quot;http://blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;@Cacheable&lt;/span&gt; oraz &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;java&quot; name=&quot;code&quot;&gt;@Cacheable(&quot;something&quot;)&lt;br /&gt;public List&amp;lt;Object&amp;gt; getMeSomething(String param) {&lt;br /&gt; // ...&lt;br /&gt;}&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=&quot;java&quot; name=&quot;code&quot;&gt;@Cacheable(value=&quot;magic&quot;, key=&quot;magicDto.id&quot;)&lt;br /&gt;public List&amp;lt;Object&amp;gt; getSomethingMore(MagicDto magicDto) {&lt;br /&gt; // ..&lt;br /&gt;}&lt;/pre&gt;Dla wielu parametrów:&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;@Cacheable(value=&quot;magic&quot;, key=&quot;param2&quot;)&lt;br /&gt;public List&amp;amp;ls;Object&amp;gt; getSomething(String param1, int param2, boolean param3) {&lt;br /&gt; // ..&lt;br /&gt;}&lt;/pre&gt;Możliwe jest także wykorzystanie dowolnej metody do wyliczenia klucza:&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;@Cacheable(value=&quot;magic&quot;, key=&quot;T(myKeyGenerator).getKey(param2)&quot;)&lt;br /&gt;public List&amp;amp;ls;Object&amp;gt; getSomething(String param1, int param2, boolean param3) {&lt;br /&gt; // ..&lt;br /&gt;}&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;condition&lt;/span&gt;&lt;/i&gt; można zdefiniować warunek, kiedy wyniki mają zostać cachowane:&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;@Cacheable(value=&quot;something&quot;, condition=&quot;param.length &amp;gt; 1024&quot;)&lt;br /&gt;public List&amp;lt;Object&amp;gt; getSomething(String param) {&lt;br /&gt; return Collections.emptyList();&lt;br /&gt;}&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;@CacheEvict&lt;/span&gt;.&lt;br /&gt;&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;@CacheEvict(value=&quot;magicCache&quot;, allEntries=true)&lt;br /&gt;public void clearMyCache(int param1) {&lt;br /&gt;        //...&lt;br /&gt;}&lt;/pre&gt;Jako &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;code&quot; class=&quot;xml&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;br /&gt; &amp;nbsp; xmlns:cache=&quot;http://www.springframework.org/schema/cache&quot;&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd&lt;br /&gt; &amp;nbsp; http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd&quot;&amp;gt;&lt;br /&gt;&lt;br /&gt; &amp;nbsp; &amp;lt;cache:annotation-driven /&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/beans&amp;gt;&lt;/pre&gt;Domyślnie w Springa wbudowana jest obsługa dwóch &quot;fizycznych&quot; cache:&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: monospace;&quot;&gt;ConcurrentMap&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;Aby skorzystać z ehcache we własnej aplikacji trzeba dopisać jeszcze dwie linie:&lt;/span&gt;&lt;br /&gt;&lt;pre class=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;!-- konfiguracja springowego CacheManagera --&amp;gt;&lt;br /&gt;&amp;lt;bean id=&quot;cacheManager&quot; class=&quot;org.springframework.cache.ehcache.EhcacheCacheManager&quot; p:cache-manager=&quot;ehcache&quot;/&amp;gt;&lt;br /&gt;&amp;lt;!-- konfiguracja ehcache --&amp;gt;&lt;br /&gt;&amp;lt;bean id=&quot;ehcache&quot; class=&quot;org.springframework.cache.ehcache.EhCacheManagerFactoryBean&quot; p:config-location=&quot;ehcache.xml&quot;/&amp;gt;&lt;br /&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ą....</description><link>http://blog.lstachowiak.pl/2011/02/caching-abstract-w-spring-framework-31.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>2</thr:total></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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/TKD9fAsZl7I/AAAAAAAAD78/-FPIkab2C2c/s1600/coherence_node_start.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;404&quot; src=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/TKD9fAsZl7I/AAAAAAAAD78/-FPIkab2C2c/s640/coherence_node_start.png&quot; width=&quot;640&quot; /&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;/bin/&lt;/span&gt; instalacji jest dostępny skrypt &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt; -ttl 0&lt;/span&gt;:&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/TKEFjPTLVbI/AAAAAAAAD8A/V_mM-FX6UNs/s1600/coherence_multicast_test.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;187&quot; src=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/TKEFjPTLVbI/AAAAAAAAD8A/V_mM-FX6UNs/s640/coherence_multicast_test.png&quot; width=&quot;640&quot; /&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;cache-server&lt;/span&gt; dodać wpis dla parametrów &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;JAVA_OPTS&lt;/span&gt;:&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Group&lt;/span&gt; podczas uruchamiania węzła znajdować się będzie sekcja &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;WellKnownAddressesList&lt;/span&gt;, np:&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;WellKnownAddressList(Size=1,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;WKA{Address=192.168.0.2, Port=8088}&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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;</description><link>http://blog.lstachowiak.pl/2010/09/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></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#">programowanie</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</category><title>Oracle Coherence - działający przykład</title><description>Po &lt;a href=&quot;http://blog.lstachowiak.pl/2010/08/oracle-coherence-zabawy-z-in-memory.html&quot;&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=&quot;http://www.oracle.com/technetwork/middleware/coherence/overview/index.html&quot;&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=&quot;java&quot; name=&quot;code&quot;&gt;package pl.lstachowiak.coherence.example1;&lt;br /&gt;&lt;br /&gt;import java.io.Serializable;&lt;br /&gt;import java.math.BigDecimal;&lt;br /&gt;&lt;br /&gt;public class Employee implements Serializable, Comparable {&lt;br /&gt;&lt;br /&gt; private int id;&lt;br /&gt; private String name;&lt;br /&gt; private String surname;&lt;br /&gt; private BigDecimal salary;&lt;br /&gt; private String city;&lt;br /&gt;&lt;br /&gt; public Employee() {&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Employee(int id, String name, String surname,&lt;br /&gt;     BigDecimal salary, String city) {&lt;br /&gt;  this.id = id;&lt;br /&gt;  this.name = name;&lt;br /&gt;  this.surname = surname;&lt;br /&gt;  this.salary = salary;&lt;br /&gt;  this.city = city;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public String getCity() {&lt;br /&gt;  return city;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setCity(String city) {&lt;br /&gt;  this.city = city;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public int getId() {&lt;br /&gt;  return id;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setId(int id) {&lt;br /&gt;  this.id = id;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public String getName() {&lt;br /&gt;  return name;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setName(String name) {&lt;br /&gt;  this.name = name;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public BigDecimal getSalary() {&lt;br /&gt;  return salary;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setSalary(BigDecimal salary) {&lt;br /&gt;  this.salary = salary;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public String getSurname() {&lt;br /&gt;  return surname;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void setSurname(String surname) {&lt;br /&gt;  this.surname = surname;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; @Override&lt;br /&gt; public String toString() {&lt;br /&gt;  return &quot;Employee{&quot; + &quot;id=&quot; + id + &quot; name=&quot; + name + &quot; surname=&quot;&lt;br /&gt;    + surname + &quot; salary=&quot; + salary + &quot; city=&quot; + city + &#39;}&#39;;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public int compareTo(Object o) {&lt;br /&gt;  Employee other = (Employee) o;&lt;br /&gt;  if (id &amp;gt; other.id) {&lt;br /&gt;   return 1;&lt;br /&gt;  } else if (id &amp;lt; other.id) {&lt;br /&gt;   return -1;&lt;br /&gt;  } else {&lt;br /&gt;   return 0;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&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=&quot;java&quot; name=&quot;code&quot;&gt;package pl.lstachowiak.coherence.example1;&lt;br /&gt;&lt;br /&gt;import com.tangosol.net.CacheFactory;&lt;br /&gt;import com.tangosol.net.NamedCache;&lt;br /&gt;import java.math.BigDecimal;&lt;br /&gt;import java.util.Map;&lt;br /&gt;import java.util.Set;&lt;br /&gt;&lt;br /&gt;public class CoherenceExample1 {&lt;br /&gt;&lt;br /&gt;    public static void main(String[] args) {&lt;br /&gt;  // #1&lt;br /&gt;        NamedCache employees = CacheFactory.getCache(&quot;employees&quot;);&lt;br /&gt;&lt;br /&gt;  // #2&lt;br /&gt;  employees.put(1, new Employee(1, &quot;John&quot;, &quot;Travolta&quot;, new BigDecimal(300000.0), &quot;New York&quot;));&lt;br /&gt;  employees.put(2, new Employee(2, &quot;Jason&quot;, &quot;Statham&quot;, new BigDecimal(550000.0), &quot;Chicago&quot;));&lt;br /&gt;  employees.put(3, new Employee(3, &quot;Sylvester&quot;, &quot;Stalone&quot;, new BigDecimal(600000.0), &quot;Miami&quot;));&lt;br /&gt;  employees.put(4, new Employee(4, &quot;Bruce&quot;, &quot;Willis&quot;, new BigDecimal(780000.0), &quot;Los Angeles&quot;));&lt;br /&gt;  employees.put(5, new Employee(5, &quot;Chuck&quot;, &quot;Norris&quot;, new BigDecimal(1300000.0), &quot;Kansas&quot;));&lt;br /&gt;  employees.put(6, new Employee(6, &quot;Steven&quot;, &quot;Seagal&quot;, new BigDecimal(20100.0), &quot;Lansing&quot;));&lt;br /&gt;&lt;br /&gt;  // #3&lt;br /&gt;  System.out.println(&quot;Pracownik o ID=1: &quot; + employees.get(1));&lt;br /&gt;  System.out.println(&quot;Rozmiar cache: &quot; + employees.size());&lt;br /&gt;  System.out.println(&quot;Usuwam: &quot; + employees.remove(5));&lt;br /&gt;  System.out.println(&quot;Rozmiar cache: &quot; + employees.size());&lt;br /&gt;&lt;br /&gt;  // #4&lt;br /&gt;  Set&amp;lt;Map.Entry&amp;gt; entries = employees.entrySet();&lt;br /&gt;  for (Map.Entry entry : entries) {&lt;br /&gt;   System.out.println(entry.getKey() + &quot;: &quot; + entry.getValue());&lt;br /&gt;  }&lt;br /&gt;    }&lt;br /&gt;}&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=&quot;http://download.oracle.com/docs/cd/E15357_01/coh.360/e15725/com/tangosol/net/CacheFactory.html&quot;&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=&quot;http://download.oracle.com/docs/cd/E15357_01/coh.360/e15725/com/tangosol/net/NamedCache.html&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_QQi5tGIQ1eA/TIu4Of2WUrI/AAAAAAAAD74/Dr04nCR1ADU/s1600/coherence_example1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;313&quot; src=&quot;http://4.bp.blogspot.com/_QQi5tGIQ1eA/TIu4Of2WUrI/AAAAAAAAD74/Dr04nCR1ADU/s640/coherence_example1.png&quot; width=&quot;640&quot; /&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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.</description><link>http://blog.lstachowiak.pl/2010/09/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></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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_QQi5tGIQ1eA/TDntbWewOEI/AAAAAAAAD64/IQ29JNaH0Qk/s1600/coherence-grid.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;http://2.bp.blogspot.com/_QQi5tGIQ1eA/TDntbWewOEI/AAAAAAAAD64/IQ29JNaH0Qk/s400/coherence-grid.png&quot; width=&quot;393&quot; /&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=&quot;http://www.oracle.com/technetwork/middleware/coherence/downloads/index.html&quot;&gt;Oracle Coherence Download&lt;/a&gt;&amp;nbsp;pobieramy paczkę &quot;&lt;i&gt;Oracle Coherence for Java Version 3.6.0&lt;/i&gt;&quot; i rozpakowujemy gdzie nam pasuje. Następnie uruchamiamy konsolę, przechodzimy do katalogu &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;coherence/bin&lt;/span&gt; i uruchamiamy skrypt &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;cache-server&lt;/span&gt;. Po chwili powinien pojawić się napis &quot;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Started DefaultCacheServer...&lt;/span&gt;&quot; - 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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;coherence&lt;/span&gt;. Na konsoli uruchomionego wcześniej węzła powinno na końcu pojawić się coś w stylu: &quot;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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;&quot;. 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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;put [klucz] [wartosc]&lt;/span&gt;, aby wyciągnąć &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;get [klucz]&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: inherit;&quot;&gt;, aby wyp&lt;/span&gt;isać całą zawartość cache należy wpisać &lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;list&lt;/span&gt;. Poniżej zamieszczam bardzo prostą sesję z użyciem Coherence:&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_QQi5tGIQ1eA/TGBNofsJvVI/AAAAAAAAD7Q/cr_YSHF-Ooo/s1600/coherence_console_session.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;400&quot; src=&quot;http://4.bp.blogspot.com/_QQi5tGIQ1eA/TGBNofsJvVI/AAAAAAAAD7Q/cr_YSHF-Ooo/s400/coherence_console_session.png&quot; width=&quot;313&quot; /&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;</description><link>http://blog.lstachowiak.pl/2010/08/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></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=&quot;http://www.geecon.org/&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/TDX4mTC2UUI/AAAAAAAAD60/BJxTeK04Lyc/s1600/geecon-cracov-2011.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/TDX4mTC2UUI/AAAAAAAAD60/BJxTeK04Lyc/s1600/geecon-cracov-2011.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Już teraz zapraszam serdecznie, bo znowu będzie baaaaardzo ciekawie :)&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;ps. to chyba pierwszy news w sieci o GeeCONie 2011 :)&lt;/div&gt;</description><link>http://blog.lstachowiak.pl/2010/07/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></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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSKxH6qX4I/AAAAAAAAD6Y/pEBH9j-JK38/s1600/rand_httpdefaults.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;260&quot; src=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSKxH6qX4I/AAAAAAAAD6Y/pEBH9j-JK38/s400/rand_httpdefaults.png&quot; width=&quot;400&quot; /&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSOR8iS-hI/AAAAAAAAD6c/v3c0XSpYUr8/s1600/rand_randvariable.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;176&quot; src=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/TBSOR8iS-hI/AAAAAAAAD6c/v3c0XSpYUr8/s400/rand_randvariable.png&quot; width=&quot;400&quot; /&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=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;${[&lt;/span&gt;&lt;i&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;Nazwa zmiennej]&lt;/span&gt;&lt;/i&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;}&lt;/span&gt;.&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_QQi5tGIQ1eA/TBSPPJhbfmI/AAAAAAAAD6g/4I4SrqJXY6I/s1600/rand_request.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;336&quot; src=&quot;http://2.bp.blogspot.com/_QQi5tGIQ1eA/TBSPPJhbfmI/AAAAAAAAD6g/4I4SrqJXY6I/s400/rand_request.png&quot; width=&quot;400&quot; /&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/TBSRtRmW5UI/AAAAAAAAD6k/P3DDQ6aldVQ/s1600/rand_jdbcrequest.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;202&quot; src=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/TBSRtRmW5UI/AAAAAAAAD6k/P3DDQ6aldVQ/s400/rand_jdbcrequest.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;I w wielu innych miejscach gdzie potrzebna jest losowa wartość ;)</description><link>http://blog.lstachowiak.pl/2010/06/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>1</thr:total></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#">db2</category><category domain="http://www.blogger.com/atom/ns#">skalowalność</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=&quot;http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAPGQk2yo-I/AAAAAAAAD6A/bJG5Rmz4k2I/s1600/Master-slavereplication-schemat.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;197&quot; src=&quot;http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAPGQk2yo-I/AAAAAAAAD6A/bJG5Rmz4k2I/s400/Master-slavereplication-schemat.png&quot; width=&quot;400&quot; /&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/_QQi5tGIQ1eA/TAPGVF1FxbI/AAAAAAAAD6I/7IbUTCxTEII/s1600/Databaseclustering-schemat.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;323&quot; src=&quot;http://4.bp.blogspot.com/_QQi5tGIQ1eA/TAPGVF1FxbI/AAAAAAAAD6I/7IbUTCxTEII/s400/Databaseclustering-schemat.png&quot; width=&quot;400&quot; /&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/TAPGTcQ7GHI/AAAAAAAAD6E/k2YupGvnz1U/s1600/Databasesharding-schemat.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;211&quot; src=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/TAPGTcQ7GHI/AAAAAAAAD6E/k2YupGvnz1U/s320/Databasesharding-schemat.png&quot; width=&quot;320&quot; /&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 &quot;dużych&quot; głównie) wprowadziły technologie, które ułatwiają skalowanie poziome. Np. w DB2 mamy &lt;a href=&quot;http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/c0021803.htm&quot;&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=&quot;http://en.wikipedia.org/wiki/ACID&quot;&gt;ACID&lt;/a&gt;.&lt;/div&gt;&lt;/div&gt;</description><link>http://blog.lstachowiak.pl/2010/05/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>5</thr:total></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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/TAKY_hLmF6I/AAAAAAAAD5w/4c5_fowhDPc/s1600/Skalowanepionowe-schemat.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;307&quot; src=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/TAKY_hLmF6I/AAAAAAAAD5w/4c5_fowhDPc/s400/Skalowanepionowe-schemat.png&quot; width=&quot;400&quot; /&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAKbhTCMe1I/AAAAAAAAD54/V66PtaGgScA/s1600/Skalowaniepoziome-schemat.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;231&quot; src=&quot;http://2.bp.blogspot.com/_QQi5tGIQ1eA/TAKbhTCMe1I/AAAAAAAAD54/V66PtaGgScA/s400/Skalowaniepoziome-schemat.png&quot; width=&quot;400&quot; /&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=&quot;http://highscalability.com/blog/2010/3/23/digg-4000-performance-increase-by-sorting-in-php-rather-than.html&quot;&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=&quot;http://highscalability.com/&quot;&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;</description><link>http://blog.lstachowiak.pl/2010/05/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></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=&quot;http://blog.lstachowiak.pl/2010/05/spotkanie-poznan-jug-processing.html&quot;&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=&quot;http://javafx.com/&quot;&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&lt;br /&gt;at sun.plugin2.applet.JNLP2Manager.initialize(Unknown Source)&lt;br /&gt;at sun.plugin2.main.client.PluginMain.initManager(Unknown Source)&lt;br /&gt;at sun.plugin2.main.client.PluginMain.access$300(Unknown Source)&lt;br /&gt;at sun.plugin2.main.client.PluginMain$2.run(Unknown Source)&lt;br /&gt;at java.lang.Thread.run(Unknown Source)&lt;br /&gt;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=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;jnlp spec=&quot;1.0+&quot; codebase=&quot;http://localhost:8082/servlet/org.netbeans.modules.javafx.project.JnlpDownloadServlet/I%3A/workspace/NetBeans/WebSiteJavaFx/dist/&quot; href=&quot;website_browser.jnlp&quot;&amp;gt;&lt;br /&gt;    &amp;lt;information&amp;gt;&lt;br /&gt;        &amp;lt;title&amp;gt;website&amp;lt;/title&amp;gt;&lt;br /&gt;        &amp;lt;vendor&amp;gt;wookasz&amp;lt;/vendor&amp;gt;&lt;br /&gt;        &amp;lt;homepage href=&quot;http://localhost:8082/servlet/org.netbeans.modules.javafx.project.JnlpDownloadServlet/I%3A/workspace/NetBeans/WebSiteJavaFx/dist/&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;description&amp;gt;website&amp;lt;/description&amp;gt;&lt;br /&gt;        &amp;lt;offline-allowed/&amp;gt;&lt;br /&gt;    &amp;lt;/information&amp;gt;&lt;br /&gt;    &amp;lt;resources&amp;gt;&lt;br /&gt;        &amp;lt;j2se version=&quot;1.5+&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;extension name=&quot;JavaFX Runtime&quot; href=&quot;http://dl.javafx.com/1.3/javafx-rt.jnlp&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;jar href=&quot;website.jar&quot; main=&quot;true&quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/resources&amp;gt;&lt;br /&gt;    &amp;lt;applet-desc name=&quot;website&quot; main-class=&quot;com.sun.javafx.runtime.adapter.Applet&quot; width=&quot;700&quot; height=&quot;500&quot;&amp;gt;&lt;br /&gt;        &amp;lt;param name=&quot;MainJavaFXScript&quot; value=&quot;pl.lstachowiak.javafx.website.WebSite&quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/applet-desc&amp;gt;&lt;br /&gt;    &amp;lt;update check=&quot;always&quot;/&amp;gt;&lt;br /&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=&quot;xml&quot; name=&quot;code&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;br /&gt;&amp;lt;jnlp spec=&quot;1.0+&quot; codebase=&quot;http://lstachowiak.pl/&quot; href=&quot;website_browser.jnlp&quot;&amp;gt;&lt;br /&gt;    &amp;lt;information&amp;gt;&lt;br /&gt;        &amp;lt;title&amp;gt;website&amp;lt;/title&amp;gt;&lt;br /&gt;        &amp;lt;vendor&amp;gt;wookasz&amp;lt;/vendor&amp;gt;&lt;br /&gt;        &amp;lt;homepage href=&quot;http://lstachowiak.pl/&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;description&amp;gt;website&amp;lt;/description&amp;gt;&lt;br /&gt;        &amp;lt;offline-allowed/&amp;gt;&lt;br /&gt;    &amp;lt;/information&amp;gt;&lt;br /&gt;    &amp;lt;resources&amp;gt;&lt;br /&gt;        &amp;lt;j2se version=&quot;1.5+&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;extension name=&quot;JavaFX Runtime&quot; href=&quot;http://dl.javafx.com/1.3/javafx-rt.jnlp&quot;/&amp;gt;&lt;br /&gt;        &amp;lt;jar href=&quot;website.jar&quot; main=&quot;true&quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/resources&amp;gt;&lt;br /&gt;    &amp;lt;applet-desc name=&quot;website&quot; main-class=&quot;com.sun.javafx.runtime.adapter.Applet&quot; width=&quot;700&quot; height=&quot;500&quot;&amp;gt;&lt;br /&gt;        &amp;lt;param name=&quot;MainJavaFXScript&quot; value=&quot;pl.lstachowiak.javafx.website.WebSite&quot;/&amp;gt;&lt;br /&gt;    &amp;lt;/applet-desc&amp;gt;&lt;br /&gt;    &amp;lt;update check=&quot;always&quot;/&amp;gt;&lt;br /&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=&quot;http://lstachowiak.pl/&quot;&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ć.</description><link>http://blog.lstachowiak.pl/2010/05/dziwny-wyjatek-podczas-uruchamiania.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>3</thr:total></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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://lstachowiak.pl/poznan-jug/poznan_jug_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://lstachowiak.pl/poznan-jug/poznan_jug_logo.png&quot; /&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=&quot;http://pl.wikipedia.org/wiki/Processing&quot;&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=&quot;Apple-style-span&quot; style=&quot;-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;&quot;&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=&quot;http://marcinignac.com/blog/tag/processingorg/&quot;&gt;tag processing.org&lt;/a&gt;.&lt;br /&gt;To mi się bardzo spodobało:&lt;br /&gt;&lt;object height=&quot;300&quot; width=&quot;400&quot;&gt;&lt;param name=&quot;allowfullscreen&quot; value=&quot;true&quot; /&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot; /&gt;&lt;param name=&quot;movie&quot; value=&quot;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&quot; /&gt;&lt;embed src=&quot;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&quot; type=&quot;application/x-shockwave-flash&quot; allowfullscreen=&quot;true&quot; allowscriptaccess=&quot;always&quot; width=&quot;400&quot; height=&quot;300&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href=&quot;http://vimeo.com/4842407&quot;&gt;MSAFluid with motion tracking&lt;/a&gt; from &lt;a href=&quot;http://vimeo.com/marcinignac&quot;&gt;Marcin Ignac&lt;/a&gt; on &lt;a href=&quot;http://vimeo.com/&quot;&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=&quot;http://oiola.com/e/606-spotkanie-poznan-jug-processing-24052010/reg/&quot;&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ć ;)</description><link>http://blog.lstachowiak.pl/2010/05/spotkanie-poznan-jug-processing.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total></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=&quot;http://blog.lstachowiak.pl/&quot;&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 ;-)</description><link>http://blog.lstachowiak.pl/2010/05/zmiana-adresu-bloga-na.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total></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#">eclipse</category><category domain="http://www.blogger.com/atom/ns#">konferencje</category><title>Eclipse DemoCamp Helios 2010 - Poznań [10.06.2010]</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://wiki.eclipse.org/images/8/89/Eclipse-camp.gif&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://wiki.eclipse.org/images/8/89/Eclipse-camp.gif&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Dużo się dzieje ostatnio w Poznaniu! Bardzo dużo! &lt;a href=&quot;http://wookasz.blogspot.com/2010/05/geecon-juz-w-poznaniu.html&quot;&gt;GeeCON&lt;/a&gt;, &lt;a href=&quot;http://wookasz.blogspot.com/2010/05/spotkanie-jugsgeecon-12052010.html&quot;&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=&quot;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;&quot;&gt;&lt;li style=&quot;list-style-image: none !important; list-style-type: decimal; margin-bottom: 0.1em;&quot;&gt;Krzysztof Daniel/IBM Eclipse Support Center, EMF supports GWT or Eclipse Extended Preferences&lt;/li&gt;&lt;li style=&quot;list-style-image: none !important; list-style-type: decimal; margin-bottom: 0.1em;&quot;&gt;Krzysztof Kazmierczyk, OSGI in the cloud&lt;/li&gt;&lt;li style=&quot;list-style-image: none !important; list-style-type: decimal; margin-bottom: 0.1em;&quot;&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=&quot;http://wiki.eclipse.org/Eclipse_DemoCamps_Helios_2010/Poznan&quot;&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;</description><link>http://blog.lstachowiak.pl/2010/05/eclipse-democamp-helios-2010-poznan.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total></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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://lstachowiak.pl/poznan-jug/poznan_jug_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://lstachowiak.pl/poznan-jug/poznan_jug_logo.png&quot; /&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=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 12px; font-style: italic; line-height: 16px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&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=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 12px; font-style: italic; line-height: 16px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&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=&quot;margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;&quot; /&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=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-size: 12px; font-style: italic; line-height: 16px;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: &#39;Trebuchet MS&#39;, sans-serif;&quot;&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=&quot;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&quot;&gt;GeeCONowej mapce&lt;/a&gt;:&lt;br /&gt;&lt;iframe frameborder=&quot;0&quot; height=&quot;350&quot; marginheight=&quot;0&quot; marginwidth=&quot;0&quot; scrolling=&quot;no&quot; src=&quot;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&quot; width=&quot;425&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;small&gt;Pokaż &lt;a href=&quot;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&quot; style=&quot;color: blue; text-align: left;&quot;&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=&quot;http://oiola.com/e/598-jugsgeecon/reg/&quot;&gt;pod tym adresem&lt;/a&gt;.&lt;br /&gt;Do zobaczenia!!</description><link>http://blog.lstachowiak.pl/2010/05/spotkanie-jugsgeecon-12052010.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total></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#">geecon</category><category domain="http://www.blogger.com/atom/ns#">konferencje</category><title>GeeCON już w Poznaniu!</title><description>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://img696.imageshack.us/img696/374/20100507020.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;480&quot; src=&quot;http://img696.imageshack.us/img696/374/20100507020.jpg&quot; width=&quot;640&quot; /&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=&quot;http://2010.geecon.org/site/schedule&quot;&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=&quot;http://2010.geecon.org/site/register&quot;&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=&quot;http://2010.geecon.org/site/university&quot;&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=&quot;http://www.geecon.org/&quot;&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=&quot;http://www.geecon.org/&quot;&gt;www.geecon.org&lt;/a&gt;&lt;br /&gt;twitter:&amp;nbsp;&lt;a href=&quot;http://twitter.com/Geecon_news&quot;&gt;twitter.com/Geecon_news&lt;/a&gt;&lt;br /&gt;facebook:&amp;nbsp;&lt;a href=&quot;http://www.facebook.com/pages/GeeCON/354953985700&quot;&gt;www.facebook.com/pages/GeeCON/&lt;/a&gt;</description><link>http://blog.lstachowiak.pl/2010/05/geecon-juz-w-poznaniu.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>0</thr:total></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=&quot;http://wookasz.blogspot.com/2010/04/testy-wydajnosciowe-bazy-danych-z.html&quot;&gt;Kolejny&lt;/a&gt; wpis o &lt;a href=&quot;http://jakarta.apache.org/jmeter/&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GdObD-z2I/AAAAAAAAD3Y/fIKz_YEgMow/s1600/schemat.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;420&quot; src=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GdObD-z2I/AAAAAAAAD3Y/fIKz_YEgMow/s640/schemat.png&quot; width=&quot;640&quot; /&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=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GgdEYPAzI/AAAAAAAAD3g/4t7-V-9xz8I/s1600/jmeter_server_console.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;104&quot; src=&quot;http://3.bp.blogspot.com/_QQi5tGIQ1eA/S9GgdEYPAzI/AAAAAAAAD3g/4t7-V-9xz8I/s640/jmeter_server_console.png&quot; width=&quot;640&quot; /&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=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;JMETER_HOME/bin/jmeter.properties&lt;/span&gt;. W linii &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&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=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&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=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&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=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/S9GykpQH3vI/AAAAAAAAD3o/-J7sYG4TiGc/s1600/remote_tests_console.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;204&quot; src=&quot;http://1.bp.blogspot.com/_QQi5tGIQ1eA/S9GykpQH3vI/AAAAAAAAD3o/-J7sYG4TiGc/s640/remote_tests_console.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;W przypadku jakiś problemów polecam sprawdzić plik &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&gt;jmeter.log&lt;/span&gt; w ktalogu &lt;span style=&quot;font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;&quot;&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.</description><link>http://blog.lstachowiak.pl/2010/04/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></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 - &quot;Wydajne witryny internetowe - Przyspieszanie działania serwisów WWW&quot;</title><description>&lt;span style=&quot;font-family: inherit; font-size: small;&quot;&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=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://helion.pl/okladki/326x466/oprzep.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;http://helion.pl/okladki/326x466/oprzep.jpg&quot; width=&quot;222&quot; /&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 &quot;Wydajne witryny internetowe - Przyspieszanie działania serwisów WWW&quot;, której autorem jest &lt;a href=&quot;http://stevesouders.com/bio.php&quot;&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 &quot;dużych&quot; 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ł !</description><link>http://blog.lstachowiak.pl/2010/04/recenzja-wydajne-witryny-internetowe.html</link><author>noreply@blogger.com (WooKasZ)</author><thr:total>4</thr:total></item></channel></rss>