środa, 30 października 2013

Remote Scalania 7 in Javart

Właśnie się zakończyła pierwsza Remote Scalania 7 in Javart. Scalania, to projekt Jacka Laskowskiego, który polega na cyklicznych spotkaniach ludzi, chcących się wspólnie uczyć Scali. Spotkanie to było wyjątkowe, ze względu na to, że było ono pierwsze, w którym można było uczestniczyć zdalnie. Tak więc nie wychodząc z domu, mogłem się „spotkać” z innymi fanami Scali, wspólnie porozwiązywać zadania, poszerzyć swoją wiedzę i się z nimi scalić.

Generalnie w warsztacie uczestniczyły w sumie 4 osoby zdalne i ileś tam na miejscu, w siedzibie firmy Javart. Jako platformy do takiej konferencji skorzystaliśmy z Google Hangouts. Dodatkowo Jacek zrobił live stream’ing na YouTube’a, czego efektem jest filmik z pierwszej godziny spotkania: Scalania 7 in Javart. Jeśli ktoś się jeszcze waha, czy przystąpić do tej inicjatywy, to mam nadzieję, że ten filmik trochę pomoże i zachęci. Nie widziałem całego nagrania, ale generalnie ta forma Multi Video konferencji zdała egzamin.

Sam miałem wcześniej pewne obawy, czy poradzę sobie z tym kursem, czy wystarczająco znam Scalę, czy powinienem się angażować. Ale przecież w końcu zaliczyłem pierwszy kurs Martina Oderskiego: Functional Programming Principles in Scala, a i teraz szykuje się kolejny: Principles of Reactive Programming. A wiedzę należy odświeżyć. Troszkę przysiadłem wcześniej do rozwiązywanych poprzednio zadań w niedzielę, poniedziałek i wtorek, co okazało się w zupełności wystarczające.

Myślałem również, że na liście, którą rozwiązujemy, są na początku banalne zadania, a później już tylko trudniejsze. Na szczęście nie jest tak, tzn. są najpierw łatwe (z jedną gwiazdką), ale są one przeplatane trudniejszymi (dwie gwiazdki). Tych bardzo trudnych jest już zaledwie kilka. Taki rozrzut pomaga bez przeszkód na dołączenie do inicjatywy nawet od któregoś z kolei spotkania – w moim przypadku od 7mego.

Co do samego przebiegu spotkania, to uważam, że Jacek się bardzo fajnie sprawdza w roli moderatora całego zamieszania, gdzie trzeba rozmawiać z tymi, co siedzą na sali, ze zdalnymi, pokazywać obydwu grupom (miejscowym i zdalnym) kod, omawiać go a i czasem pisać. Pomimo inputu z różnych stron, Jacek był w stanie świetnie ogarnąć całość.

Podczas warsztatu miałem okazję pochwalenia się swoim rozwiązaniem (nie raz) i od razu zebrałem sporo krytycznych uwag. Ale dzięki temu, bardzo szybko się sporo nauczyłem. Pomogło mi również patrzenie na rozwiązania innych uczestników. Jak się widzi inne, dobre rozwiązanie, to się myśli: kurde, przecież to takie łatwe. Zauważyłem wcześniej u siebie (podczas rozwiązywania wcześniejszych zadań), że nauczyłem się jak działa młotek (w tym przypadku funkcje rekurencyjne z akumulatorem) i już niemal każde zdania traktowałem jak gwóźdź (czyli próbowałem każdy problem rozwiązać w ten sposób). Zobaczenie innego rozwiązania (jednolinijkowego), spowodowało u mnie odrzucenie zaślepek z oczu i późniejsze zadania próbowałem rozwiązywać już tylko w ten sposób.

Swoimi rozwiązaniami dzieliliśmy się za pomocą Gitsów. Na szczęście w IntelliJ Idei jest szybka możliwość publikacji takiego Gitsa. Dowiedziałem się też również, dzięki temu spotkaniu, że można swojego Gitsa edytować. Jest to sposób wystarczający do szybkiego podglądu rozwiązań, ale przydało by się je zbierać i wysyłać jako PR do repozytorium Jacka, aby zawsze można było sobie je później przejrzeć. Nie rozwiązaliśmy jednak problemu jak by dokładniej miało to działać.

Generalnie jeszcze na spotkaniach lokalni uczestnicy pracują w parach, ale zdalni pracowali osobno. Po prostu nie mieliśmy na szybko jakiegoś rozwiązania, jak taka pracę zorganizować. Kojarzę, ze kiedyś była możliwość takiej pracy w NetBeansie, ale na szybko nic sensownego nie znalazłem do Idei. Ewentualnie można skorzystać z TeamViewer’a, lub podobnego rozwiązania, ale to będzie dodatkowe obciążenie dla komputerów i mogą one nie dać rady. Jak dla mnie można próbować szukać jakiś możliwości zdalnego paring’u, ale nie jest to konieczne na przyszłych spotkaniach.

No i chyba na przyszłość przydało by się trochę więcej testów przygotować do każdego zadania, z warunkami brzegowymi i z niepoprawnymi danymi itp., choć obsługa tych sytuacji wyjątkowych mogła by sprawić, że 10 min na rozwiązanie problemu to za mało. Po za tym, co do ram czasowych spotkania, nie ma się do czego przyczepić. Jak dla mnie jest to idealnie zaplanowane i wykonane.

Podsumowując, dziękuję Jackowi za zorganizowanie Scalani w ten sposób, mam w zamiarze uczestnictwo w kolejnych spotkaniach. Jest jeszcze parę detali możliwych do dopracowania, ale i tak bez tego jest już super. Trzeba tylko pamiętać, aby zawczasu ściągnąć nowe testy, odpalić kompilator, aby reszta szła już sprawniej. Zachęcam również czytelników do aktywnego udziału w tej inicjatywie.

wtorek, 29 października 2013

Zawsze sprzątaj po refaktoryzacji

Poniżej prezentuję pewnego potworka, na którego natknął się kolega z zespołu:


Jak to się stało? Otóż jeden z parametrów wyleciał jako zbędny i Eclipse zamienił miejsca jego użycia null'em :) Ciekawsze by było, gdyby ten warunek byłby jeszcze kiedyś spełniony.

Tak więc po każdej refaktoryzacji, należy się jeszcze dokładniej przyjrzeć wynikowi, aby nie pozostawić dziwnego smordu po sobie. Na szczęście skończyło się na kupie śmiechu i nic złego się nie wydarzyło.

Btw. Zna ktoś dobry sposób implementacji Exception Handler'a, gdzie odbyło by sie bez łańcuszka if / else / instanceof?

czwartek, 24 października 2013

Warsjawa 2013

W tym roku jakoś tak biednie u mnie było, jeśli chodzi o konferencje javowe (z różnych względów), ale na szczęście udało mi się zawitać na Warsjawę. Trzeba więc relację z tegoż wydarzenia skrobnąć, aby w przyszłości było gdzie zajrzeć do notatek, gdy przyjdzie mi zmierzyć się z jakimś poważniejszym problemem wydajnościowym lub a Akką.

Warsztat z Profilowania aplikacji JVM prowadzili Kuba Kubryński i Michał Warecki. Na początku było strasznie dużo teorii (właściwie do przerwy obiadowej), no ale nie każdy ma możliwość zmierzenia się z takimi problemami na co dzień, więc należało dużo wytłumaczyć i pokazać, co jest standardowo dostępne wraz z zainstalowanym systemem operacyjnym i JDK.

Zaczęło się od pamięci w Javie. Generalnie można ją podzielić na 3 części:
  • Young Generation
  • Old Generation
  • Permanent Generation

Młoda i stara generacja są przechowywane na stercie, a ostatnia trzecia część pamięci to Perm Gen, gdzie znajdują się załadowane klasy wraz z metodami. Co ważne, to to, że internowane Stringi lądują w Perm Gen i dlatego warto sprawdzać, ile one zajmują. Na szczęście od wersji 7 problem ten znika, gdyż teksty lądują na stercie. Więcej na ten temat tutaj: Java SE 7 Features and Enhancements.

Jest jeszcze coś takiego jak Code Cache, czyli miejsce w pamięci na skompilowany kod natywny naszych aplikacji. Pewnie jeszcze by się coś tam znalazło, ale nie jest to dla nas w tym momencie interesujące.

Następnie było o tym, jaka jest różnica między boolean a Boolean, a właściwie ile to obydwa twory zajmują pamięci. I tak boolean to jeden bit, ale Boolean to 12 bajtów nagłówka obiektu i jeden bit. A że nie można takich dziwnych, nieokrągłych wartości w pamięci używać, klasa zostanie dodatkowo wyrównana do 32 bitów (4ch bajtów) lub ich wielokrotności, w przypadku 32 bitowej maszyny wirtualnej. W przypadku 64 bitowej wersji będzie to zaokrąglenie do 64 bitów (8 bajtów), lub wielokrotności oczywiście.

Tak więc Boolean zajmuje w Javie aż 16 bajtów! Dlatego ze względów wydajnościowych, gdy trzecia wartość wyrażenia logicznego (null) jest nam niepotrzebna, to warto Boolean’a unikać.

Było jeszcze o rozmiarach, jakie zajmują obiekty:
  • shallow – to rozmiar samego obiektu wraz nagłówkiem
  • deep - rozmiar całego grafu obiektów, jaki jest osiągany z danego obiektu.
  • retained - rozmiar definiujący, ile pamięci było by zwolnione, gdyby właśnie wystartował Garbage Collector.

Jeszcze ciekawsze rozwiązanie to odśmiecanie przez kopiowanie, czyli Copying GC. W Young Generation mamy dwa obszary: From (Survivor1) i To (Survivor2). Gdy pierwszy z nich się zapełni i gdy nadejdzie czas na odśmiecanie, to żyjące obiekty zostaną przekopiowane z From do To. Następnie zamienią się role bloków, tzn. blok From stanie się nowym blokiem To, a obecnie zapełniony To stanie się nowym From. Każde takie kopiowanie pomiędzy Survivor1 i Survivor2 zwiększa wiek życia obiektów. Dzięki temu zabiegowi kopiowania do nowej przestrzeni, pamięć jest regularnie defragmentowana. Intensywnie z tego podejścia korzysta The Garbage First Garbage Collector (G1 GC). W tym przypadku pamięć jest podzielona na sporo kawałków, pomiędzy którymi, podczas odśmiecania, są kopiowane elementy.

W JVM są dostępne różne implementacjie Garbage Collectorów. I tak przykładowo domyślnym jest Serial GC (-XX:+UseSerialGC). Działa on jednowątkowo i blokuje inne zdania. Ale przynajmniej nie traci się tutaj czasu na przełączanie kontekstu.

Kolejną implementacją jest Parallel GC (albo jak podaje dokumentacja: throughput collector). Można ją uaktywnić pomocą -XX:+UseParallelGC a cechuje się ona tym, że w przeciwieństwie do Serial GC, używa wielu wątków do przyspieszenia odśmiecania. Domyślnie tylko generacja Young (Minor) jest odśmiecana równolegle. Aby również starą (Old, Major) generację równolegle odśmiecić, należy skorzystać z opcji -XX:+UseParallelOldGC. Te strategie redukują narzut Garbage Collektora na aplikację.

Kolejną implementacją czyszczenia pamięci z nieużytków jest Concurrent Collector (-XX:+UseConcMarkSweepGC), zwany też często CMS. Jest on zalecany tam, gdzie preferuje się krótkie przerwy na odśmiecanie, gdzie jest dużo długożyjących danych, na maszynach z dwoma lub więcej procesorami.

Jest jeszcze G1 GC, oficjalnie dostępny od JDK 7. Dzieli on całą pamięć na bloki, w których są umieszczane nasze dane. Gdy obszar się zapełni, dane są przenoszone do innych bloków, a co jest nie potrzebne - jest usuwane. Docelowo G1 GC ma zastąpić CMS GC.

Następnie były przedstawione Unixowe narzędzia, które mogą nam pomóc podejść do problemu od trochę innej strony (nie koniecznie od dupy strony). I tak za pomocą htop można podejrzeć drzewo procesów, również Javy. Iostat pokazuje utylizację zasobów na poziomie I/O. Dzięki temu można się np. dowiedzieć, że dysk nam nie wyrabia. Free pokazuje ilość wolnej / zajętej pamięci, a dstat przerywania, Contex Switche i inne różne zużycia. Natomiast perf to taki systemowy profiler. Uwzględnia on Contex Switch’e, migracje CPU (przerzucenie wykonywania czegoś na inny procek), ilość instrukcji na cykl CPU, odwołania do cache procesora.

Następnie było o narzędziach dostępnych w JDK. Poniżej opiszę tylko to, czego nie opisałem w relacji z JDD 2012.

Jinfo najczęściej pokazuje komunikat „Error attaching to process...”, ale jeden z prelegentów ma na to 2 obejścia: sudo sh -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
Lub w: /etc/sysctl.d/10-pthrace.conf ustawić kernel.yama.ptrace_scope = 0

Pierwsze jest tymczasowe i każdy admin powinien nam je na chwilę dać, a drugie jest permanentne, ale z jakiś tam względów niebezpieczne. Kolejne narzędzia to:

jstat -class PID 5s - komenda ta zrzuca nam co 5 sekund informację, ile jest załadowanych klas, ile pamięci zajmują i ile jest „odładowanych” klas
jstat -gc PID 5s - daje nam informacje o utylizacji pamięci
jstat -printcompilation PID 5s – pokazuje nam, które metody są skompilowane do kodu natywnego przez kompilator JIT (just-in-time compilation).
jstack PID - pokazuje stacktrace’y wszystkich wątków

Gdy chcemy się pobawić trochę linią poleceń, to możemy w ten sposób: java -XX:+PrintFlagsFinal -server –version wyświetlić sobie wszystkie flagi w Javie i poznać ich wartości domyślne. Niby znaczenie tych flag miało być gdzieś w dokumentacji opisane, ale jedyne co sensownego znalazłem to ten wpis na blogu: Hotspot JVM Options - The complete reference.

Później było jeszcze o Alekseyu Shipilevie i jego projekcie Java Object Layout. Niestety obecnie jest on niedostępny. Udało mi się gdzieś binarkę znaleźć, ale problem jest, jak to podpiąć pod Ideę / Eclipse’a, gdyż wszyscy linkują do strony autora, a ta już nie istnieje. Ale generalnie dzięki temu narzędziowi można podejrzeć wielkości, jakie zajmują w pamięci nasze klasy.

Było jeszcze trochę o Java VisualVM dostępnym standardowo w JDK. Warto do niego doinstalować pluginy, takie jak: MBeans, GC Viewer, Visual GC, Tracer i inne. Dzięki temu będziemy mogli sporo ciekawszych informacji podczas tuningowania naszych aplikacji uzyskać.

Po przerwie było jeszcze o Java Mission Control narzędziu, które jest dostępne JDK od wersji 7u40. Na pewno warto się przyjrzeć bliżej temu narzędziu.

Na koniec było jeszcze trochę o JProfileru i nadszedł czas na trochę praktyki. Za pomocą aplikacji profiling można było zobaczyć jak się zachowują różne implementacje Garbage Collectora, jak wyglądają wycieki pamięci itp. Podpinaliśmy się pod aplikację za pomocą JVisualVM’a i tam było bardzo ładnie widać co jak działa.

Kolejnym warsztatem, w którym uczestniczyłem, była Akka, prowadzona przez Maćka Próchniaka. Było już trochę widać zmęczenie po twarzach uczestników jak i samego prelegenta. No ale cóż, 17 godzina to trochę późna pora, zwłaszcza jak się chwilę wcześniej w innych warsztatach uczestniczyło.

Początkowy wstęp teoretyczny był bardzo klarownie przedstawiony i wszystko wydawało się bardzo jasne i proste. Takie się nie okazało, gdy przeszliśmy do kodu. Tam już było trochę ciężej. Postanowiliśmy, że zamiast osobno rozwiązywać zadania przygotowane przez Maćka, to rozwiąże on je sam, a reszta popatrzy. Tutaj jednak już nic więcej nie napiszę co zapamiętałem, ani czego się nauczyłem, gdyż trochę nie nadążałem / nie funkcjonowałem, a nieużywanie Skali od czasów ostatniego kursu Oderskiego dało mi się we znaki. Na szczęście niedługo startuje kolejna część tego kursu: Principles of Reactive Programming. Trzeba sobie do tego czasu trochę odświeżyć Scalę, aby gładko przez kurs przebrnąć.

Na koniec udało nam się zestawić razem rozproszonych aktorów, którzy komunikowali się ze sobą.

Byłem jeszcze na imprezie powarsztatowej. Udało mi się odnowić parę starych znajomości, trochę nowych nawiązać, dostać opieprz, że nic nie piszę na blogu (a więc jednak ktoś to czyta i niektórym komuś to pomaga), ani że nie występuję na konferencjach (zwłaszcza tych zagranicznych, nie mówiąc już o polskich). No cóż będę się starał zmienić ten stan rzeczy no i mam nadzieję, że się uda.

Na koniec należą się jeszcze wielkie brawa dla organizatorów, wolontariuszy i sponsorów, za super warsztaty (choć sam może nie trafiłem na typowe warsztaty), dobrą atmosferę i możliwość dzielenia się wiedzą jak i jej zdobywaniem. Sieć po kablu bardzo dobrze działała, trochę może brakowało informacji, gdzie, jaka sala się znajduje. Rozumiem też, że wydarzenie było darmowe i budżet był nie wielki, ale zabrakło mi... herbaty. No cóż, nie każdy jest przecież kawowcem (choć w naszej branży to chyba tylko jakieś odosobnione wyjątki), ale w ogólnej ocenie całości można ten detal pominąć. Trzymajmy poziom, aby w przyszłym roku było co najmniej tak dobrze jak w tym.

wtorek, 2 lipca 2013

I hate Eclipse

Nienawidzę Eclipse’a. Jest to narzędzie, do którego używania jestem zmuszany, a które w swoim rozwoju się gdzieś tam dawno temu zatrzymało. Niby można w nim znaleźć to samo co oferuje konkurencja, czyli IntelliJ Idea, ale diabeł tkwi w szczegółach, które poniżej przedstawiam. Niby autorzy obydwu środowisk przeczytali  zapewne książkę Martina Fowlera Refactoring: Improving the Design of Existing Code, ale nie wszyscy wykonali robotę tak jak trzeba.

Zaznaczam jednocześnie, że spędziłem sporo czasu na poznanie obu tych środowisk, co wcale nie oznacza, że znam je na wylot. Jak by się więc coś nie zgadzało w opisywanych przypadkach, to proszę o sprostowanie w komentarzu.

Podpowiedzi w kodzie

W Idei mamy tak:



wciskam Alt + Enter i mam:



Czyli zaimportowało mi żądaną kolekcję (a dokładniej interfejs kolekcji), który może być parametryzowany. A więc dokładnie to co chciałem i to jest najczęściej oczekiwane przez 99% developerów.
W Eclipse, chcąc zrobić to samo, otrzymuję długaśną listę, która ma mi niby pomóc:



Na co mi java.awt.List? I to na pierwszej pozycji? Przecież ona nie działa z typami generycznymi, więc powinno być jasne, że to się nie będzie kompilować. A skorzystał ktoś z was kiedyś z którejś opcji od 5 w dół? Idea widząc ten sam kod, patrzy nie tylko na nazwę klasy, ale i na to czy występują ostre nawiasy. Przecież generyki mamy w Javie od połowy 2004 roku.

Zgadywanie typów

Tworząc kod z wykorzystaniem TDD, często najpierw wybieram nazwę dla zmiennej, wywołuję jakąś metodę na niej, a na koniec się zastanawiam, czy powinna to być zmienna lokalna czy pole w klasie i jaki de facto powinien być zadeklarowany typ. W Idei robi się to bardzo przyjemnie (Alt + Enter):



i po wybraniu pierwszej opcji:


Idea proponuje mi, co będzie pasowało, skoro na danym obiekcie chcę wywołać metodę put(). W tym przypadku chcę mieć mapę i takowa podpowiedź jest dostępna.
A w Eclipse:



i po wybraniu drugiej opcji muszę sam przeskoczyć do nowo utworzonej definicji. Miało by to sens, gdyby tworzona automatycznie definicja dała się skompilować. Przeskakuję:


ale brak tu jakiejś sensownej podpowiedzi:


ReformatSettings to klasa, w której wklejałem ten kod, a więc zero pomocy ze strony środowiska.

Tworzenie instancji nowych obiektów

W Idei mamy Ctrl + Space:



i widzimy to co pasuje do interfejsu zadeklarowanego po lewej stronie znaku równości. Na pierwszej pozycji najczęściej wybierana opcja, na drugiej pozycji goły interfejs. Dalej jakieś inne możliwe implementacje.
Analogicznie w Eclipse:


A tu bieda aż piszczy. Nawet jak spróbujemy podpowiedzieć Eclipse’owi co ma zrobić, to i tak mu nie wychodzi:


W powyższym przykładzie próbuję utworzyć instancję klasy implementującej interfejs Map. Wpisuję HM, wciskam Ctrl + Space spodziewając się podpowiedzi, aby utworzyć HashMap’ę. Co dostaję? Jakieś HMACParameterSpec – klasa której nigdy nigdzie nie użyłem, nie wiem do czego służy i (najgorsze) która nie implementuje interfejsu Map.
A jak sprawa wygląda w Idei:


Jako podpowiedź dostaję jedyną słuszną klasę jaka w tym kontekście pasuje do zadeklarowanego interfejsu.

Dopasowywanie podpowiedzi do kodu

Na ten przykład natrafiłem tworząc jeden z postów: Logowanie interakcji w Mockito i jak się trochę nad tym zastanowiłem, że takie kodowanie to czysta przyjemność.

Na początek Idea. Mamy taki oto stan i piszemy właśnie konfigurację mocka:


Tutaj akurat zwykłe Ctrl + Space jakoś szczególnie nie zachwyca (jak to się mówi dupy nie urywa). Ale zobaczmy co się dzieje gdy wciskamy Ctrl + Shift + Space (Smart type).


I tutaj już Idea widzi, co można dopasować. Jako że metoda createUser() jako argumenty przyjmuje login i password, to pierwszą preferowaną opcja jest tutaj wcześniej utworzona stała LOGIN. Co ciekawsze to nie ma na liście analogicznej stałej, ale o nazwie PASSWORD, a która teoretycznie na podstawie typu pasuje! Czyż nie jest to powalające? Mamy również poniżej kilka ciekawych metod, które zwracają String’a jako rezultat, który może nam tutaj ewentualnie podpasować i metodę any() z Mockito! Skąd Idea wie, że jeśli się zabawiamy z Mockami, to w tym miejscu możemy (i ma to sens) wywołać tą metodę?

Idźmy dalej. Zatwierdzamy pierwszą propozycję (LOGIN) Enterem i ponownie naciskamy Ctrl + Shift + Space:



I znów analogiczna podpowiedź. Wybieramy pierwszą, właściwą opcję i Enter. Dopisujemy jeszcze co ma się stać po wywołaniu tej metody, czyli:



I teraz tak:
Ctrl + Shift + Space
Ctrl + Shift + Space
Enter
Ctrl + Shift + Space
Enter
Ctrl + Shift + Enter

I mamy wszystko czego nam do szczęścia potrzeba, razem ze średnikiem na końcu linii.



A w Eclipse:



Jedynie nazwy i typy argumentów. Na dalszym miejscu jest trochę lepiej, przy okazji new:



Po naciśnięciu Ctrl + Space:



mamy jakąś konkretną podpowiedź. Później jest już trochę lepiej:


Ale nadal nie jest to co w Idei.

Dopasowywanie argumentów metod

Kolejna sprawa z podpowiadaniem. Często jako argument metody pasuje tylko jeden typ (np. Enum). W przypadku podpowiedzi Eclipse’a jest trochę ubogo:



Dostajemy tylko nazwy argumentów. Trochę lepiej sprawa ma się gdy zaczniemy pisać nazwę oczekiwanego Enuma:



Tylko na co mi te wszystkie klasy od drugiej w dół? Przecież one w ogóle tu nie pasują. Mój argument jest prostym typem wyliczeniowym, który sam zdefiniowałem, który po niczym nie dziedziczy i nikt po nim nie dziedziczy, bo się nie da. Jest to niepotrzebne zaciemnianie ekranu.

Analogicznie w Idei, przy Ctrl + Space mamy coś takiego:



czyli możemy tą wartość wyczarować z obiektów które mamy (args, export), lub z Enuma. Jeśli chcemy podać konkretną wartość, to lepiej w tym wypadku skorzystać z Ctrl + Shift + Space:



i tu już mamy to co na pewno do sygnatury metody będzie pasować w bardziej zwięzłej formie. A jeśli nie pamiętamy tego skrótu klawiszowego (lub nie pamiętamy dokładnego znaczenia), to zawsze można napisać pierwszą literę potrzebnego Enuma i skorzystać ze standardowego Ctrl + Space:



I wtedy pasujące konkretne wartości typu wyliczeniowego zostaną dopasowane do otoczenia.

Uzupełnianie metod zależnie od kontekstu

Często mi się zdarza, że muszę zmienić nazwę metody, gdy mam już porządnie przygotowaną listę argumentów. Oczywiście w Eclipse działa to tragicznie. Przykładowo mamy taką sytuację:


Argumenty metody są już dobrze dopasowane, ale z jakiś względów początkowo źle wybrałem nazwę asercji. Zaczynam pisać poprawną nazwę metody, potem Ctrl + Space:



i dostaję podpowiedź w postaci różnych wariantów oczekiwanej metody. Wybieram pierwszą podpowiedź z brzegu:


i muszę od nowa uzupełniać listę argumentów. Bezsens!

Jak to działa w Idei? Po naciśnięciu Ctrl + Space również dostaję listę pasujących metod:


Wybieram pierwszą:


i wszystko się od razu dopasowuje do kontekstu.

Skróty klawiszowe

Skróty klawiszowe, to trochę delikatna sprawa. Jednym pasują te z Idei, innym te z Eclipse’a. Najczęściej zależy to od tego, których się wcześniej nauczyliśmy i jak bardzo się do nich przyzwyczailiśmy. A przyzwyczajenia to zło. Uznajemy czasem, że skróty są narzucone z góry i są logicznie poukładane. Czy na pewno?

Ctrl + D w Eclipse to usunięcie linii (delete), a w Idei skopiowanie w dół (duplicate). Jest to dla mnie największa bolączka, gdy się przesiadam z jednego środowiska do drugiego, gdyż jest to pierwsza różnica, która mi doskwiera. Do usuwania linii w Idei służy Ctrl + Y, co swoje korzenie ma w edytorze Vim (Yank – yy – usuwa aktualną linię). Ponadto Alt + F7 (wyszukiwanie użyć) i Shift + F6 (zmiana nazwy) mają swoje korzenie z Total Comander'a.

Kolejna sprawa (moja ulubiona), to te genialne czteroklawiszowe skróty w Eclipse, na których można się dorobić trwałego kalectwa palców: Alt + Shift + X, T – wystartowanie testów, lub czegoś innego w zależnie od ostatniej naciśniętej litery. Tą czynność wykonujemy bardzo często w cyklu TDD, więc ten hotkey powinien być łatwiejszy. Jak się doinstaluje MoreUnit, to jest trochę lepiej, ale jak pokazuję ten skrót niektórym kolegom (zwłaszcza tym starszym, którzy etap nauki i rozwoju mają już dawno za sobą), to wymiękają w tym momencie, twierdząc, że taka gimnastyka to dla nich za dużo. Dodatkowo tą ostatnią literę trzeba wcisnąć nie za szybko i nie za późno.

Kolejny super skrót to np. Alt + Shift + Q, C – przeskoczenie do konsoli. Można również przeskoczyć do innych widoków... Tylko co z tego, skoro aby wrócić do edycji kodu należy kliknąć myszką, lub Ctrl + F7? Skrajna ułomność i niedopatrzenie.

W Idei mamy problem przeskakiwania pomiędzy widokami o wiele lepiej rozwiązany. Do tego używamy Alt + numer widoku. A numery widoku mamy zazwyczaj widoczne na ekranie:


Są to te numerki tuż przy nazwie widoku. Dodatkowo, jak chcemy wrócić już do okna edycji to wciskamy po prostu Esc. Czyż to nie jest intuicyjne? A jak nam to okienko przeszkadza, to można wcisnąć Shift + Esc i je zamknąć, równocześnie przeskakując do okna edycji kodu. Można też ponownie skorzystać z kombinacji przeskakującej do aktualnego widoku (Alt + numer), która przy drugim naciśnięciu zamyka dany widok.

I tu wychodzi kolejna wyższość Idei nad Eclipsem. W Eclipsie mamy koncepcję perspektyw: Java, JavaEE, Debug itd. Jak się pomiędzy nimi przełączamy, to pewne widoki (views) znikają a inne się pojawiają, a jeszcze inne są trochę zdeformowane i na innych pozycjach. W Idei odpowiedniki Eclipsowych widoków pojawiają się i znikają „na żądanie”. Oczywiście wszystko sterowane z klawiatury.

Wracając do skrótów klawiaturowych. W Eclipse brakuje sporo ważnych skrótów, aby były od razu po instalacji dostępne. I tak bardzo często korzystam w Idei ze skakania od razu do implementacji (Ctrl + Alt + B). W Eclipse trzeba sobie samemu taki skrót podlinkować, np. Alt + F3, aby nie wiele się różnił od typowego skakania do deklaracji. Niestety nie wielu developerów wie o tej możliwości.

Przypisywanie wartości do pól, zmiennych lokalnych, stałych

W Eclipse mamy tzw. Quick Assist (Ctrl + 2), czyli przypisywanie do pola / zmiennej lokalnej, które działa bardzo kiepsko. Przykładowo w Eclipse dla takiego kodu:


nic nie da się zrobić, gdy kursor jest na końcu linii. Zresztą jak się zaznaczy kod od słówka new do końca linii to i tak Eclipse nic z tym nie wymyśli. Alt + Shift + L (Extract Local Variable) też nic nie pomoże. Idea natomiast radzi sobie z tym wyśmienicie:

Ctrl + Alt + V (Value):


Ctrl + Alt + F (Field)


Tutaj dodatkowo Idea sprawdza, czy to samo wyrażenie nie występuje jeszcze gdzieś w kodzie i sugeruje jego zastąpienie. Oczywiście z pomocą Alt + A można to zrobić bez konieczności użycia myszki.

Ctrl + Alt + C (Constans)


Tutaj dodatkowo Idea zapisuje stałą wielkimi literami, jak to się powszechnie w Javie przyjęło. Oczywiście wszystkie te refaktoringi można cofnąć za pomocą Esc lub Ctrl + Z. A jak w Eclipse wyeksportować do stałej? Mamy kolejnego łamańca: Alt + Shift + T, A, które i tak w przykładowym kontekście nie zadziała i do którego nie ma przypisanego standardowego skrótu.

Eclipse również sobie nie radzi jak ma trochę bardziej skomplikowane wyrażenie, którego wynik chcemy zapamiętać w zmiennej lokalnej. Przykładowo:


Nie działa ani Ctrl + 1, Ctrl + 2, ani Alt + Shift + L. Bieda! A w Idei Ctrl + Alt + V zachowuje się zgodnie z oczekiwaniem:


Idea pozwala nam zadeklarować pole jako final, zmienić przy tej okazji typ zmiennej, jak i sam dorzuca średnik na końcu.

Zaznaczanie tekstu

W Idei jest jeszcze cos takiego jak Ctrl + W (Incremental expression selection). W Eclipse jest niby coś analogicznego: Alt + Shift + Up, ale nie działa to tak fajnie jak w Idei.

Przesuwanie kodu w pionie

Kolejnym skrótem, którego mi bardzo brakuje w Eclipse jest inteligentne przesuwanie kodu Ctrl + Shift Up/Down (Move Statement Up). W Eclipse brak ekwiwalentnego skrótu, a działa on tak:

Przed:


Po:


Czyli po naciśnięciu Ctrl + Shift + Up cała metoda setName() została przeniesiona powyżej getName(), czyli tam gdzie ma ona sens. Jest to bardzo przydatna funkcjonalność podczas refaktoringu.

Komentowanie

Jeszcze irytująca mnie rzecz, to działanie Ctrl + / w Eclipse. Skrót ten wstawia komentarz w aktualnie zaznaczonych liniach, ale działa tylko w Javie. W przypadku plików XML, HTML i innych należy używać  kolejnego, ale działającego wszędzie łamańca: Ctrl + Shift + C, zamiast prostego Ctrl + /. W Idei ten ostatni skrót działa wszędzie i wstawia komentarz zależnie od kontekstu w jakim się znajdujemy.

Refactoring

W Idei gdy zmieniamy nazwę pola w klasie (Shift + F6), które to posiada gettery i settery, to dostajemy zapytanie, czy te metody dostępowe również przeorać:


Dodatkowo Idea sugeruje, aby dopasować nazwę parametru w konstruktorze do nowej nazwy pola:


wciskamy spację, lub Alt + A aby wybrać wszystkie sugestie i Ctrl + Enter aby zamknąć okno. Następnie Idea jeszcze sugeruję nazwę pola, która jest użyta jako tekst w metodzie toString():


Oczywiście akceptujemy to za pomocą Alt + D i gotowe! Wszystko co chcieliśmy zostało dopasowane.

A w Eclipse? Eclipse zmienia tylko nazwę pola. Musimy sami pamiętać o getterach / setterach, konstruktorach i tekstach w toString(). Czyli mamy jakieś plus 4 więcej kroków do wykonania!

W Idei również działa całkiem dobrze (albo właściwie nie wiele gorzej) refaktoring, gdy go wykonujemy, gdy nasz kod się nie kompiluje. Dla Eclipse’a jest to najczęściej nie do wykonania.

Usability

Standardowo w Eclipse jest sporo ukrytych funkcjonalności. Czyli jeśli nie przeczytasz setki tutoriali, lub jeśli nie przeklikasz każdej opcji z okna Preferences, to będziesz mógł sobie tylko żyły wypruwać. I tak podczas Legacy Code Retreat, miałem spory problem z głupim wklejeniem tekstu wielolinijkowego do edytora tak, aby był traktowany jako String. Praktyczny przykład poniżej:


W Eclipse funkcjonuje to tak:


Czyli istna tragedia. Razem z osobą, z którą aktualnie byłem sparowany, straciliśmy z 10 minut, na doprowadzenie tego do stanu używalności, za pomocą metody find & replace. W Idei jest to out of the box:


Później jeszcze poszukałem chwilkę w necie i znalazłem rozwiązanie na to:


Źródło: http://stackoverflow.com/questions/2159678/paste-a-multi-line-java-string-in-eclipse

Inne, ogólne

Kolejny wielki błąd w designie Eclipsa to brak ciągłej synchronizacji pomiędzy tym co jest w edytorze a stanem na dysku twardym. Wystarczy czasem zrobić builda z zewnątrz lub jakiegoś update’a z repozytorium i podczas próby otwarcia pliku otrzymujemy coś podobnego do tego widoku:


Jeszcze jestem w stanie zrozumieć, że Eclipse nie odświeża sobie wszystkich plików ze wszystkich otwartych projektów (choć w Idei to działa dobrze i szybko), ale w momencie próby otworzenia pliku mógłby sobie już sam automatycznie to odświeżyć, zamiast wypisywać out of sync.

Dodatkowo jakość pluginów Eclipsowych jest bardzo słaba. Są one rozwijane po za podstawowym środowiskiem, czyli czasem działają, czasem nie, a po jakimś czasie autorzy często zarzucają jego rozwój. Tak się np. stało z MouseFeed, który przez długi czas nie działał z Eclipsem 4.X. Na szczęście plugin został ostatnio reaktywowany: Eclipse Mousefeed Plugin Merged With Marketplace Plugin. W przypadku innych pluginów nie wszystko zawsze dobrze działa. W Idei natomiast rozwój pluginów jest wspierany przez samych twórców, którzy dostarczają odpowiednią ich jakość i ich niezawodność.

Kilka dni temu (tj. 26 czerwca 2013) opublikowano nową wersję Eclipse'a 4.3 Kepler. Jeszcze jej nie sprawdzałem, ale pewnie nie wiele się zmieniło. Zrobię to pewnie za jakiś czas, jak już pluginy dostosują.

To chyba by było na tyle, choć jak by się chciało, to by się jeszcze znalazło parę Eclipse’owych niedogodności, ale wtedy nigdy bym nie opublikował tego posta. Następnym razem jak ktoś się mnie zapyta, „a co takiego ma Idea, czego nie ma Eclipse?” to go po prostu odeślę do tego artykułu.

A ty które wybierasz?