Projekt Bilet #5 — Aktualizujemy zależności

By 24 March 2019 Projekt Bilet

Od cza­su, kiedy rozpoczęliśmy Pro­jekt Bilet, minęło już trochę cza­su — warto więc zak­tu­al­i­zować wszys­tkie zależnoś­ci. Tym zajmiemy się w dzisiejszym (mini) wpisie.

Aktu­al­iza­c­je bib­liotek nie są nieste­ty zbyt częstą prak­tyką — w końcu taka zmi­ana może wyma­gać sto­sunkowo sporej iloś­ci niedużych zmi­an, wyma­ga dokład­niejszego przetestowa­nia, a jed­nocześnie nie zapew­nia żad­nej dodatkowej funkcjon­al­noś­ci dla naszych użytkown­ików. Jeśli chodzi o wyda­jność, częs­to tego typu aktu­al­iza­c­ja nie wprowadza zmi­an lub są one minimalne.

Mimo wszys­tko warto raz na jak­iś czas przez­naczyć czas na aktu­al­iza­cję bib­liotek. Pier­wszy, najbardziej namacal­ny powód, to kwes­t­ia zabez­pieczeń. Im bardziej automaty­cznie coś dzi­ała, tym więk­sze ryzyko, że opro­gramowanie to zaw­iera błędy lub luki (moż­na tutaj przy­wołać jako przykład jeden z najwięk­szych wycieków danych w his­torii, które­mu moż­na by potenc­jal­nie zapo­biec dba­jąc o aktu­al­iza­c­je bib­liotek). Dru­ga kwes­t­ia to wyko­rzys­tanie najnowszych tech­nologii i możli­woś­ci języ­ka — być może dzię­ki aktu­al­iza­cji jest okaz­ja uproś­cić jakąś część aplikacji lub pozbyć się kodu, który ter­az jest ‚w pakiecie’. To także dobra okaz­ja do małych porząd­ków w kodzie — dopisa­nia testów, podzie­le­nia dużych klas na mniejsze itp. Przede wszys­tkim jed­nak, częs­ta aktu­al­iza­c­ja wer­sji pozwala uniknąć ‚skokowych’ zmi­an (np. wyobraź sobie aktu­al­iza­c­je aplikacji napisanej dla Spring 2 od razu do Spring 5, gdzie zmienia się prak­ty­cznie wszys­tko). Dzię­ki temu nasza aplikac­ja nie stanie się ‚lega­cy’, którym kole­jne pokole­nia pro­gramistów będą się straszyć ;)

Semver

Zan­im zabierze­my się za aktu­al­iza­cję, na początek trochę teorii. W tym wypad­ku — o wer­s­jach. Jak zapewne zauważyłaś, wiele bib­liotek ma wer­sje składa­jącą się z dwóch lub trzech częś­ci odd­zielonych krop­ka­mi. To stan­dar­d­owy sposób zapisu wer­sji, a każdy z tych członów ma spec­jalne znacze­nie. Ele­men­ty skład­owe mają nazwy MAJOR.MINOR.PATCH, czyli np. wer­s­ja 1.7.19 moż­na zapisać jako:

  • 1 — Major
  • 7 — Minor
  • 19 — PATCH

Z założe­nia, pier­wsza część jest liczbą powin­na zostać zwięk­szona za każdym razem, kiedy wprowadzane są zmi­any niez­godne wstecz. Tzn aplikac­je, które korzys­ta­ją z Two­jego API/biblioteki, przes­taną dzi­ałać (zakładamy, że w kodzie nie zostaną wprowad­zone żadne zmiany).

Dru­ga część — także liczbowa — powin­na zostać zwięk­szona w przy­pad­ku zmi­an funkcjon­al­noś­ci, które nie powodu­ją prob­lemów ze zgod­noś­cią wstecz (np. dodanie nowego API/interfejsu lub nowego, opcjon­al­nego pola do ist­nieją­cych obiektów).

Trze­cia część najczęś­ciej zaw­iera liczbę oraz kwal­i­fika­tor (np. 2‑beta, 1‑SNAPSHOT, 13-rc1 itp). Zwięk­sza­my ją za każdym razem, kiedy wprowadza­my zmi­any nie powodu­jące zmi­an w funkcjonalności/API (np. popraw­iamy jakieś błędy, refak­toru­je­my kod itp).

Taki sys­tem nazy­wa­nia wer­sji znaczą­co upraszcza automatyza­cję i porówny­wanie wer­sji (np. jest jasne, że wer­s­ja 2.5 jest nowsza od 2.4, nato­mi­ast 2.0 jest nowsza od 1.9). Stan­dard ten, nazy­wany Seman­tic Ver­sion­ing (lub Semver w skró­cie), jest jed­nak bardziej odzwier­ciedle­niem pop­u­larnej prak­ty­ki niż stan­dar­d­em do którego wszyscy się sto­su­ją — np. sufiksy ‑SNAPSHOT czy ‑RELEASE znane z Mave­na są teo­re­ty­cznie niez­godne ze stan­dar­d­em. Podob­nie dwuczłonowe numer wer­sji (np. 1.1) — niem­niej z punk­tu widzenia uży­wanych narzędzi stan­dard ten opisu­je ide­alne założe­nia jeśli chodzi o wer­sjonowanie naszych aplikacji/bibliotek — warto się z nim przy­na­jm­niej zapoznać.

Więcej infor­ma­cji zna­jdziesz na głównej stron­ie poświę­conej tej kon­wencji — semver.org

Sprawdzanie wersji

Sko­ro ustalil­iśmy już, jak czy­tać wer­sje, pora z tej wiedzy sko­rzys­tać. A ponieważ jesteśmy pro­gramis­ta­mi, lenist­wo jest naszą najwięk­szą zaletą — poz­wolimy więc kom­put­erowi zająć się wszys­tkim za nas.

W tym celu sko­rzys­tamy z plug­inu ‘ver­sions’, a dokład­niej jego celu dis­play-depen­den­cy-updates . W kat­a­logu pro­jek­tu wywołu­je­my komendę

mvn org.codehaus.mojo:versions-maven-plugin:display-dependency-updates

W efek­cie Maven sprawdzi dostęp­ne wer­sje a następ­nie pokaże raport oraz infor­ma­c­je o możli­wych aktualizacjach.

Plu­g­in ten ma także cel depen­den­cy-updates-report , którego dzi­ałanie jest właś­ci­wie iden­ty­czne, z tą różnicą że generu­je wspom­ni­any raport do pliku (zna­jdziesz go w kat­a­logu {katalog_projektu}/target/site/dependency-updates-report.html) — może to być przy­datne, jeśli budu­jesz włas­ną infra­struk­turę do budowa­nia pro­jek­tów lub ta, której uży­wasz, jest w stanie takie raporty automaty­cznie anal­i­zować. Raport ten zaw­iera też więcej infor­ma­cji (np. o wer­s­jach w przy­pad­ku aktu­al­iza­cji wer­sji tylko minor).

Maven 2 i ‚najnowsze’ wersje lub przedziały wersji

Zas­tanaw­iasz się pewnie, dlaczego nie moż­na po pros­tu określić wer­sji zależnoś­ci jako ‚najnowsza’ i zapom­nieć o prob­lemie, sko­ro Maven ‚rozu­mie’ kole­jność wersji?

Otóż his­to­rycznie było to możli­we — w Maven 2 funkcjonowały ‚metaw­er­sje’ — zami­ast podawa­nia konkret­nej wer­sji moż­na było określić wer­sję jako ‚RELEASE’ lub ‚LATEST’ co pod­czas budowa­nia było pod­mieni­ane na najnowszą wer­sję (uwzględ­ni­a­jąc wyda­nia snap­shot, wer­sje beta itp) lub najnowszą wer­sję z sufik­sem ‑RELEASE. Ta możli­wość została usunię­ta w wer­sji 3 Mavena.
Głównym powo­dem usunię­cia była pow­tarzal­ność pro­ce­su budowa­nia. Dość częstą prak­tyką, w szczegól­noś­ci w więk­szych fir­ma­ch i narzędzi­ach typu CI, jest lokalny cache arte­fak­tów. Pozwala to zaoszczędz­ić sporo łącza i trans­feru (pod­czas budowa­nia bib­liote­ki nie są pobier­ane z inter­ne­tu tylko z lokalnego ser­w­era) oraz cza­su (pobranie z ser­w­era w sieci lokalnej jest dużo szyb­sze od pobiera­nia ze zdal­nego ser­w­era, co ma znaczą­cy wpływ na czas trwa­nia pro­ce­su budowa­nia w przy­pad­ku więk­szych pro­jek­tów). Ta opty­mal­iza­c­ja powodu­je jed­nak że dla kom­put­erów w różnych sieci­ach ‚najnowsza wer­s­ja’ może oznaczać coś innego. Przez to aplikac­ja (lub bib­liote­ka) będzie dzi­ałała inaczej w zależnoś­ci od tego na którym ser­w­erze została zbu­dowana. Powodowało to także sporo prob­lemów z tes­ta­mi, które mogły zacząć zgłaszać prob­le­my w ‚losowych’ momen­tach. Wszys­tko to powodowało, że pro­ces wyt­warza­nia opro­gramowa­nia przestawał być deter­min­isty­czny, co jest pod­sta­wową zaletą uży­wa­nia kom­put­erów ;) Z tego powodu kon­cept porzu­cono na rzecz ścisłego określa­nia uży­wanych wersji.

Więcej infor­ma­cji na ten tem­at zna­jdziesz w ofic­jal­nej notce na stron­ie Apache Foun­da­tion.

Teoria a praktyka

W tym miejs­cu warto zwró­cić uwagę na jeszcze jed­ną rzecz — praw­idłowe wer­sjonowanie bard­zo częs­to ma miejsce w przy­pad­ku bib­liotek i aplikacji dostęp­nych pub­licznie (moż­na powiedzieć wręcz że jest to wymóg, aby aplikacja/biblioteka była trak­towana w środowisku poważnie i aby inni devel­op­erzy mieli zau­fanie do korzys­ta­nia z niej).
Rzecz najczęś­ciej ma się zupełnie inaczej w fir­ma­ch i wewnętrznych pro­jek­tach. W takim wypad­ku bard­zo częs­to aplikac­je rozwi­jane są równole­gle (co powodu­je częste zmi­any, które teo­re­ty­cznie powin­ny gen­erować kole­jne wer­sje opro­gramowa­nia) oraz stale (przez co prob­lem z niekom­paty­bil­noś­cią zmi­an jest zauważany i rozwiązy­wany w prze­ciągu godzin a nie dni czy tygod­ni). W takim środowisku poprawne uży­wanie numerów wer­sji wiąza­ło by się z dużym nakła­dem pra­cy i cza­su aby za każdym razem aktu­al­i­zować wer­sje, przez co prze­ważnie (to uogól­nie­nie — są oczy­wiś­cie firmy, które nawet w wewnętrznych pro­jek­tach trzy­ma­ją się pewnych zasad wer­sjonowa­nia) przez całe swo­je życie aplikac­ja jest w wer­sji ‚1.0‑SNAPSHOT’ .

Jest to jed­na z sytu­acji w których obiek­ty­wnie sen­sow­na prak­ty­ka jest po pros­tu nieefek­ty­w­na i kosz­tow­na, a więc także pomi­jana. Ma to oczy­wiś­cie pewne kon­sek­wenc­je, ale w prze­waża­jącej więk­szoś­ci przy­pad­ków oszczęd­ność cza­su i wysiłku jest zde­cy­dowanie więk­sza niż ewen­tu­alne problemy.

Od każdej zasady wys­tępu­ją także wyjąt­ki — nieste­ty są bib­liote­ki, które w kilku przy­pad­kach zła­mały schemat numer­acji wer­sji (celowo lub przez pomyłkę). Przykła­dem może być bib­liote­ka antlr — w listopadzie 2005 roku wrzu­cono wer­sję ‘20030911’. I choć od tego cza­su było już kil­ka aktu­al­iza­cji (w momen­cie pisa­nia tego artykułu najnowszą dostęp­ną wer­sją jest 3.0ea8), to plu­g­in pod­powia­da wer­sję ‘20030911’ jako najnowszą (w myśl semver, wer­s­ja ta ma major ‘2030911’, która jest wyższa niż ‘3’). Z tego powodu warto zwracać uwagę, jakie fak­ty­cznie zmi­any są wprowadzane (szczegól­nie jeśli korzys­tamy z automaty­cznego pluginu)

Zanim zaczniemy — przygotowanie do pracy z Javą 9+

Wraz ze zmi­aną sposobu wydawa­nia nowych wer­sji języ­ka Java, wiele orga­ni­za­cji szy­b­ciej wdraża najnowsze wer­sje. W dużej mierze nie powin­no nam to robić różni­cy, ponieważ Java z założe­nia zakła­da zgod­ność wstecz. Wyjątkiem jest Java 9, a dokład­niej sposób orga­ni­za­cji ‘bazowych’ kom­po­nen­tów. To tem­at na osob­ny wpis, ale w dużym uproszcze­niu zmi­ana pole­ga na tym, aby jak najbardziej ‘odchudz­ić’ stan­dar­d­owe bib­liote­ki i nie ład­owanie niepotrzeb­nych ele­men­tów (które stały się częś­cią JDK/JRE, a jed­nocześnie nie są powszech­nie potrzeb­ne w pro­jek­tach. Jed­nym z przykładów mogą być bib­liote­ki do par­sowa­nia plików XML — niewiele współczes­nych pro­jek­tów z nich korzys­ta, a jed­nocześnie były one częś­cią stan­dar­du Java EE.

Prob­lem pojaw­ia się jeśli nasz pro­jekt korzys­ta z tych bib­liotek (częs­to nie bezpośred­nio, tylko np. frame­work lub jakaś bib­liote­ka) — aktu­al­izu­jąc Javę, pro­jekt przes­tanie się kom­pi­lować. W naszym przy­pad­ku prob­lematy­cz­na jest właśnie bib­liote­ka do XMLi, z której korzys­ta testowa baza danych. Są dwie możli­woś­ci — może­my albo dodać spec­jalne argu­men­ty do kom­pi­la­to­ra Javy, albo pobrać te klasy jako zależnoś­ci (nieco szer­szy opis i porów­nanie moż­na znaleźć w świet­nej odpowiedzi na Stack Over­flow ; lista zależnoś­ci tutaj). Ponieważ bib­liote­ki te zostaną usunięte w przyszłych wer­s­jach Javy całkowicie, najbez­pieczniejszą opcją jest dodanie ich jako zależności:

<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.0</version>
</dependency>

a także:

<dependency>
  <groupId>javax.activation</groupId>
  <artifactId>activation</artifactId>
  <version>1.1</version>
</dependency>
<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
  <version>2.3.2</version>
</dependency>

Natkniemy się też potenc­jal­nie na kil­ka innych prob­lemów, np. uży­wana przez nas wer­s­ja Find­bugs nie wspiera Javy 11 (wystar­czy aktu­al­iza­c­ja do wer­sji 3.1.7: https://github.com/spotbugs/spotbugs/blob/release‑3.1/CHANGELOG.md#317—2018–09-12). Warto je rozwiązać zan­im prze­jdziemy dalej (dzię­ki temu prob­le­my nie nawarst­wią się i będzie nam łatwiej radz­ić sobie z nimi po kolei).

Krok pierwszy — aktualizowanie dodatkowych zależności

Oczy­wiś­cie może­my po pros­tu zak­tu­al­i­zować wszys­tkie zależnoś­ci do najnowszych wer­sji a następ­nie popraw­ić wszys­tkie znalezione błędy. To może być szyb­sza meto­da w małych pro­jek­tach, które nie zdążyły się za bard­zo ‘zes­tarzeć’, ale nie sprawdzi się za dobrze w więk­szych i bardziej złożonych projektach.

Dodatkowe zależnoś­ci to wszys­tkie bib­liote­ki, które nie są zarządzane przez nasz par­ent pom (w tym wypad­ku takie, które nie są zarządzanie przez Spring Boot). Do tej grupy częs­to zal­icza­ją się mniejsze bib­liote­ki, które nie są na tyle pop­u­larne aby dołączać je do np. Spring Frame­work. W ich wypad­ku najczęś­ciej pro­jekt po aktu­al­iza­cji budu­je się, ale mogą pojaw­ić się błędy log­iczne. Dlat­ego ważne jest, aby uru­chomić wszys­tkie możli­we testy, a także odpal­ić aplikację i ‘przek­likać’ wszys­tkie możli­we do sprawdzenia scenariusze.

Tutaj posłużymy się wygen­erowanym wcześniej pod­sumowaniem —  będzie on bard­zo dłu­gi, ponieważ zaw­iera także wszys­tkie zależnoś­ci zarządzane przez Spring Boot (te zna­jdziemy pod nagłówkiem ‘The fol­low­ing depen­den­cies in Depen­den­cy Man­age­ment have new­er ver­sions’; w przy­pad­ku rapor­tu gen­erowanego do pliku jest to sekc­ja ‘Depen­den­cy Man­age­ment’). Intere­su­jące nas zależnoś­ci w sekcji ‘The fol­low­ing depen­den­cies in Depen­den­cies have new­er ver­sions’ (w przy­pad­ku rapor­tu w pliku jest to ‘Depen­den­cies’), gdzie zna­jdziemy infor­ma­c­je o możli­wej aktu­al­iza­cji naszej testowej bazy danych. Aktu­al­iza­cję numeru wer­sji może­my wykon­ać ręcznie, albo automaty­cznie za pomocą komendy

mvn org.codehaus.mojo:versions-maven-plugin:use-latest-releases

Ten goal ma wiele użytecznych opcji, np. taką, która pozwala na aktu­al­iza­cję tylko wer­sji minor (jeśli dostęp­na). Więcej infor­ma­cji zna­jdziesz w doku­men­tacji.

Warto także sprawdz­ić czy są dostęp­ne nowsze wer­sje uży­wanych przez nas plug­inów i w razie potrze­by je zaktualizować:

mvn org.codehaus.mojo:versions-maven-plugin:display-plugin-updates

Krok drugi — aktualizacja parent POMa (minor releases)

Kole­jnym krok­iem jest aktu­al­iza­c­ja par­ent POMa — w naszym przy­pad­ku wer­sji Spring Boot. Ten pro­ces rozbi­je­my jed­nak na dwa etapy — aktu­al­iza­cję wer­sji minor oraz aktu­al­iza­cję wer­sji major.

W tym celu nieste­ty nie może­my sko­rzys­tać z tego samego plug­inu, i jego celu ‘update-par­ent’ — ten cel nie pozwala na ogranicze­nie zmi­an wer­sji tylko ‘minor’, przez co tę zmi­anę musimy wykon­ać ręcznie. Dostęp­ne wer­sje może­my sprawdz­ić w cen­tral­nym repozy­to­ri­um lub jed­nej z bliź­ni­aczych stron. W naszym przy­pad­ku najnowszą dostęp­ną wer­sją 1.x jest 1.5.19.RELEASE — i z tej wer­sji skorzystamy.

Ten krok przy­na­jm­niej w teorii nie powinien spowodować żad­nych zmi­an funkcjon­al­nych. Frame­wor­ki częs­to bard­zo dba­ją o to, aby numer­ac­ja wer­sji była zgod­na z założe­ni­a­mi semver, więc stan­dar­d­owy zestaw testów jed­nos­tkowych i inte­gra­cyjnych powinien wystar­czyć, aby upewnić się, że aplikac­ja dzi­ała tak jak oczeku­je­my (to nie znaczy, że ni warto przetestować aplikacji dokład­niej! Te kil­ka godzin pra­cy może oszczędz­ić Ci masę potenc­jal­nych prob­lemów, gdy­by coś jed­nak nie działało).

To także dobry moment na wrzuce­nie zmi­an ‘pośred­nich’ na repozy­to­ri­um oraz potenc­jal­nie na środowisko pro­duk­cyjne — kole­jny krok jest znacznie bardziej ryzykowny, ale też potenc­jal­nie czasochłon­ny (zarówno z uwa­gi na dos­tosowanie kodu jak i rozsz­er­zone testowanie).

Krok trzeci — aktualizacja parent POMa (major releases)

Ostat­ni krok to ‘grande finale’ naszych aktu­al­iza­cji — aktu­al­iza­c­ja major release. Oczy­wiś­cie nie zawsze ten krok jest konieczny — cza­sem aktu­al­izu­jąc wer­sję minor, osiąg­niemy najnowszą dostęp­ną. W naszym przy­pad­ku tak nie jest — najnowszą wer­sją Spring Boot jest na chwilę obec­ną 2.1.3.RELEASE, a więc zaka­su­je­my rękawy, parzymy kawę i zabier­amy się do pracy.

Pier­wszą rzeczą, którą chce­my sprawdz­ić, to jakie zmi­any trze­ba wprowadz­ić. Jest (mała) szansa na to, że aktu­al­iza­c­ja nie zmienia rzeczy, z których korzys­tał nasz pro­jekt (tak było np. w przy­pad­ku wielu ‘stan­dar­d­owych’ pro­jek­tów aktu­al­i­zowanych ze Springa 3 do 4). Nieste­ty, w naszym przy­pad­ku nie mamy takiego szczęś­cia i pro­jekt nawet się nie skom­pilu­je. (Ważne! To, że pro­jekt po aktu­al­iza­cji się skom­pilu­je, nie znaczy, że dzi­ała! Koniecznie uru­chom go lokalnie, ‘przek­likaj’ wszys­tkie ścież­ki i spróbuj wywołać błędy np wysyła­jąc w zapy­ta­niu niepraw­idłowe dane — testowanie zawsze powin­no objąć także ścież­ki negaty­wne!). Zaczy­namy od najważniejszego (kawy), po czym zaczy­namy szukać w sieci. Kil­ka infor­ma­cji szczegól­nie przy­dat­nych pod­czas migracji:

Każ­da aplikac­ja jest inna, i kro­ki opisane poniżej mogą nie wystar­czyć do migracji innej aplikacji. Są one jed­nak dobrym punk­tem star­tu, a powyższe lin­ki powin­ny pomóc z inny­mi problemami.

Pier­wsza zmi­ana to usunię­cie stałej SecurityProperties.ACCESS_OVERRIDE_ORDER, którą uży­wal­iśmy w naszym Secu­ri­ty­Con­fig’u. Ponieważ nie była to kry­ty­cz­na linia, może­my się jej w całoś­ci pozbyć.

Kole­j­na zmi­ana to usunię­cie spring-secu­ri­ty-oau­th2 z zarządzanych zależnoś­ci. Wystar­czy dodać konkret­ny numer wer­sji, w naszym przy­pad­ku zamieniając:

<dependency>
  <groupId>org.springframework.security.oauth</groupId>
  <artifactId>spring-security-oauth2</artifactId>
</dependency>

na:

<dependency>
  <groupId>org.springframework.security.oauth</groupId>
  <artifactId>spring-security-oauth2</artifactId>
  <version>2.3.5.RELEASE</version>
</dependency>

co powin­no rozwiązać wszys­tkie prob­le­my z budowaniem pro­jek­tu. Niem­niej Spring Secu­ri­ty 5 wprowadz­ił jeszcze jed­ną ważną zmi­anę, a mianowicie wprowadza­jąc nowy sposób prze­chowywa­nia haseł (zmi­ana domyśl­nej imple­men­tacji Pass­wor­dEn­coder) — więcej na ten tem­at zna­jdziesz w release note. Z naszego punk­tu widzenia oznacza to trzy rzeczy:

  • musimy zmienić imple­men­tację wg opisu w release note w naszym SecurityConfig
  • zmienić sposób zapisu wszys­t­kich haseł i sekretów wg nowego sposobu, tzn: 
    • w bazie danych musimy zmienić wszys­tkie hashe haseł doda­jąc na początku ‘{bcrypt}’ (bez apostrofów)
    • a także w klasie Oauth2AuthServerConfig podać fron­tend­ClientSe­cret z pre­fik­sem ‘{noop}’ — w prze­ci­wnym razie nasze zapy­ta­nia o toke­ny OAuth będą gen­erowały dzi­wne błędy (może­my to zro­bić zarówno zmieni­a­jąc wartość w kon­fig­u­racji, jak i doda­jąc pre­fiks w samym kodzie — kon­fig­u­rac­ja oczy­wiś­cie pozwala na łatwiejsze mody­fikac­je w przyszłości).

Zmi­an­ie uległy także domyślne ścież­ki w Spring Actu­a­tor — zami­ast /health mamy ter­az /actuator/health. Stosowną zmi­anę musimy wprowadz­ić zarówno w naszych tes­tach inte­gra­cyjnych (Webap­pAp­pli­ca­tion­IT) jak i w kon­fig­u­racji zabez­pieczeń (Secu­ri­ty­Con­fig). W tej wer­sji Actu­a­tor sprawdza także dzi­ałanie Elas­tic­Search (który mamy dodany w zależnoś­ci­ach, ale do tej pory go nie skon­fig­urowal­iśmy) co spowodu­je prob­lem z tes­ta­mi inte­gra­cyjny­mi. Na ten moment usuniemy tą zależność (i dodamy ją ponown­ie, kiedy będziemy z tej funkcjon­al­noś­ci korzystać).

Ostat­nia zmi­ana w naszej aplikacji związana jest ze zmi­aną nazw kluczy kon­fig­u­racji dla liquibase — a dokład­niej doda­niu do nich prze­drost­ka ‘spring.’

Podsumowanie

Aktu­al­iza­c­ja wer­sji jest niezwyk­le waż­na z kilku powodów — przede wszys­tkim pozwala uniknąć prob­lemów i znanych luk bez­pieczeńst­wa (co może doprowadz­ić do tak spek­taku­larnych prob­lemów jak wyciek danych z firmy Equifax w 2017 roku). Reg­u­larne aktu­al­iza­c­je pozwala­ją też na ‘sprzą­tanie’ i popraw­ki kodu mały­mi kroka­mi wraz z każdą nową wer­sją zami­ast wielu poprawek koniecznych przy aktu­al­iza­cji o kil­ka wer­sji. Cały pro­ces nie jest trud­ny — co najwyżej żmud­ny i częs­to wyma­ga­ją­cy czy­ta­nia Release notes oraz szuka­nia rozwiązań po różnych forach.

Kod źródłowy

Przeglądaj kodPobierz ZIP

Kody źródłowe są dostęp­ne w ser­wisie GitHub — użyj przy­cisków po prawej aby pobrać lub prze­jrzeć kod do tego mod­ułu. Jeśli masz wąt­pli­woś­ci, jak posługi­wać się Git’em, instrukc­je i lin­ki zna­jdziesz w naszym wpisie na tem­at Git’a.

Licencja Creative Commons

Jeśli uważasz powyższą lekcję za przy­dat­ną, mamy małą prośbę: pol­ub nasz fan­page. Dzię­ki temu będziesz zawsze na bieżą­co z nowy­mi treś­ci­a­mi na blogu ( i oczy­wiś­cie, z nowy­mi częś­ci­a­mi kur­su Javy). Dzięki!