Category Archives: Java

[Links] Strings concatenation in Java and Groovy

Lately I had a discussion at work regarding strings concatenation in Java and Groovy. To clear the view I hit the web and found several interesting posts about it that I want to share but the truth is after reading this I know less than before ­čśë

http://www.javacodegeeks.com/2013/03/java-stringbuilder-myth-debunked.html
http://java-performance.info/primitive-types-to-string-conversion-and-string-concatenation/
http://stackoverflow.com/questions/11359333/string-concatenation-with-groovy

There is a little bit more – while searching the web I have found neat solution in latest┬áJava┬áwith a class StringJoiner┬áwhich allows programmer to forget about pluses or several <em>append()</em> calls.

Advertisements

Walidacja encji

Dzisiaj ci─ůgniemy dalej temat troch─Ö bardziej zaawansowanych zagadnie┼ä powi─ůzanych z JPA – napisz─Ö co┼Ť o walidacji encji przy u┼╝yciu JSR 303.

Walidacja encji i JSR-303

Do tej pory poruszaj─ůc temat encji skupiali┼Ťmy si─Ö g┼é├│wnie na zagadnieniach zwi─ůzanych z relacjami oraz ewentualnie na konkretnym opisaniem konkretnych w┼éa┼Ťciwo┼Ťci (np. wymuszenie mapowania na konkretny typ Javy). Jednak┼╝e do┼Ť─ç istotnym elementem ka┼╝dej aplikacji bazodanowej jest walidacja przychodz─ůcych danych. By usprawni─ç ten do┼Ť─ç cz─Östo wyst─Öpuj─ůcy proces powsta┼éa specyfikacja JSR 303 (jej protoplast─ů jest projekt hibernate-validator, kt├│ry sta┼é si─Ö od wersji czwartej implementacj─ů wzorcow─ů tej specyfikacji), kt├│rej celem jest dostarczanie jednolitego sposobu walidacji danych w klasach Javy (nie dotyczy to tylko JPA). Zainteresowanych odsy┼éam do strony specyfikacji.

Zacznijmy od prostego, dzia┼éaj─ůcego przyk┼éadu, a nast─Öpnie zajm─Ö si─Ö szczeg├│┼éami. Oczywi┼Ťcie wpierw trzeba ┼Ťci─ůgn─ů─ç odpowiedniego JARa. Obecnie najnowsz─ů wersj─ů hibernate-validator jest ju┼╝ wersja 5.0.2 ale jej nie b─Ödziemy u┼╝ywa─ç!. ┼Üci─ůgamy wersj─Ö 4.3.1 i dodajemy j─ů do bibliotek projektu. Jest to jednak┼╝e (w przypadku aplikacji konsolowej) konkretna implementacja walidatora, za┼Ť my potrzebujemy jeszcze klas, kt├│re dostarczaj─ů podstawowych adnotacji. Dlatego te┼╝ musimy zaci─ůgn─ů─ç jeszcze validation-api w wersji 1.0 (jest to wa┼╝ne, wersja 1.1 nie jest kompatybilna z hibernate-validator w wersji 4). Dzi─Öki temu b─Ödziemy u┼╝ywa─ç adnotacji oraz klas typowych dla JPA, a nie Hibernate (w ko┼äcu egzamin dotyczy czystego JPA).

Id┼║my dalej – w przyk┼éadach b─Ödziemy u┼╝ywa─ç adnotacji, dzi─Öki temu u┼éatwimy sobie robot─Ö. Jednak┼╝e istnieje jak najbardziej mo┼╝liwo┼Ť─ç korzystania z XMLa – by to osi─ůgn─ů─ç nale┼╝y umie┼Ťci─ç odpowiedni plik XML w folderze META-INF – musi on nazywa─ç si─Ö validation.xml. Na razie jednak┼╝e skupi─Ö si─Ö na adnotacjach, gdy┼╝ jest to bardziej czytelne rozwi─ůzanie. Bibliotek─Ö ju┼╝ mamy – teraz wypada┼éoby dowiedzie─ç si─Ö w jaki w og├│le spos├│b walidujemy encj─Ö?

Jest to do┼Ť─ç proste – potrzebujemy do tego obiektu o typie Validator. W ┼Ťrodowisku EE wystarczy wstrzykn─ů─ç go z u┼╝yciem adnotacji @Resource. W podawanych przeze mnie przyk┼éadach u┼╝ywamy kodu uruchamianego z konsoli, zatem musimy wykorzysta─ç klas─Ö Validation. Zach─Öcam jak zawsze do zapoznania si─Ö z dokumentacj─ů tej klasy. Kod wygl─ůda tak:

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

Tylko tyle i ju┼╝ jeste┼Ťmy w domu. Teraz zajmiemy si─Ö nasz─ů encj─ů – dla u┼éatwienia i czytelno┼Ťci przyk┼éadu dodamy walidacje do encji reprezentuj─ůcej bro┼ä. Kod wygl─ůda tak:

@Entity
public class Dragon {

    @Id
    @GeneratedValue(generator="increment")
    @GenericGenerator(name="increment", strategy = "increment")
    private Long id;
    
    @Size(min=3,max=32)
    private String name;

    
    @OneToOne(mappedBy="dragon")
    @NotNull
    private Hero rider; 
    
    
    public Dragon() { }

    // reszta pominieta dla czytelnosci

}

Jak wida─ç zosta┼éy dodane adnotacje dotycz─ůce d┼éugo┼Ťci imienia smoka, a tak┼╝e dodatkowo wymusili┼Ťmy, aby smok mia┼é zawsze je┼║d┼║ca (co akurat do tej pory przechodzi┼éo). Teraz wypada zebra─ç to wszystko do kupy.

ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();

entityManager.getTransaction().begin();
                                              
               
Hero h = new Hero();
h.setCreationDate(new Date());
h.setLevel(1);
h.setName("Chlebikowy Mag");               
               	
                		
FinanceState finances = new FinanceState();
finances.setCooper(10);
finances.setSilver(20);
finances.setGold(1);
h.setFinance(finances);
             
                
Dragon d = new Dragon();
d.setName("Smok Wawelski");				
d.setRider(h);                                  
h.setDragon(d);
                
                                
entityManager.persist(h);
entityManager.getTransaction().commit(); 

Uruchamiamy projekt i co? Ano wszystko o dziwo si─Ö zapisa┼éo. Nie uruchomili┼Ťmy r─Öcznie walidacji, za┼Ť przy uruchomieniu aplikacji ca┼éy schemat jest generowany od nowa. Zatem je┼Ťli spojrze─ç w logi zobaczymy takie co┼Ť:

Hibernate: create table Dragon (id bigint not null, name varchar(32), primary key (id))

Czyli nasza tabela wzi─Ö┼éa pod uwag─Ö maksymalny rozmiar imienia smoka. Je┼Ťli zmienimy t─Ö adnotacj─Ö (np. ustawimy maksymaln─ů d┼éugo┼Ť─ç na 50 znak├│w, w├│wczas przy ponownym zbudowaniu projektu zmieni si─Ö te┼╝ wpis w bazie danych). Je┼╝eli jednak┼╝e nasz kod troszeczk─Ö zmodyfikujemy:

Dragon d = new Dragon();
d.setName("Smok Wawelski Wielki Wspanialy i Najlepszy w Swoim Fachu Pozeracz Dziewic");				
d.setRider(h);  

W├│wczas przy pr├│bie zapisu otrzymamy taki b┼é─ůd:

Caused by: javax.validation.ConstraintViolationException: Validation failed for classes [com.wordpress.chlebik.jpa.domain.Dragon] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
	ConstraintViolationImpl{interpolatedMessage='size must be between 3 and 37', propertyPath=name, rootBeanClass=class com.wordpress.chlebik.jpa.domain.Dragon, messageTemplate='{javax.validation.constraints.Size.message}'}
]

Zasadniczo m├│wi nam to tyle, ┼╝e nasze adnotacje zadzia┼éa┼éy. Jednak┼╝e nie jest zbyt przyjemnym obs┼éugiwanie tego typu wyj─ůtk├│w – dlatego te┼╝ obecnie przed zapisaniem smoka wykorzystamy obiekt walidatora:

Dragon d = new Dragon();
d.setName("Smok Wawelski Wielki Wspanialy i Najlepszy w Swoim Fachu Pozeracz Dziewic");				
d.setRider(h);  
                
Set<ConstraintViolation<Dragon>> errors = validator.validate(d);
for( ConstraintViolation<Dragon> err : errors ) {
    System.out.println(err.getMessage());
}
                                
h.setDragon(d);
                
if( errors.isEmpty() ) {
    entityManager.persist(h);
}

W konsoli dostaniemy prosty komunikat:

size must be between 3 and 37

Nie jest to jednak┼╝e brzydki wyj─ůtek, kt├│ry trzeba obs┼éu┼╝y─ç. Na chwil─Ö obecn─ů to tyle – mamy dzia┼éaj─ůcy przyk┼éad walidacji.

Walidacja grupowa

Standardowo wszystkie adnotacje walidacyjne danej klasy otrzymuj─ů ‘dost─Öp’ o nazwie default. Dzieje si─Ö to w pe┼éni przejrzy┼Ťcie i u┼╝ytkownik nie musi o tym wiedzie─ç. Co jednak kiedy w pewnych przypadkach pewne w┼éasno┼Ťci powinny by─ç walidowane, a w innych przypadkach nie (albo te┼╝ walidatory maj─ů mie─ç inne atrybuty). Wr├│─çmy do przyk┼éadu naszego smoka – za┼é├│┼╝my, ┼╝e chcemy zasymulowa─ç sytuacj─Ö, w kt├│rej smok dopiero si─Ö rodzi (czyli wykonamy na bazie polecenie INSERT). W├│wczas zale┼╝y nam na tym, aby smok posiada┼é je┼║d┼║ca. Jednak┼╝e bohaterowi mo┼╝e si─Ö zemrze─ç i wtedy nasz smok zostaje sam. I w├│wczas chcieliby┼Ťmy ten fakt zapisa─ç w bazie (a obecnie nie mo┼╝emy, gdy┼╝ dali┼Ťmy relacji z w┼éa┼Ťcicielem adnotacj─Ö @NotNull). W├│wczas mo┼╝emy oczywi┼Ťcie r─Öcznie nie weryfikowa─ç encji, ale to rodzi tylko problemy. Co wi─Öcej (wr├│c─Ö jeszcze do tego zagadnienia) w wi─Ökszo┼Ťci aplikacji walidacja odbywa si─Ö niejawnie – automatycznie i nie wymaga ‘r─Öcznego’ uruchamiania.

Rozwi─ůzaniem tego typu problem├│w jest przypisywanie konkretnych adnotacji do ┼Ťci┼Ťle okre┼Ťlonych grup. Grupy te tworzymy po prostu tworz─ůc nowy interfejs rozszerzaj─ůcy interfejs Default o nazwie odpowiadaj─ůcej grupie. Czyli dla naszego smoka mo┼╝emy utworzy─ç dwa interfejsy (oczywi┼Ťcie w oddzielnych plikach):

import javax.validation.groups.Default;

public interface Create extends Default { }
public interface Modify extends Default { }

Dzi─Öki temu deklaracj─Ö relacji z je┼║d┼║cem mo┼╝emy teraz zapisa─ç nast─Öpuj─ůco:

 @OneToOne(mappedBy="dragon")
 @NotNull(groups=Create.class)
 @Null(groups=Modify.class)
 private Hero rider; 

Za┼Ť w kodzie aplikacji po zgodnie w┼éa┼Ťciciela smok mo┼╝e ┼╝y─ç sobie po swojemu:

entityManager.getTransaction().begin();
                
d.setRider(null);
                
Set<ConstraintViolation<Dragon>> errors = validator.validate(d, Modify.class);
for( ConstraintViolation<Dragon> err : errors ) {
  System.out.println(err.getMessage());
}
                
entityManager.getTransaction().commit(); 

Taki kod z ca┼é─ů pewno┼Ťci─ů nie spowoduje wygenerowania b┼é─Ödu. Je┼╝eli jednak drugi argument metody validate zmienimy na warto┼Ť─ç Create.class – dostaniemy komunikat o b┼é─Ödzie. Mechanizm ten jest jak wida─ç bardzo przydatny, do tego nale┼╝y przypomnie─ç, ┼╝e warto┼Ť─ç atrybutu groups mo┼╝e przyjmowa─ç (zgodnie z nazw─ů) list─Ö grup, podobnie jak drugi parametr metody validate(). Tym samym encj─Ö mo┼╝emy oprogramowa─ç bardzo konkretnie, uwzgl─Ödniaj─ůc r├│┼╝norakie wymagania.

Podstawowe adnotacje oraz tworzenie własnych

W specyfikacji wymieniono tylko kilka podstawowych adnotacji, kt├│re s┼éu┼╝─ů do walidacji. Oto one:

  • @Null
  • @NotNull
  • @AssertTrue
  • @AssertFalse
  • @Min
  • @Max
  • @DecimalMin
  • @DecimalMax
  • @Size
  • @Digits
  • @Past
  • @Future
  • @Pattern

Nie jest to jaka┼Ť gigantyczna lista. Jest tak mi─Ödzy innymi dlatego, ┼╝e w JSR 303 dodano mo┼╝liwo┼Ť─ç tworzenia w┼éasnych, specyficznych adnotacji walidacyjnych. Zasadniczo temat dobrze zaprezentowa┼é Kozio┼éek na swoim blogu, zatem nie b─Öd─Ö dublowa┼é materia┼éu i zainteresowanych odsy┼éam tam┼╝e.

Walidacja w JPA

Ok. Po tym przyd┼éugim wst─Öpie nale┼╝a┼éoby dok┼éadniej przyjrze─ç si─Ö samej walidacji w JPA. Co prawda pokaza┼éem ju┼╝ przyk┼éady dzia┼éaj─ůcego kodu, ale by┼éy to przyk┼éady sunny day scenario. Sama integracja pomi─Ödzy JPA i JSR 303 jest lekko problematyczna. Specyfikacja walidacji ma tak naprawd─Ö dzia┼éa─ç niezale┼╝nie od tego co i gdzie waliduje. Jak si─Ö to ma np. do op├│┼║nionego ┼éadowania w┼éasno┼Ťci encji? ┼üatwo mo┼╝na wyobrazi─ç sobie sytuacj─Ö, w kt├│rej by poprawnie przeprowadzi─ç proces walidacji trzeba do pami─Öci zaci─ůgn─ů─ç ca┼é─ů encj─Ö, wraz ze wszystkimi zale┼╝no┼Ťciami! Niezbyt cz─Östo jest to po┼╝─ůdane zachowanie. Dlatego przy u┼╝ywaniu JSR 303 w stosunku do encji JPA walidacji podlegaj─ů tylko zwyk┼ée w┼éasno┼Ťci oraz typy wbudowane. Relacje z innymi obiektami nie b─Öd─ů walidowane, chyba ┼╝e encje, do kt├│rych si─Ö odnosz─ů r├│wnie┼╝ s─ů zmieniane/zapisywane/usuwane w tej samej transakcji.

Powiew ksi─ů┼╝kowej ┼Ťwie┼╝o┼Ťci

W ostatnim czasie po raz kolejny co┼Ť si─Ö ruszy┼éo w kwestii wydawniczej w Polsce. Rodzimy Helion w ko┼äcu poszed┼é po rozum do g┼éowy i zabrali si─Ö za wydawanie troszeczk─Ö bardziej sensownych pozycji dotycz─ůcych interesuj─ůcego nas poletka. Mieli ju┼╝ przeb┼éyski wcze┼Ťniej, ale tym razem wygl─ůda to jak sta┼éy trend. Obecnie wydali (b─ůd┼║ te┼╝ planuj─ů wyda─ç) kilka ciekawych pozycji.

Mog─ů pojawi─ç si─Ö g┼éosy, ┼╝e przecie┼╝:

  • g┼éupot─ů jest czyta─ç ksi─ů┼╝ki papierowe – jak kto woli, ja jestem fetyszyst─ů ksi─ů┼╝kowym i do przesiadki na ebooki jako┼Ť si─Ö nie pal─Ö
  • czekanie na polskie wydania jest ┼Ťmieszne, technologia staje si─Ö stara zanim przet┼éumacz─ů – mo┼╝e tak, mo┼╝e i nie. Zasadniczo oczywistym jest, ┼╝e kiedy potrzebujemy wyuczy─ç si─Ö na szybko nowej technologii to si─Ögamy po oficjaln─ů dokumentacj─Ö na sieci. Jednak┼╝e stoj─Ö na stanowisku, ┼╝e czym innym s─ů tutoriale i dokumentacja, a czym innym ksi─ů┼╝ka. To moje zdanie i b─Öd─Ö si─Ö go trzyma┼é.
  • po polsku? Angielskiego nie znasz? – zasadniczo to znam, ca┼ékiem nawet zno┼Ťnie. Jednak┼╝e o ile na co dzie┼ä sp─Ödzam sporo czasu wertuj─ůc ┼║r├│d┼éa angielskoj─Özyczne, chcia┼ébym m├│c dla luzu (np. w poci─ůgu) przeczyta─ç co┼Ť w rodzimym j─Özyku. Ot tak tylko dla odmiany i rozlu┼║nienia.

Co tam zatem Helion nam gotuje?

  • Clojure – daleko mi wci─ů┼╝ do programowania funkcyjnego, ale Jacek Laskowski jak zawsze robi ciekawy hype wok├│┼é zagadnienia zatem jest to rzecz warta uwagi. Dla tych, co nie chc─ů czeka─ç mam inn─ů pozycj─Ö – J─Özyk programowania Scala
  • Spring in Action – moim zdaniem najfajniejsza ksi─ů┼╝ka o Springu wreszcie doczeka┼éa si─Ö polskiego wydania. Prawd─ů jest, ┼╝e dotyczy wersji 3.0, ale wci─ů┼╝ pozostaje ┼Ťwietnym wprowadzeniem do Springa jako takiego. Dla pocz─ůtkuj─ůcych – bezcenna pozycja.
  • Wydajno┼Ť─ç Javy – tej ksi─ů┼╝ki nie mia┼éem w r─Ökach w wersji oryginalnej, zaskoczy┼éa mnie za┼Ť poruszana tematyka. Bardzo (moim zdaniem) ciekawe aspekty programowania, na kt├│re my – programi┼Ťci – mo┼╝e nie do ko┼äca zwracamy uwag─Ö. Z ca┼é─ů pewno┼Ťci─ů zapoznam si─Ö z ni─ů bli┼╝ej za┼Ť wra┼╝eniami podziel─Ö si─Ö na blogu.

Dzia┼éaj─ůcy przyk┼éad JEE w akcji

Jako┼Ť tak si─Ö z┼éo┼╝y┼éo, ┼╝e poza servletami i┬áJPA┬ániespecjalnie mia┼éem w ┼╝yciu pobawi─ç si─Ö w┬áEJB┬ái insze wynalazki. Fakt, ┼╝e pojawi┼é si─Ö kiedy┼Ť dawno┬áSpring skutecznie zniech─Öca┼é do posi┼ékowania si─Ö┬áJEE┬áw codziennym developmencie. Jednak┼╝e sytuacja zmieni┼éa si─Ö wraz z wydaniem wersji 6┬áJavy EE.

Szukaj─ůc w sieci materia┼é├│w dla przygotowa┼ä do certyfikatu Java Persistence API Developer Certified Expert┬á(tak tak, pierwsze wpisy z przygotowa┼ä ju┼╝ nied┼éugo) znalaz┼éem do┼Ť─ç ciekawy tutorial, kt├│ry umo┼╝liwia postawienie w pe┼éni funkcjonalnej aplikacji, na kt├│rej mo┼╝naby prze─çwiczy─ç mniej i bardziej zaawansowane tematy zwi─ůzane z t─ů certyfikacj─ů.

JBoss to nazwa budz─ůca respekt. Jako firma oferuje szeroki wachlarz produkt├│w – pocz─ůwszy od serwera aplikacyjnego sko┼äczywszy na IDE. Oferuje r├│wnie┼╝ strasznie fajny tutorial znajduj─ůcy si─Ö ┬ádok┼éadnie pod tym adresem. Obejmuje on instalacj─Ö dedykowanego IDE oraz przedstawia┬áJEE┬áw akcji – mamy i us┼éugi sieciowe, mamy┬áJSF,┬ámamy te┼╝ podpi─Öte┬áHibernate┬ájako┬áORM. Nic tylko bra─ç i dzia┼éa─ç. Je┼Ťli kto┼Ť potrzebuje zobaczy─ç jak mo┼╝e wygl─ůda─ç sensowna appka bez miliona zale┼╝no┼Ťci w POMie to powy┼╝szy adres jest ┼Ťwietnym punktem wyj┼Ťcia.

Narz─Ödzia JDK

W przypadku┬áJDK┬ánajcz─Ö┼Ťciej wiemy, ┼╝e trzeba go zainstalowa─ç by m├│c co┼Ť zaprogramowa─ç. Cz─Östo na samej instalacji nasza przygoda z┬áJDK┬ási─Ö ko┼äczy – reszt─Ö bior─ů na siebie IDE czy ┼Ťcie┼╝ka systemowa do kompilatora i tyle. Tymczasem warto zapozna─ç si─Ö z┬áJDK┬átroch─Ö bli┼╝ej – dostarcza on bowiem szeregu ca┼ékiem przyjemnych narz─Ödzi. W swoim wywodzie pomin─Ö najbardziej oczywiste – java oraz javac. Chyba ka┼╝dy wie, ┼╝e u┼╝ywa kompilatora oraz uruchamia oddzielne instancje JVM ­čśë

Lista z ca┼é─ů pewno┼Ťci─ů nie jest kompletna, nie ma r├│wnie┼╝ s┼éu┼╝y─ç za tutorial dotycz─ůcy ich u┼╝ycia. Ma tylko pokaza─ç istnienie pewnych programik├│w, kt├│re mog─ů nam si─Ö przyda─ç. Wiekszo┼Ť─ç z ni┼╝ej wymienionych posiada dodatkowe opcje i parametry, kt├│rymi mo┼╝emy sterowa─ç uruchomienie oraz dzia┼éanie program├│w. Ca┼éo┼Ť─ç testowa┼éem na JDK od Sun/Oracle w wersjach 1.6 oraz 1.7

  • JPS ┬á– jest to narz─Ödzie pozwalaj─ůce wylistowa─ç uruchomione (domy┼Ťlnie) na lokalnym komputerze maszyny wirtualne. W charakterze parametru mo┼╝na poda─ç dowolny adres komputera (zdalnego), oczywi┼Ťcie pod warunkiem, ┼╝e mamy do niego dost─Öp. R├│wnie┼╝ nale┼╝y zwr├│ci─ç uwag─Ö na opis w dokumentacji:

    The jps command uses the java launcher to find the class name and arguments passed to the main method. If the target JVM is started with a custom launcher, the class name (or JAR file name) and the arguments to the main method will not be available. In this case, the jps command will output the string Unknown for the class name or JAR file name and for the arguments to the main method.

    The list of JVMs produced by the jps command may be limited by the permissions granted to the principal running the command. The command will only list the JVMs for which the principle has access rights as determined by operating system specific access control mechanisms.

    Dodatkowo dokumentacja m├│wi jasno, i┼╝ JPS nie jest ju┼╝ wspierane i mo┼╝e znikn─ů─ç w kolejnych wersjach Javy. U mnie w JDK 1.7.0 wci─ů┼╝ jest dost─Öpne ­čśë

  • Appletviewer – zgodnie z nazw─ů s┼éu┼╝y do uruchamiania applet├│w bez konieczno┼Ťci osadzania ich na loklanej stronie WWW (czy te┼╝ gdzie┼Ť indziej). Dla przyk┼éadu – mamy gr─Ö w Javie w formie apletu, ale nie chcemy uruchamia─ç ca┼éej otaczaj─ůcej aplet strony (z mas─ů reklam). Podajemy adres strony zawieraj─ůcej element z apletem i do przodu. Niestety nale┼╝y si─Ö r├│wnie┼╝ liczy─ç z tym, i┼╝ mog─ů wyst─ůpi─ç problemy z uruchomieniem – przekazywane parametry, sprawdzanie poprawno┼Ťci, cookie – ewentualnych przyczyn braku poprawnego uruchomienia jest wiele. Jednak┼╝e by zobaczy─ç cho─ç w praktyce jak to wygl─ůda wystarczy uruchomi─ç z konsoli to narz─Ödzie przekazuj─ůc jako pierwszy argument adres: http://www.roseindia.net/tutorialfiles/java/applet-oline-example.html . Hello World!
  • JSTAT i JSTATD – to bardzo pot─Ö┼╝ne narz─Ödzia, kt├│re umo┼╝liwiaj─ů monitoring parametr├│w JVM. JStad uruchamia lokalny rejestr RMI, co umo┼╝liwia wystawienie informacji o JVM na zewn─ůtrz (np. w┼é─ůczenie ┼éadnego monitoringu w formie aplikacji webowej uruchomionej na innym serwerze). Na szybko za┼Ť powiem wi─Öcej o Jstat, kt├│re to narz─Ödzie pozwala na do┼Ť─ç dok┼éadne monitorowanie parametr├│w JVM. G┼é├│wnie rzecz w zaj─Öto┼Ťci pami─Öci oraz zdarzeniach Garbage Collectora. Jest to naprawd─Ö bardzo istotne w przypadku wyciek├│w pami─Öci, monitoringu zmian oraz badaniach efektywno┼Ťci. Zwracane warto┼Ťci mog─ů by─ç r├│┼╝nie formatowane i dobrze jest zapozna─ç si─Ö z nimi w dokumentacji .
  • Javap – narz─Ödzie u┼╝yteczne do┼Ť─ç w w─ůskim zakresie. Jego wywo┼éanie z argumentem w formie klasy spowoduje zwr├│cenie danych o pakiecie oraz publicznych i chronionych polach/metodach. Oczywi┼Ťcie wynik programu mo┼╝emy regulowa─ç za pomoc─ů du┼╝ej ilo┼Ťci opcji. Przydatne kiedy debugujemy kod na zapomnianym serwerze z Jav─ů 1.3 bez dost─Öpu do API w innej postaci (man, internet, IDE) ­čśë
  • JDB – debugger dla Javy. Je┼Ťli my┼Ťl o pr├│bach zabawy z tym narz─Ödziem bez IDE przyprawia Ci─Ö o dr┼╝enie r─ůk to wiedz, ┼╝e nie jeste┼Ť jedynym.
  • JMap i JHat – narz─Ödzia do tworzenia zrzut├│w sterty oraz do ich analizy. Parametrem do analizy przez program JHat mo┼╝e by─ç efekt dzia┼éania JMap. Program JHat po przeanalizowaniu pliku uruchamia serwer WWW i udost─Öpnia dane na temat zrzutu.
  • JConsole i JVisualVM – ┼éadne narz─Ödzia graficzne do zarz─ůdzania i statystyki JVM (zar├│wno lokalnych jak i zdalnych). S─ů to nak┼éadki wykorzystujace niekt├│re wspomniane powy┼╝ej narz─Ödzia. D┼éugo by pisa─ç – zach─Öcam do zapoznania si─Ö z nimi.

Pozosta┼ée narz─Ödzia s─ů w fazie eksperymentalnej (np. jrunscript) b─ůd┼║ te┼╝ do┼Ť─ç cz─Östo u┼╝ywane, ale przez inne biblioteki i narz─Ödzia (wsgen, javadoc, xjc, jar). Wielu z powy┼╝szych narz─Ödzi mo┼╝emy nigdy nie potrzebowa─ç. Warto jednak zajrze─ç do folderu BIN, tak tylko z wrodzonej ciekawo┼Ťci ­čśë

Klaster ActiveMQ i dlaczego kolejno┼Ť─ç XMLa ma znaczenie

Jednym z element├│w specyfikacji korporacyjnej┬áJavy s─ů┬áMessage Driven Beans, kt├│re zasadniczo wrzuca si─Ö do wora z napisem┬áJMS┬á(Java Message System). Jak zawsze pomin─Ö dywagacje teoretyczne co jest czym. Kiedy wezm─Ö si─Ö za zdawanie certyfikatu biznesowego┬áOracla┬áto na pewno sporo na ten temat napisz─Ö. Dzisiaj jednak co┼Ť prostego i na szybko – zrobimy┬áklaster broker├│w ActiveMQ.

ActiveMQ jest produktem ze stajni Apache, kt├│ry dostarcza funkcjonalno┼Ťci JMS, ale poza kontenerem JEE. Ma to swoje plusy – do obs┼éugi JMS mo┼╝na oddelegowa─ç oddzieln─ů maszyn─Ö i nie przejmowa─ç si─Ö padami serwera. Troch─Ö ┼éatwiej skalowa─ç prost─ů aplikacyjk─Ö ni┼╝ kolejne serwery aplikacyjne. W przypadku┬áActiveMQ┬ánie jest r├│wnie┼╝ problemem stworzenie klastra broker├│w, co umo┼╝liwia ci─ůg┼éo┼Ť─ç dzia┼éania w przypadku gdyby jeden z broker├│w odm├│wi┼é pos┼éusze┼ästwa.

Samo ActiveMQ da si─Ö uruchomi─ç z domy┼Ťlnymi (na systemach *nixowych wystarczy nada─ç prawa do wykonywania plikowi activemq oraz zapisu do folder├│w z danymi i konfiguracj─ů) ustawieniami i b─Ödzie to dzia┼éa┼éo ca┼ékiem sprawnie. Ka┼╝dy z broker├│w posiada swoj─ů nazw─Ö, a tak┼╝e maszyn─Ö i port, na kt├│rym nas┼éuchuje. Domy┼Ťlny plik konfiguracyjny wygl─ůda nastepuj─ůco (wersja┬á5.5.1):

<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements. See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License. You may obtain a copy of the License at

 http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->
<!-- START SNIPPET: example -->
<beans
 xmlns="http://www.springframework.org/schema/beans"
 xmlns:amq="http://activemq.apache.org/schema/core"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
 http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">

 <!-- Allows us to use system properties as variables in this configuration file -->
 <bean>
 <property name="locations">
 <value>file:${activemq.base}/conf/credentials.properties</value>
 </property>
 </bean>

 <!--
 The <broker> element is used to configure the ActiveMQ broker.
 -->
 <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.base}/data" destroyApplicationContextOnStop="true">

 <!--
 For better performances use VM cursor and small memory limit.
 For more information, see:

 http://activemq.apache.org/message-cursors.html

 Also, if your producer is "hanging", it's probably due to producer flow control.
 For more information, see:
 http://activemq.apache.org/producer-flow-control.html
 -->

 <destinationPolicy>
 <policyMap>
 <policyEntries>
 <policyEntry topic=">" producerFlowControl="true" memoryLimit="1mb">
 <pendingSubscriberPolicy>
 <vmCursor />
 </pendingSubscriberPolicy>
 </policyEntry>
 <policyEntry queue=">" producerFlowControl="true" memoryLimit="1mb">
 <!-- Use VM cursor for better latency
 For more information, see:

 http://activemq.apache.org/message-cursors.html

 <pendingQueuePolicy>
 <vmQueueCursor/>
 </pendingQueuePolicy>
 -->
 </policyEntry>
 </policyEntries>
 </policyMap>
 </destinationPolicy>

 <!--
 The managementContext is used to configure how ActiveMQ is exposed in
 JMX. By default, ActiveMQ uses the MBean server that is started by
 the JVM. For more information, see:

 http://activemq.apache.org/jmx.html
 -->
 <managementContext>
 <managementContext createConnector="false"/>
 </managementContext>

 <!--
 Configure message persistence for the broker. The default persistence
 mechanism is the KahaDB store (identified by the kahaDB tag).
 For more information, see:

 http://activemq.apache.org/persistence.html
 -->
 <persistenceAdapter>
 <kahaDB directory="${activemq.base}/data/kahadb"/>
 </persistenceAdapter>

 <!--
 The systemUsage controls the maximum amount of space the broker will
 use before slowing down producers. For more information, see:

 http://activemq.apache.org/producer-flow-control.html

 <systemUsage>
 <systemUsage>
 <memoryUsage>
 <memoryUsage limit="20 mb"/>
 </memoryUsage>
 <storeUsage>
 <storeUsage limit="1 gb"/>
 </storeUsage>
 <tempUsage>
 <tempUsage limit="100 mb"/>
 </tempUsage>
 </systemUsage>
 </systemUsage>
 -->

 <!--
 The transport connectors expose ActiveMQ over a given protocol to
 clients and other brokers. For more information, see:

 http://activemq.apache.org/configuring-transports.html
 -->
 <transportConnectors>
 <transportConnector name="openwire" uri="tcp://0.0.0.0:61616"/>
 </transportConnectors>

 </broker>

 <!--
 Enable web consoles, REST and Ajax APIs and demos

 Take a look at ${ACTIVEMQ_HOME}/conf/jetty.xml for more details
 -->
 <import resource="jetty.xml"/>

</beans>
<!-- END SNIPPET: example -->

By stworzy─ç klaster nie musimy si─Ö specjalnie wysila─ç. Wystarczy uruchomi─ç 2 razy┬áActiveMQ. Mo┼╝na do tego u┼╝y─ç dok┼éadnie tego samego kodu (lokalizacji na dysku), a u┼╝y─ç tylko innych plik├│w startowych oraz konfiguracji (rzecz jasna ka┼╝dy broker musi nas┼éuchiwa─ç na oddzielnym porcie). U mnie rzecz by┼éa o tyle ┼éatwiejsza, i┼╝ klaster mia┼é by─ç zbudowany z u┼╝yciem 2 oddzielnych maszyn. W zwi─ůzku z czym skopiowa┼éem folder z ca┼é─ů aplikacj─ů i konfiguracj─ů na drugi serwer i jedynym co zmieni┼éem by┼éa nazwa brokera (parametr┬ábrokerName┬áw elemencie┬ábroker).

Uruchomienie tym samym 2 oddzielnych w─Öz┼é├│w nie by┼éo problemem – oba dzia┼éa┼éy bez zastrze┼╝e┼ä. Jednak┼╝e jak wspomnia┼éem celem by┼éo stworzenie klastra broker├│w. A tym samym obydwa w─Öz┼éy powinny widzie─ç siebie nawzajem.

Musimy wpierw odwiedzi─ç te┼╝ skrypty startuj─ůce┬áAMQ i odnale┼║─ç zmienn─ů ACTIVEMQ_QUEUEMANAGERURL i nada─ç jej adres nie localhost, ale pe┼énej nazwy domeny – np. tcp://broker1.chlebik.pl:61616.

Potrzebna do klastra jest te┼╝ zmiana elementu transportConnectors┬áw konfiguracji brokera. U mnie wygl─ůda on po zmianie tak:


<transportConnectors>
 <transportConnector name="openwire" uri="tcp://broker1.chlebik.pl:61616" updateClusterClients="true"
 rebalanceClusterClients="true" updateClusterClientsOnRemove="true" />
 </transportConnectors>

Uwaga! od razu ostrzegam, ┼╝e przestawione domeny/porty s─ů prezentacyjne i nie istniej─ů naprawd─Ö. A je┼Ťli ju┼╝ to na pewno nie s─ů dost─Öpne poprzez sie─ç ­čśë

Podobnie konfigurujemy (zmieniaj─ůc dane) na drugim brokerze. Ich uruchomienie oddzielnie powinno si─Ö powie┼Ť─ç bez problemu – po prostu dwie oddzielne instancje. By si─Ö zobaczy┼éy wzajemnie musimy doda─ç do konfiguracji ka┼╝dego z nich element o nazwie networkConnectors. W przypadku konfiguracji brokera s┼éuchaj─ůcego pod adresem tcp://broker1.chlebik.pl:61616 wygl─ůda─ç b─Ödzie to tak:


<networkConnectors>
 <networkConnector uri="static:(tcp://broker2.chlebik.pl:61616)" conduitSubscriptions="false" />
</networkConnectors>

Oczywi┼Ťcie dla broker2 adres b─Ödzie odnosi┼é si─Ö do broker1. I tutaj najwa┼╝niejsza informacja – podana konfiguracja u mnie nie dzia┼éa┼éa. Pomimo przeorania tutoriali w sieci oraz dokumentacji jako┼Ť nikt nie wspomnia┼é, i┼╝ plik konfiguracyjny ActiveMQ jest wra┼╝liwy na kolejno┼Ť─ç element├│w konfiguracyjnych!!! I by temat zadzia┼éa┼é element networkConnectors najbezpieczniej jest umie┼Ťci─ç zaraz za elementem destinationPolicy. Dopiero wtedy przy odpaleniu drugiego brokera otrzymamy w logach co┼Ť na kszta┼ét:

2012-01-16 20:02:28,078 | INFO  | Establishing network connection from vm://broker1?async=false&network=true to tcp://broker2.chlebik.pl:61616 | org.apache.activemq.network.DiscoveryNetworkConnector | main

Lub co┼Ť podobnego do wy┼╝ej przedstawionego. Mi ten niuans zmarnowa┼é kilka godzin – mam nadziej─Ö, ┼╝e tym wpisem uchroni┼éem kogo┼Ť przed podobnym niebezpiecze┼ästwem.

Co tam zn├│w u konkurencji s┼éycha─ç?

Podobnie jak kawa┼é czasu temu postanowi┼éem przejrze─ç swoje┬áRSSy┬áby podzieli─ç si─Ö z Wami ciekawymi materia┼éami w interesuj─ůcych nas tematach. Co prawda materia┼éy te obejmuj─ů 2 ostatnie lata (troch─Ö zapu┼Ťci┼éem bloga ostatnio, przepraszam), ale to na pewno nie odejmuje im warto┼Ťci merytorycznej. W nowy rok dobrze jest wej┼Ť─ç z solidn─ů dawk─ů wiedzy na rozruch.

Na pocz─ůtek linkowany ju┼╝ u mnie na blogu tutorial Darka Zonia wprowadzaj─ůcy w Spring Framework. M├│j tutorial p├│ki co stoi w miejscu za┼Ť Darek bardzo szybko i sprawnie ┬ástworzy┼é kawa┼éek niezg┼éego pisania.

Jak zawsze bajt├│w na dysku nie zasypuje Tomek Dziurko i przez ostatnie miesi─ůce na blogu zaprezentowa┼é kilkana┼Ťcie ciekawych wpis├│w dotycz─ůcych popularnych bibliotek i narz─Ödzi. Przede wszystkim Tomek od zawsze popularyzuje u┼╝ycie webframeworku Wicket i w zwi─ůzku z tym mo┼╝na u Niego znale┼║─ç bardzo fajny tutorial na ten temat. Do tego ciekawym wpisem na pewno jest przedstawienie systemu kontroli wersji┬áMercurial – warto sprawdzi─ç czy “konkurent”┬áGITa mo┼╝e nam co┼Ť ciekawego zaoferowa─ç.

Nie jestem pewny, czy aby nie umieszcza┼éem ju┼╝ linka do bardzo fajnego tutoriala o UMLu autorstwa Grze┼Ťka Kukawskiego. Co ciekawe – materia┼é jest prezentowany w formie oddzielnych lekcji i do tego w formie kr├│tkich filmo-prezentacji (pomys┼é z u┼╝yciem map my┼Ťli do prezentacji tre┼Ťci jest moim zdaniem bardzo dobry). Zach─Öcam do zapoznania si─Ö z tym kursem.

Cz─Östo podczas nauki Javy brakowa┼éo mi ciekawych i przyst─Öpnych tutoriali, kt├│re opisywa┼éyby warstw─Ö middleware pisanego w Javie – tych wszystkich kolejek, webserwis├│w, wzorc├│w integracyjnych i ca┼éej ha┼éastry. Z wielk─ů zatem ciekawo┼Ťci─ů przeczyta┼éem kilka wpis├│w na ten temat ┼üukasza Dywickiego.

Na koniec zostawi┼éem zwyci─Özc─Ö mojego prywatnego konkursu o tytu┼é “Tytana Javowej Blogosfery” – Bartka “Kozio┼éka” Kuczy┼äskiego. Na jego blogu mo┼╝na znale┼║─ç tyle warto┼Ťciowego materia┼éu, ┼╝e pr├│ba wyliczenia tych ciekawszych mocno rozd─Ö┼éaby d┼éugo┼Ť─ç tego posta. Ja mog─Ö poleci─ç ze swej strony bardzo ciekaw─ů seri─Ö o “Ekstremalnej obiektowo┼Ťci”.

To tyle na dzi┼Ť i tak przy okazji – Szcz─Ö┼Ťliwego Nowego Roku.