JTechLog - Viczián István magyar nyelvű Java blogjaKötetlen hangvételű blog a Java világábólhttp://www.jtechlog.hu/favicon.ico2024-03-01T15:31:21+00:00http://www.jtechlog.huViczián IstvánProject Reactor és a szálkezelés2024-01-31T22:00:00+00:00http://www.jtechlog.hu/2024/01/31/project-reactor-szalkezeles<p>A Project Reactor egy Springhez közel álló reaktív könyvtár. Erre épül a Spring Framework 5-ben megjelent WebFlux webes keretrendszer
reaktív webes alkalmazások készítésére. Ez nagyban hasonlít a Spring MVC-re, azonban reaktív módon működik.
Ezzel találkozhatunk akkor is, ha <code class="language-plaintext highlighter-rouge">WebClient</code>-et használunk REST webszolgáltatások hívására
(ez a <code class="language-plaintext highlighter-rouge">RestTemplate</code>-et hivatott leváltani, de úgy tűnik, hogy mégis szükség van egy szinkron megvalósításra is,
ezért jelent meg a 6.1-es Spring Frameworkben a <code class="language-plaintext highlighter-rouge">RestClient</code>). A reaktív elvekről és keretrendszerekről
már írtam a <a href="https://www.jtechlog.hu/2021/08/03/reaktiv-programozas.html">Reaktív programozás</a> posztomban.</p>
<p>A Reactor ún. <em>concurrency-agnostic</em>, ami azt jelenti, hogy nem erőltet ránk semmilyen párhuzamossági modellt.
Azonban a fejlesztőnek lehetőséget ad a szálak használatára.</p>
<p>Ez a poszt azzal foglalkozik, hogy lehet szálakat használni, hogyan befolyásolja a szálak
használatát a <code class="language-plaintext highlighter-rouge">publishOn</code> és <code class="language-plaintext highlighter-rouge">subscribeOn</code> operátor (<code class="language-plaintext highlighter-rouge">Mono</code> és <code class="language-plaintext highlighter-rouge">Flux</code> osztályokban lévő metódusok).</p>
A REST API hypertext-driven legyen2023-10-11T08:00:00+00:00http://www.jtechlog.hu/2023/10/11/hateoas<p>Bár erős vitákat tapasztalok a REST körül, valahogy a hypertext-driven API-val
ritkán találkozom.</p>
<p>Roy T. Fielding, a REST megálmodója a gyakran idézett <a href="https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven">REST APIs must be hypertext-driven</a>
cikkjében a következőt mondja:</p>
<blockquote>
<p>In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period.</p>
</blockquote>
<p>Erre erősít rá a <a href="https://martinfowler.com/articles/richardsonMaturityModel.html">Richardson Maturity Model</a> is, mely
három lépésben mutatja be a REST alapvető elemeit:</p>
<ul>
<li>Level 1 - Resources</li>
<li>Level 2 - HTTP Verbs</li>
<li>Level 3 - Hypermedia Controls</li>
</ul>
<p>És egy API csak akkor nevezhető RESTfulnak, ha az összes szinten leírtakat teljesíti, igen a hypermedia control használatát is.</p>
<p>De mit is jelent ez? Az állítás egyszerű: a kliensnek minden előzetes tudás nélkül igénybe kell tudnia venni a
RESTful API mögötti szolgáltatásokat, és ez linkek segítségével valósulhat meg.</p>
<p>Pl. az előző <a href="/2023/08/31/workflow-es-rest.html">Workflow REST API-n posztomban</a> szereplő Issue Tracker alkalmazás
a következőképp adja vissza a hibajegyek listáját:</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"_embedded"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"jtl:issueResourceList"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
</span><span class="nl">"title"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Write a post about REST"</span><span class="p">,</span><span class="w">
</span><span class="nl">"state"</span><span class="p">:</span><span class="w"> </span><span class="s2">"NEW"</span><span class="p">,</span><span class="w">
</span><span class="nl">"_links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"href"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://localhost:8080/api/issues/1"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"actions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"href"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://localhost:8080/api/issues/1/actions"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">]</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"_links"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"self"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"href"</span><span class="p">:</span><span class="w"> </span><span class="s2">"http://localhost:8080/api/issues"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Látható a hibajegyek listáját reprezentáló URL-jét tartalmazó <code class="language-plaintext highlighter-rouge">self</code> link, valamint hibajegyenként
a hibajegyet reprezentáló URL-jének linkje szintén <code class="language-plaintext highlighter-rouge">self</code> névvel, valamint a hibajegyhez tartozó
lépéseket reprenzentáló URL <code class="language-plaintext highlighter-rouge">actions</code> névvel.</p>
<p>Ez a Hypermedia as the engine of application state (HATEOAS), melyet szintén Roy T. Fielding
vezetett be a disszertációjában. A HATEOAS szerint a szerver a kliens számára
linkekkel jelzi, hogy mit tehet.</p>
<p>Az elv mögötte az, hogy a REST API-t is úgy lehessen használni, mint a webet. Ahol vannak oldalak és
linkek és semmilyen előzetes információra nincs szükségem a használatához.</p>
<p>Hogy hogyan viszonyul ez az OpenAPI-hoz (Swaggerhez)? Elvileg a cél ugyanaz, és míg a HATEOAS
a REST gonolatiságához illeszkedik, az OpenAPI inkább az RPC-hez.</p>
Workflow REST API-n2023-08-31T08:00:00+00:00http://www.jtechlog.hu/2023/08/31/workflow-es-rest<p>Bár kétségtelenül a REST a legelterjedtebb kommunikációs mód, akár ugyanolyan
platformon fejlesztett alkalmazások között is, REST API tervezéskor
nekem sok kérdés merül fel, melyre nem kapok megnyugtató választ,
és sok olyan megoldással találkozom, amelyek nem felelnek meg a REST elveknek,
vagy egyszerűen csak nem tetszenek.</p>
<p>Sokáig próbáltam megfogalmazni, hogy mi az alapvető problémám, és talán most
sikerült közelebb kerülni. Vegyünk két microservice-t, melyek mindegyike Javaban készült,
Spring Boot használatával. Mindkét oldalon a programozási nyelv alapeleme az osztályok,
ahol érvényesül az egységbezárás, azaz az attribútumok mellett ott vannak
a metódusok, a megfelelő paraméterekkel és visszatérési értékekkel. Ez
a legtöbb fejlesztőnek triviális.</p>
<p>A REST a kettő között viszont egy teljesen
más absztrakció. Bár a REST nem mondja ki, hogy csak HTTP-vel együtt használható,
más protokollal működni még nem láttam.
A REST alapfogalma az erőforrás, és az azon végzett műveletek, melyeket a HTTP metódusok valósítanak meg, mint a <code class="language-plaintext highlighter-rouge">GET</code>, <code class="language-plaintext highlighter-rouge">POST</code>, <code class="language-plaintext highlighter-rouge">PUT</code> és <code class="language-plaintext highlighter-rouge">DELETE</code>.
Ez nehezen feleltethető meg az objektumorientált világnak.
Egy objektum létrehozására tipikusan konstruktort használunk, ebből nem feltétlen egy van.
Ezen kívül egy objektumnak lehet több metódusa, amik nem feltétlenül feleltethetőek meg a HTTP metódusoknak,
hiszen nem csak ezeket az alapműveleteket használjuk, valamint lehet belőle sokkal több is, mint négy.
Míg a Java nyelv szabvány, addig a REST csak egy ajánlás, és az sincs megfelelően
definiálva, hogy hogyan kéne implementálni, az meg aztán pláne nincs, hogy a kettőt
hogyan feleltessük meg egymásnak. És ennek az az eredménye, hogy minden projekten
teljesen más megoldásokat látok, a legtöbb helyen kompromisszumokkal.</p>
<p><img src="/artifacts/posts/2023-08-31-workflow-es-rest/absztakciok.png" alt="Absztrakciók" /></p>
<p>Az RPC alapú kommunikáció esetén igazából nincs ilyen probléma, mert nem szükséges
átfordítás, nincs szükség az absztrakció váltására. Hiszen ott is eljárások vannak,
paraméterekkel és visszatérési értékekkel. A Spring Frameworkben volt is ilyen
lehetőség, hogy egy távoli eljáráshívás történt, azonban a protokollt
kódolás nélkül cserélni lehetett alatta, pl. választhattunk RMI-t,
vagy ki emlékszik még a Hessian és Burlap protokollokra.
Sajnos ez azóta eltűnt.
A SOAP esetén sem volt akkora probléma az átfordítás, hiszen ott is vannak
az operációk (eljárásnak felel meg), és a paraméter, valamint a visszatérési
érték is egy-egy (XML) dokumentum. Vannak modernebb RPC alapú kommunikációs
protokollok is, mint pl. JSON-RPC, vagy az egyre inkább elterjedő
multiplatform gRPC, bináris Protocol Buffers formátummal.</p>
<p>Amennyiben CRUD alkalmazásról van szó, a REST használata talán triviális. De ha
egy olyan alkalmazásról beszélünk, amiben komoly üzleti logika van (és hiszem,
hogy a legtöbb alkalmazásnak ilyennek kéne lennie, csak a fejlesztők “butítják le”
CRUD alkalmazássá, amely végső soron oda is vezethet, hogy borzasztó felhasználói
felületek kerülnek kifejlesztésre), akkor már több kérdés merül fel.</p>
<p>Vegyünk például egy hibajegykezelő alkalmazást (issue tracker), mely rendelkezzen egy minimális
üzleti logikával. Ha hibajegy kerül felvételre, az <em>új</em> (<em>new</em>) állapottal kerül létrehozásra.
Amennyiben valaki elkezd rajta dolgozni, átkerül <em>folyamatban</em> (<em>in_progress</em>) állapotba.
Amennyiben elkészült, átkerül <em>megoldott</em> (<em>resolved</em>) állapotba. Bár a legtöbb hibajegykezelő
alkalmazás lehetővé teszi, hogy egyedi munkafolyamatot lehessen benne létrehozni,
ettől most tekintsünk el, mert akkor megint más problémák merülnek fel.
Ezt egy egyszerű állapotdiagrammal lehet a legegyszerűbben szemléltetni.</p>
<p><img src="/artifacts/posts/2023-08-31-workflow-es-rest/allapotatmenet-diagram.png" alt="Absztrakciók" /></p>
<p>Talán egy hibajegy felvételét még el tudom képzelni REST API-n (bár már ott is vannak
kérdéseim), azonban a különböző munkafolyamat lépések implementálásakor már
bizonytalanabb vagyok. Ez a poszt ezt a problémakört járja körbe,
forráskódokkal alátámasztva.</p>
Hőmérséklet monitorozása2023-08-18T08:00:00+00:00http://www.jtechlog.hu/2023/08/18/homerseklet-monitorozas<p>Nagyon régóta érdekel az IoT (Internet of Things, azaz Internetre köthető kütyük) világa, ugyanis ezek azok az eszközök,
melyek összekötik a virtuális világót a való világgal. Már régóta <a href="2013/12/30/raspberry-pi-alapok.html">rendelkezem egy Raspberry PI számítógéppel</a>,
melyet azóta is lelkesen használok egy alacsony fogyasztású home serverként. Telepítve van rá a Prometheus és Grafana, mely
a DevOps világban egy kvázi standard monitorozó eszköz. Mindkettő ingyenesen használható, nyílt forráskódú eszköz.
A Prometheus különösen alkalmas idősorok hatékony tárolására, gyors lekérdezésére, aggregált műveletek végrehajtására. Az idősorok
olyan megfigyelések, melyeket egymást követő időpontokban (időszakokban) regisztrálták, és ez az időbeliség az adatok fontos tulajdonsága.
Ilyen például egy szerverrel kapcsolatban a bizonyos időpontokban lekérdezett CPU és memóriahasználat, vagy a háttértárakon lévő szabad
hely mérete. A Grafana használatával ezeket tudjuk vizualizálni, gyönyörű dashboardokat létrehozni és akár riasztásokat
beállítani.</p>
<p>De melyik is lehet az az IoT eszköz, melyet a legegyszerűbben, lehetőleg barkácsolás nélkül és olcsón lehetne bekötni ebbe a rendszerbe?
Már régóta szemezem a Xiaomi Mi Temperature and Humidity Monitor 2 hőmérséklet-, és páratartalom mérővel, amihez most 2000 Ft-ért
lehet hozzájutni az <a href="https://mstore.hu/xiaomi-mi-temprerature-humidity-monitor-2-1473">mStore akciója keretében</a>.</p>
<p><img src="/artifacts/posts/2023-08-18-homerseklet-monitorozas/xiaomi-temperature-and-humidity-monitor.jpg" alt="Xiaomi Mi Temperature and Humidity Monitor 2" /></p>
<p>Ez pontosan a LYWSD03MMC modell, mely egy precíz Sensirion szenzorral, 1,5”-os LCD kijelzővel rendelkezik, és Bluetooth 4.2 BLE
vezeték nélküli kapcsolaton keresztül kommunikál. Egy CR2032 elemmel működik, ezt külön szerezzük be, mert nem része
a csomagnak. Ezzel akár fél-egy évig képes üzemelni. Természetesen Bluetooth-on tud kapcsolódni mobiltelefonhoz, illetve
Bluetooth Gateway-hez, azonban én direktbe, egy Linuxos számítógéppel, jelen esetben egy Raspberry PI-vel szeretnék
hozzá kapcsolódni, és kinyerni belőle az adatokat. (Nincs szükség egyedi firmware telepítésére.)</p>
<p>Ezt utána csak be kell kötni a Prometheusba, mely időközönként lekérdezi és eltárolja az adatokat, majd egy Grafana dashboardot
létrehozni, mely megjeleníti azokat.</p>
<p><a href="/artifacts/posts/2023-08-18-homerseklet-monitorozas/dashboard.png" data-lightbox="post-images"><img src="/artifacts/posts/2023-08-18-homerseklet-monitorozas/dashboard_700px.png" alt="Grafana dashboard" /></a></p>
<p>Közben természetesen szerettem volna megismerni a kapcsolódó technológiákat is.</p>
JTechLog Technology Radar2023-08-12T08:00:00+00:00http://www.jtechlog.hu/2023/08/12/technology-radar<p>Emlékszem régebben mennyire nagy esemény volt mindig, mikor kijött a Thoughtworks
<a href="https://www.thoughtworks.com/radar">Technology Radar</a> legfrissebb kiadása.
A Thoughtworksről annyit kell tudni, hogy 1999-ben csatlakozott a céghez
Martin Fowler, és több munkatársával együtt jelentős és meghatározó könyveket írtak,
melyeket én is javaslok elolvasni. Ezek például:</p>
<ul>
<li>Martin Fowler - Refactoring</li>
<li>Martin Fowler - Patterns of Enterprise Application Architecture</li>
<li>Jez Humble, David Farley - Continuous Delivery</li>
<li>Sam Newman - Building Microservices</li>
</ul>
<p>A cég mindig nagyon haladó gondolkodású volt, és bizonyos időközönként
közreadta a Technology Radart, melyben grafikusan ábrázolták, hogy mi is
a véleményük az épp aktuális technológiákról, eszközökről, módszertanokról.</p>
Gondolatok a modell osztályokról, entitásokról, DTO-król2023-08-01T08:00:00+00:00http://www.jtechlog.hu/2023/08/01/modell-osztalyok<p>Nagyon szeretem azokat az írásokat, melyek különböző területekről származó fogalmakat
próbálnak valamilyen egységes rendszerbe foglalni, a fogalmaknak egységes elnevezést
adni. Ilyen volt a
<a href="https://reflectoring.io/book/">Tom Hombergs - Get Your Hands Dirty on Clean Architecture (2nd edition)</a>
könyv, mely a modell osztályokkal próbálta ezt tenni. Különösen tetszett, hogy nem egy megoldást
fogad el igaznak, hanem ismerteti a különböző megoldásokat, összehasonlítva azok előnyeit és hátrányait.</p>
<p>A mostanában fejlesztett alkalmazások vagy a klasszikus háromrétegű (3-layer) architektúrával készülnek,
vagy a modernebb Hexagonal vagy Clean Architecture-t használják.</p>
<p>Egy klasszikus Spring Boot alkalmazás esetén a három réteg a repository, service, controller.
Java EE esetén ez a web, üzleti és EIS (Enterprise Information System) rétegek. Én egységesen
úgy fogok rájuk hivatkozni, hogy prezentációs, üzleti logika és perzisztens réteg.</p>
<p>Clean Architecture esetén is megjelennek ezek, az alapvető különbség a függőségek irányában van,
hiszen amíg a klasszikus háromrétegű alkalmazás esetén az üzleti logika réteg függ a perzisztens
rétegtől, addig a Clean Architecture esetén a perzisztens réteg függ az üzleti logika rétegtől.</p>
<p>Minden rétegben szükség van azonban az adatokat tároló osztályokra, nevezzük ezeket modell osztályoknak.
Manapság ezek egyszerű POJO (Plain Old Java Object) osztályok, pár attribútummal, konstruktorokkal, getter/setter metódusokkal.</p>
<p>Kérdés, hogy ebbe a fogalomrendszerbe hogyan illeszkednek be az entitások, DTO-k, stb.?
Melyik rétegben helyezkednek el? Illetve kell-e, és hogyan kell ezek között a megfeleltetést elvégezni (mapping),
konvertálni?
Ez a poszt ebben próbál egyfajta rendet tenni.</p>
Spring Security és Spring Boot2023-03-28T08:00:00+00:00http://www.jtechlog.hu/2023/03/28/spring-security-spring-boot<p>Technológiák: Spring Security 6.1, Spring Boot 3.1, Thymeleaf, Spring Data JPA, H2</p>
<p>Utolsó frissítés: 2023. november 15.</p>
<p>(Azért írtam meg ezt a posztot, mert sokan kerestek a Spring Security-re,
továbbá 2022 novemberében kijött a Spring Security 6 és Spring Boot 3, valamint
teljesértékű Spring Security poszt Spring Boottal eddig hiányzott.
A <a href="/2010/01/10/spring-security.html">Spring Security használata Springgel Frameworkkel poszt</a>
továbbra is elérhető.)</p>
<p>A Spring Security egy olyan keretrendszer, mely támogatja az autentikációt,
autorizációt és védelmet biztosít bizonyos támadási formák ellen. A Spring Security
a de-facto szabványos eszköz a biztonság megvalósítására Springes alkalmazásokon belül.</p>
<p>A Spring Security támogatja a felhasználónév és jelszó párossal történő bejelentkezést,
de ezen kívül pl. webszolgáltatások védelmére támogatja a HTTP BASIC, HTTP Digest
és tanúsítvány alapú bejelentkezést, sőt az OAuth 2.0 használatát is.</p>
<p>A felhasználók és a hozzá kapcsolódó szerepkörök tárolhatóak memóriában, adatbázisban, LDAP szerveren, stb.
Ezekhez adottak beépített implementációk, de saját is készíthető. Támogatja a jelszó hashelését
különböző algoritmusokkal. A felhasználóval kapcsolatos információkat képes cache-elni is. Különböző eseményekre eseménykezelőket lehet
aggatni, pl. bejelentkezés, így könnyen megoldható pl. audit naplózás.</p>
<p>Az alkalmazáson belül szerepkörökhöz lehet kötni bizonyos url-eket, valamint metódus szinten is
meg lehet adni, hogy milyen szerepkörrel rendelkező felhasználó hívhatja meg.</p>
<p>A poszthoz egy példa projekt is tartozik, mely <a href="https://github.com/vicziani/jtechlog-boot-security">elérhető a GitHub-on</a>.
Egyszerű Spring Boot webes alkalmazás, Spring Data JPA perzisztens réteggel, Thymeleaf template engine-nel.</p>
Modularizált alkalmazás fejlesztése a Spring Modulith-tal2022-12-19T09:00:00+00:00http://www.jtechlog.hu/2022/12/19/spring-modulith<h2 id="bevezetés">Bevezetés</h2>
<p>A microservice alkalmazások népszerűsége továbbra is töretlen. Miért is választják sokan ezt
az architektúrát? Egyik ok természetesen a hype factor, sokan szeretnék kipróbálni, valamint
hogy bekerüljön az önéletrajzukba. További ok, hogy sokan megcsömörlöttek a monolitikus
alkalmazásoktól, hiszen sok kötöttséggel járnak mind fejlesztés, mind üzemeltetési oldalról.
Ebből talán a legfontosabb, hogy gyakori jellemzője a spagetti kód, ennek következményeképp ha valahol
belenyúlunk az alkalmazásba, lehet, hogy másik helyen romlik el, ezért ha telepíteni akarunk,
ha biztosra akarunk menni, a teljes alkalmazást újra kéne tesztelnünk. Erre megoldás lehet
a microservice architektúra, ahol az alkalmazásunkat lazán kapcsolódó szolgáltatásokra
bontjuk fel. Ezzel kapcsolatban azonban a leggyakrabban elhangzó kérdés, hogy hol
a határ, hol vágjunk, mi alapján bontsuk szét az alkalmazásunkat szolgáltatásokra.
Monolitikus alkalmazásnál további kötöttségek a technológiai kötöttségek,
valamint hogy a teljes alkalmazást egyben lehet csak telepíteni.
És érdekes módon, csak ritkán szoktam azzal az indokkal találkozni, hogy azért
választották a microservice architektúrát, mert gond volt a skálázhatósággal,
aminek pedig nagy szerepe volt a kialakulásában.</p>
<p>Gyakran elfelejtjük, hogy egy monolitikus alkalmazásnak sem kéne szükségszerűen
egyben lennie, hanem azt is felépíthetjük lazán kapcsolt komponensekből.
A hiányzó láncszem itt a modul. A modularizált monolitikus alkalmazást
szokás modulith-nak nevezni. Ennek létét két okból is fontosnak tartom.
Egyrészt úgy vélem, hogy ahol nem tudnak modularizált alkalmazást fejleszteni,
ott nem érdemes a microservice architektúrával foglalkozni, ugyanis ezek
a technológiák nem mutatják meg, hogy hogy kell vágni. És a rossz vágásnak
az eredménye ugyanúgy spagetti lesz, de már meg lesz nehezítve az
elosztottságból adódó technológiai és üzemeltetési bonyodalmakkal is.
Többek által is jónak tartott út a microservice-ek felé, hogy először modularizáljuk
az alkalmazásunkat, majd utána emeljük ki a moduljainkat külön service-ekbe.
A másik ok, amit érdemes észben tartani, hogy már egyre több helyről
hallani, hogy a microservice architektúra nem vált be, nem váltotta be
az ígéreteket, a szervezet még nem állt készen (pl. agilis módszertanok, DevOps, CI/CD hiánya - igen, ezek
a microservice-ek előfeltételei), nem volt szükség skálázhatóságra, még rosszabb lett performanciában, stb.</p>
<p>Technológiailag a modulok azonban elég kevésbé támogatottak. Kezdeti próbálkozás volt az OSGi,
azonban komplexitása miatt nem terjedt el, pedig olyan igéretei vannak, mint a futás közbeni plugin telepítés,
valamint egy library-nek különböző verziói a classpath-on. Szabványos megoldást a
Java Platform Module System próbált adni a Java 9-ben, de annak ellenére, hogy már mikor
megjelent, szintén nem sikerült még elterjednie. A leggyakrabban használt megoldás a
build rendszer által biztosított modularizáció, gondoljunk itt a Maven multi module projectre.
Illetve a Gradle is azt hangoztatja, hogy multi module projektek kezelésében jobb és
gyorsabb, mint a Maven. Azonban ez is plusz komplexitással jár, különösen a build folyamat, a CI/CD terén.</p>
<p>A kézenfekvő megoldás a Java csomagok használata lenne, azonban ez sajnos túl kevés eszközt ad a kezünkbe,
a láthatósági módosítók csak nagyon szegényes hozzáférés szabályozást nyújtanak.
Ennek kiegészítésére jelent meg az <a href="https://spring.io/projects/spring-modulith">Spring Modulith</a> projekt, mely több jó megoldást is ad.
Nem hiszek feltétlenül abban, hogy ez az eszköz el fog terjedni, de a benne lévő
ötleteket érdemes ismerni, és akár a saját projekjeinkben is bevezetni.</p>
Perzisztens réteg technológiák és a MyBatis2022-10-06T08:00:00+00:00http://www.jtechlog.hu/2022/10/06/mybatis<h2 id="bevezetés">Bevezetés</h2>
<p>Amikor adatbázist kell választani, főleg a relációs adatbázisok és az SQL kerülnek szóba.
Az ezzel való kapcsolattartásra az alkalmazás oldalon főleg a JPA szabványt, és
annak valamelyik implementációját, pl. a Hibernate-et használjuk.</p>
<p>Régóta sokan ódzkodnak ettől a technológiától, különböző okok miatt.
Hamar lehet vele eredményeket elérni, azonban nagyon nehéz megérteni a mélységeit.
Ennek hiányában azonban az alkalmazásunk rosszul teljesíthet, az N + 1 probléma miatt
nagyon sok SQL utasítást adhat ki, és mivel a JPA implementáció ezeket generálja,
nem tudjuk finoman szabályozni. A JPA ezen kívül nehezebben alkalmazható egy
már meglévő, esetleg nem körültekintően megtervezett adatbázisra, sokkal inkább támogatja azt,
ha a Java osztályokból indulunk ki.</p>
<p>Ezért érdemes megnézni, hogy milyen alternatív technológiák vannak, és ezek
milyen jellemzőkkel rendelkeznek.</p>
<p>A technológia kiválasztása valamilyen szinten hat az alkalmazásunk architektúrájára is.
Többrétegű alkalmazás esetén a perzisztens réteg tartja a kapcsolatot az adatbázissal.
Itt különböző architektúrális mintákat használhatunk, ebből egy pár darab:</p>
<ul>
<li>Repository pattern, a Domain Driven Design (DDD) könyvből</li>
<li>Table és Row Data Gateway a Patterns of Enterprise Application Architecture (Martin Fowler) könyvből</li>
<li>Data Mapper ugyanonnan</li>
<li>Data Access Object (DAO) a Java EE tervezési minták közül</li>
</ul>
<p>Bizonyos neveket ráadásul bizonyos technológiák is használnak, ilyen pl. a repository,
melyet a Spring Framework is használ a perzisztens rétegének elnevezésére, amit
a Spring Data JPA is átvett.</p>
<p>Az eredeti tervem az volt, hogy ezek jelentését részletesen kifejtem, és összehasonlítom
őket. De rossz hírem van. Arra jöttem rá, hogy ezeket a fogalmak nincsenek jól
definiálva, nem összehasonlíthatóak, és <a href="https://stackoverflow.com/questions/804751/what-is-the-difference-between-the-data-mapper-table-data-gateway-gateway-da">mindenki másra használja ezeket</a>. És ezt
a különböző technológiák tovább bonyolítják, ugyanis saját komponenseik
elnevezésére használják ezeket a fogalmakat, helytelenül.</p>
<p>(Egy szemléletes példa erre, hogy a DDD szerint a repository egy olyan objektum, mely
az üzleti logika és az és az üzleti objektumok adatbázisból olvasásáért vagy oda írásáért felelős ún.
mapping réteg között helyezkedik el, és az üzleti objektumokat a kollekciókhoz hasonlóan kezeli. Ezen túl
komplex lekérdezési lehetőséget is biztosít úgy, hogy a lekérdezési feltételeket dinamikusan lehet
összeállítani. A Spring Data JPA repository-ja ezzel pont ellentétes, előre definiálnunk kell
a metódusokat, melyek csak egy jól meghatározott feltétellel hívhatóak meg.
Saját véleményem szerint a repository-nak a JPA Criteria Query API-ja sokkal jobban megfelel.)</p>
<p>Ezért úgy döntöttem, nem én fogok ezekben a fogalmakban rendet szabni, hanem inkább
egy tulajdonság rendszert állítok össze, ami alapján a perzisztens technológiák
osztályozhatóak. Ez legyen a következő:</p>
<ul>
<li>Szabvány-e vagy egyedi implementáció</li>
<li>Ingyenes-e</li>
<li>SQL lekérdező nyelvet kell használni, vagy saját nyelve van, amiből maga generál le SQL utasításokat</li>
<li>Van-e benne mapping, azaz az adatbázisból jövő adatokat automatikusan meg tudja-e feleltetni az objektumokkal</li>
<li>Elég-e interfészeket definiálni, amihez maga generálja ki az implementációt.</li>
<li>Képes-e metódusnév alapján implementációt generálni</li>
</ul>
<p>A mapping tipikusan reflectionnel működik, és rendelkezik alapkonfigurációval
(pl. az attribútum neve megegyezik az oszlopnévvel), de ez személyre is szabható.</p>
<p>Azt is eldöntöttem, hogy nem a különböző tervezési minták neveit fogom használni, hanem
a különböző technológiák elnevezési konvencióit.</p>
<p>Ezek alapján a JPA:</p>
<ul>
<li>Szabványos, a Java EE szabvány része, implementációi pl. a Hibernate vagy az EclipseLink</li>
<li>Mindkét elterjedt implementációja ingyenes</li>
<li>Saját nyelve van, a JPQL, vagy a Criteria Query API is használható</li>
<li>(Object-Relational Mapping) ORM eszköz, azaz megfelelteti az objektumokat az adatbázisból jövő adatokkal</li>
<li>Nem elég interfészeket definiálni</li>
<li>Ezért metódusnév alapján sem tud implementációt generálni</li>
</ul>
Spring Boot 3 újdonságai2022-09-13T08:00:00+00:00http://www.jtechlog.hu/2022/09/13/spring-boot-3<p>Frissítés: 2023. október 3.</p>
<h2 id="bevezetés">Bevezetés</h2>
<p>Mivel a hétvégén megkaptam, hogy írjak már Javas cikkeket, így ebben a posztban
a Spring Boot 3 újdonságait veszem sorra. A Spring Boot 3-as sorozat már a Spring
Framework 6-os sorozatára építkezik, ennek újdonságait nem fogom külön tárgyalni.
A poszt megírásának a pillanatában a legfrissebb verzió a 3.1.4.</p>
<p>Az említendő változások a következő területeket érintik:</p>
<ul>
<li>Alapkövetelmény a Java 17</li>
<li>Jakarta EE 9 függőségek</li>
<li>Problem Details</li>
<li>Tracing</li>
<li>Natív futtatható fájl elkészítése</li>
</ul>
Fejlesztőként mivel akadályozom a tesztelők munkáját?2022-08-20T08:00:00+00:00http://www.jtechlog.hu/2022/08/20/fejlesztok-es-tesztelok<h2 id="bevezetés">Bevezetés</h2>
<p>Frissítve: 2022. november 04-én, kiegészítve a <em>Rossz gyakorlat: Egy projekten már teszteltünk, nem vált be</em>,
a <em>Rossz gyakorlat: nem megfelelő üzleti fogalmakat használok</em>, a <em>Rossz gyakorlat: nem megfelelő branch-en történik a tesztelés</em>, és a <em>Rossz gyakorlat: nem bontom részproblémákra a problémát</em> fejezetekkel</p>
<p>Frissítve: 2022. augusztus 21-én, kiegészítve a <em>Naplózás fontossága</em> résszel, valamint a cache-re vonatkozó ajánlásokkal</p>
<p>Ahhoz, hogy sikeres szoftvert tudjunk szállítani, hiszem, hogy nagyon fontos a fejlesztők és
a tesztelők közötti szoros együttműködés. És mikor tesztelőket említek, ugyanúgy gondolok
a manuális és automata tesztelőkre is. Az irányzat, mely a fejlesztők és az üzemeltetők
közötti kapcsolat fontosságát hangsúlyozza, a DevOps nevet kapta. Célja egy olyan kultúra
kialakítása, gyakorlatok és eszközök kiválasztása, ahol a fejlesztők és az üzemeltetők
közös munkával tudnak gyorsan, megbízhatóan alkalmazásokat és megoldásokat szállítani.
Ez a fogalom manapság igencsak felkapott, <em>de méltatlannak érzem, hogy a tesztelőkkel
való közös munka fontosságának kiemelése korántsem ennyire hangsúlyos</em>.</p>
<p>Történetileg kialakult, hogy a fejlesztés és az üzemeltetés a legtöbb cégnél elvált
egymástól, tisztán elválasztott szervezeti egységekben, sőt akár külön cégekben működtek,
melyek között a kommunikáció finoman szólva is döcögős volt. Sőt, úgy érződött, hogy a két csoportnak
eltérő a célja. Az üzemeltetők stabilitást, biztonságot, tervezhetőséget szerettek volna,
míg a fejlesztők mindig az örökös változásért, fejlődésért harcoltak. Észrevehetjük,
ugyanez megfigyelhető a tesztelőknél is, egyrészt a különválás, a nehézkes kommunikáció,
és a látszólag ellentétes cél. Van, hogy a fejlesztők által késznek minősített alkalmazást
a tesztelők “visszadobnak”. Kezdjük felismerni, hogy az üzemeltetés és a fejlesztés
szétválasztása káros, <em>de vajon így érezzük a tesztelők munkájával kapcsolatban is</em>?
Ráadásul az egyes agilis módszertanok, mint pl. a Scrum szerint a csapat felelős
a sprint végén a kész termék leszállításáért, és ebben olyan egyenrangú csapattagok vesznek részt,
akik persze rendelkeznek speciális ismeretekkel, pl. üzleti elemzés, fejlesztés, tesztelés vagy
üzemeltetés.</p>
<p>Voltam olyan helyen, ahol a fentebb bemutatott elszigeteltség jelen volt, és mindig dolgoztam ennek
csökkentésén. Voltan olyan projekten is, ahol ezen különböző ismeretekkel rendelkező
szakemberek egy csapatban dolgoztak. Régóta tartok fejlesztői tanfolyamokat, köztük
kezdő fejlesztői tanfolyamokat, amin egyre több tesztelővel találkozok, aki el akar mozdulni
az automata tesztelés irányába. Sőt részt vettem tesztelői bootcampek megszervezésében is, ahol nagyon sokat
tanultam a tesztelő kollégáimtól, és beleláthattam ennek a szakmának a szépségeibe is, és erősítették bennem a hitet,
hogy mennyire fontos az együttműködés. Sőt, automata teszt eszközökkel kapcsolatos képzéseket is tartok, amin szintén sok tesztelő vesz részt.</p>
<p>Ezen tapasztalataim alapján, és a tesztelők (akár szünetekben elmesélt) történeteit meghallgatva gyakran úgy látom,
hogy a fejlesztőknek a teszteléssel kapcsolatban rengeteg tévhit él a fejében, és rengeteg rossz gyakorlatot folytatnak. Ebben a posztban ezeket próbálom felsorolni, megcáfolni. Lesz szó általános elvekről, de pár helyen lemegyek technológiai szintre is. Egyes szám első személyben fogok írni, fejlesztő lévén, még akkor is,
ha magam nem így gondolkozom, így megpróbálok senkit sem megsérteni. Félreértés ne essék, nem ellentéteket szeretnék szítani, hanem megoldásokat kínálni.</p>
Gondolatok az objektumorientált programozásról2022-04-22T08:00:00+00:00http://www.jtechlog.hu/2022/04/22/osztaly-invarians<p>Egy fejlesztő számára a legtöbbször öröm egy új keretrendszer vagy lib kipróbálása, és használatba vétele,
azonban szerintem ugyanilyen fontos újra és újra visszanyúlni az objektumorientált alapokhoz, az osztályok és
metódusok tervezéshez. Ebben a posztban egy egyszerű példán keresztül próbálom bemutatni, hogy ennek is
milyen mélységei lehetnek, és mennyire nem egyértelmű a jó megoldás kiválasztása. Az itt megismert fogalmak
használata egyszerűsíti a fejlesztők közötti kommunikációt is.</p>
<p>A posztot az ihlette, hogy szó esett az invariánsról a Clean Code könyvben. És nem sokkal később
a Domain-Driven Design könyvben is megemlítették.</p>
Szoftverfejlesztés okosan Pythonnal2022-02-03T09:00:00+00:00http://www.jtechlog.hu/2022/02/03/Szoftverfejlesztes-okosan-Pythonnal<p>Bár egyetértek azzal, hogy a programozással kapcsolatos szakirodalom nyelve
az angol, mégis üdvözlöm a magyar nyelvű könyveket, és blogokat
(hiszen ezért írom a JTechLogot is). Ezek a tartalmak itthon egy olyan
réteget is meg tudnak szólítani, akik esetleg kedvet kapva, ezen
az úton elindulva elkezdik fogyasztani az angol szakirodalmat is.
Gondolok például az középiskolásokra, felsőoktatási intézmények
diákjaira, manapság annyira népszerű
bootcampeken tanulókra, rokon szakmákból érdeklődőkre (pl. üzleti
elemzők, manuális tesztelők, matematikusok, stb.)</p>
<p>Ezért is tartom rajta a szemem a magyar nyelven megjelenő
könyveken. Sok megkeresés érkezik hozzám azzal kapcsolatban is,
hogy mivel ajánlott kezdeni, és a programozással kapcsolatos
fórumokon, listákon, csoportokon is újra és újra előjön a kérdés.
Mindig érdekelt az is, hogy egy kezdőknek szóló könyv hogyan
próbál bevezetni rendkívül absztrakt fogalmakat, mennyire hoz új példákat,
mennyire mer elrugaszkodni az eddigi tanítási módszerektől.
Különösen a magyar szerzők könyveinek örülök.</p>
<p>Már 2020-ban láttam Guta Gábor <em>Szoftverfejlesztés okosan Pythonnal : agilis csapatok közös nyelve</em>
című könyvét, és múltkor, mikor ki szerettem volna venni a könyvtárból, hogy
belelapozzak, és nem találtam benn, döntöttem el, hogy írok neki, hátha van neki
egy-két elfekvőben lévő példány. Gáborral már régóta ismerjük egymást,
akkor még mindketten Javaval foglalkoztunk, azóta váltott át, és merült bele
nagyon mélyen a Python világába. Mostanában ebben a témában ad elő
különböző szakmai konferenciákon is, pl. kifejezetten ajánlom a
<em>Python és a turbó csiga</em> című előadását a Python teljesítményhangolásról,
mely a HWSW free! meetup-sorozaton <a href="https://www.youtube.com/watch?v=MCJZWrPVgcs">hangzott el</a> 2020. februárjában.</p>
<p><a href="/artifacts/posts/images/szoftverfejlesztes-okosan-pythonnal-agilis-csapatok-kozos-nyelve.jpg" data-lightbox="post-images"><img src="/artifacts/posts/images/szoftverfejlesztes-okosan-pythonnal-agilis-csapatok-kozos-nyelve-thumb.jpg" alt="Kép leírása" /></a></p>
DLNA, az otthoni médiahálózat alapja2022-01-05T09:00:00+00:00http://www.jtechlog.hu/2022/01/05/dlna-otthoni-mediahalozat<p>Amikor itthon elkezdtem egy médiahálózatot kialakítani, akkor azonnal belefutottam a DLNA-ba, és mindig
is érdekelt, hogy pontosan hogyan működik. Otthoni médiahálózatnak nevezem azt, mikor egy lokális hálózatra
több eszköz is csatlakozik, mely vagy tárol, vagy lejátszik médiatartalmat, pl. képet, zenét, filmet.
Elvárás ezekkel kapcsolatban, hogy a hálózaton együtt tudjanak működni.</p>
<p>A médiatartalmat valamilyen háttértáron (winchester) tároljuk. Ilyen lehet pl. az asztali számítógépbe, vagy
laptopba épített HDD vagy SSD. Ide tartoznak a NAS-ok (Network Attached Storage), melyekben szintén ilyen
eszközök dolgoznak. De költséghatékony megoldás lehet egy Raspberry PI-hoz (sőt, akár közvetlen routerhez)
USB-vel csatlakoztatott külső merevlemez is.</p>
<p>Lejátszó eszköz lehet pl. az okostévé, okostelefon, asztali multimédia lejátszók
(Google Chromecast, Apple TV, Android TV-t futtató eszközök, bár nem akartam leírni ezt a szót, de “TV-okosítók”, stb.),
de lehet akár bármelyik asztali számítógép vagy laptop. (Ebből is látszik, hogy egy eszköz egyben akár médiatartalmat
tároló és lejátszó is lehet.) Sőt a játékkonzolok is képesek tartalmat lejátszani.</p>
<p>Ha már ezek ugyanazon a hálózaton vannak elvárás lehet, hogy a médiatartalmat tárolók a médiatartalmat más eszközökkel is
meg tudják osztani, és a lejátszók pedig bármelyik eszközön tárolt tartalmat le tudják játszani. És lehetőleg nekünk ezzel
a legkevesebb dolgunk legyen.</p>
<p>Pontosan ennek a megoldására alakult meg a Digital Living Network Alliance (DLNA) szövetség, akik kidolgozták a
pontosan ezt a nevet viselő szabványt is. Ez a gyakran emlegetett Universal Plug and Play (UPnP) szabványra épül,
ami pedig olyan hálózati protokollok összessége, melyek lehetővé teszik, hogy a hálózatra kötött
eszközök mindenféle beállítás nélkül megtalálják egymást, és együtt tudjanak működni. Ez az ún.
zero-configuration networking.</p>
<p>Ebben a posztban protokoll szinten bemutatom a DLNA-t, Python kódokkal érthetőbbé téve.</p>
Szoftverfejlesztés és Önfejlesztés podcast2021-10-22T08:00:00+00:00http://www.jtechlog.hu/2021/10/22/szoftverfejlesztes-es-onfejlesztes<p>A <a href="https://careercompass.hu/podcast/">Szoftverfejlesztés és Önfejlesztés podcastban</a>
Marhefka István meghívott egy kötetlen beszélgetésre.
Szó esett a folyamatos tanulásról, oktatásról, technológiákról, microservice-ekről,
szakmai életutamról.</p>
<p>A podcast első évadát is érdemes meghallgatni, ahol István a beszélgetőtársával hétről hétre azt
boncolgatják, hogyan kapcsolódik a technológia és az ember.</p>
<p>A második évadban sikeres szoftverfejlesztőket kért meg, hogy meséljenek szakmai útjukról.</p>
MDC naplózáskor és distributed tracing2021-10-04T08:00:00+00:00http://www.jtechlog.hu/2021/10/04/mdc-trace<p>A naplózó keretrendszerekben (legalábbis a Log4J-ben és a Logbackben) elég régóta ott
a Mapped Diagnostic Context, ami egy nagyon hasznos eszköz, mégis aránylag ritkán
látom használni.</p>
<p>Egy terhelés alatt lévő webes alkalmazásnál a naplóbejegyzéseket alapvetően elég nehéz szétválogatni pl.
kérésenként, sessionönként/felhasználónként. Az MDC segítségével minden napló bejegyzésbe
elhelyezhetük olyan adatot (pl. session azonosítót, felhasználónevet), mely ezek azonosítását teszi lehetővé. Ráadásul tehetjük
ezt anélkül, hogy a naplózás helyén a hívást, és benne az üzenetet módosítanunk kéne.</p>
<p>A naplóüzenetek címkézése, azonosítása különösen fontos lehet elosztott, microservice környezetben,
ahol különböző gépekről beérkező naplóüzeneteket kell összekötnünk.</p>
Reaktív programozás2021-08-03T15:00:00+00:00http://www.jtechlog.hu/2021/08/03/reaktiv-programozas<p>A reaktív programozás mostanában elég pezsgő irányzat, melynek fejlődését érdemes
nyomon követni. A reaktív programozás mibenlétéről megoszlanak a vélemények. Amit
azonban először érdemes megemlíteni, a Reaktív Kiáltvány (<a href="https://www.reactivemanifesto.org/">The Reactive Manifesto</a>).</p>
<p>A kiáltvány szerint a modern alkalmazásokkal kapcsolatban már más
nem funkcionális követelmények merülnek fel, pl. válaszidő, rendelkezésre
állás, adatmennyiség, skálázhatóság és hibatűrés tekintetében, valamint
más környezetekben futnak, a felhő és konténerizáció nagyon elterjedt.</p>
<p>Ezen alkalmazásoknak négy jellemzőjét definiálja a kiáltvány, melyek a következők:</p>
<ul>
<li>Reszponzív (Responsive): az alkalmazásnak minden esetben gyors választ kell adnia</li>
<li>Ellenálló (Resilient): az alkalmazás gyorsan válaszoljon hiba esetén is</li>
<li>Rugalmas (Elastic): az alkalmazás gyorsan válaszoljon nagy terhelés esetén is</li>
<li>Üzenetvezérelt : rendszerek elemei aszinkron, nem blokkoló módon, üzenetekkel kommunikálnak</li>
</ul>
<p>Reaktív programozás használatakor az alkalmazást
úgy építjük fel, hogy az az adatok aszinkron folyamára reagáljon. Ezen
adatfolyamok lehetnek a felhasználói interakciók, más alkalmazásoktól vagy (pl. IoT) eszközöktől érkező
üzenetek.</p>
<p>Az első három feltétel elég általános, talán az üzenetvezéreltség némileg technológiaibb. Ennek
segítségével lehet megoldani a rendszer komponensei közötti laza kapcsolatot. Megvalósítható vele
a lokális transzparencia, azaz a komponensek helyzetüktől függetlenül szólíthatók meg. Egyszerűbbé
válik a hibakezelés, pl. a hálózati kiesés. Segít a terheléselosztásban, skálázhatóságban.
Valamint megóvhatja a komponenseket a túlzott terheléstől.</p>
<p>Ebben a posztban szó lesz a reaktív programozás kialakulásáról, tulajdonságairól, irányvonalairól, különböző
eszközökről, szabványosításáról, valamint hogyan használhatjuk Springen belül.</p>
<p>A példaprojekt elérhető <a href="https://github.com/vicziani/employees-webflux-r2dbc">GitHubon</a>.</p>
JWT kezelése Java/Jakarta EE környezetben JAX-RS-sel2021-06-02T06:00:00+00:00http://www.jtechlog.hu/2021/06/02/jwt-jax-rs<p>Egy korábbi posztban (<a href="/2019/03/18/jwt-es-spring-security.html">JWT és Spring Security</a>)
írtam arról, hogy mi az a JWT token, és hogyan lehet használni Spring Security-vel.
Ez a poszt azt írja le, hogy lehet JAX-RS-sel használni (ami a Java/Jakarta EE szabvány része is).</p>
<p>A példámban a Jetty servlet containert, Jersey JAX-RS implementációt fogom használni,
és a <a href="https://github.com/jwtk/jjwt">Java JWT</a> könyvtárat. A szabványos megoldásnak
köszönhetően bármelyik komponens cserélhető.</p>
<p>A folyamat nagyon egyszerű:</p>
<ul>
<li>A felhasználó bejelentkezik, és ezáltal kap egy HttpOnly Cookie-t, benne a tokennel, melyet minden kéréssel visszaküld
a szervernek</li>
<li>Egy JAX-RS <code class="language-plaintext highlighter-rouge">ContainerRequestFilter</code> példányon megy keresztül minden kérés. Ez ellenőrzi, kicsomagolja a tokent, és
létrehoz egy új <code class="language-plaintext highlighter-rouge">SecurityContext</code> példányt, mely tárolja a bejelentkezett felhasználó adatait, pl. a felhasználónevet és szerepkörét</li>
<li>A JAX-RS végpontban, azaz a <code class="language-plaintext highlighter-rouge">Resource</code>-ban már paraméter injectionnel elérhető a <code class="language-plaintext highlighter-rouge">SecurityContext</code>, de működik pl. a <code class="language-plaintext highlighter-rouge">@RolesAllowed</code>
annotáció is</li>
</ul>
Elosztott tranzakciókezelés Spring Boottal2021-01-04T19:00:00+00:00http://www.jtechlog.hu/2021/01/04/spring-boot-elosztott-tranzakciokezeles<p>A tranzakciókezelésről már többször írtam. Egy bevezető
elérhető a <a href="/2010/05/31/tranzakciokezeles.html">Tranzakciókezelés EJB 3 és Spring környezetben</a>
címen is, melyet most frissítettem.</p>
<p>A jelenlegi posztban viszont azt írom le, hogyan lehet Spring Boottal elosztott
tranzakciókezelést végezni.</p>
<p>Elosztott tranzakciókezelést akkor használunk, ha egy tranzakcióba
szeretnénk foglalni két külön adatbázisban történő műveletet,
vagy még gyakoribb példa, ha egy tranzakcióba szeretnénk foglalni
egy adatbázis beszúrást és egy JMS üzenet elküldését. Látható,
hogy nem csak adatbázisok képesek tranzakcióban részt venni, hanem
pl. JMS-en elérhető üzenetkezelő middleware-ek
(Message Oriented Middleware - MOM) is. Összefoglaló nevén ezek
un. erőforráskezelők.</p>
<p>Az elosztott tranzakciókezeléshez egy tranzakció koordinátort kell kinevezni, aki
irányítja a tranzakciót. Itt jön képbe a two-phase commit
protocol (2PC), ahol első körben az erőforráskezelők felkészülnek a
tranzakcióra, és második körben hagyják jóvá azt. Minden
erőforráskezelőnek vétójoga van. Az erőforráskezelők a tranzakció
koordinátorral az X/Open XA protokollon keresztül kommunikálnak.</p>
A Java EE jelene, jövője és tesztelése2020-12-28T20:00:00+00:00http://www.jtechlog.hu/2020/12/28/java-ee-jelen-jovo-teszt<p>A Java EE technológiai manapság igencsak megosztó. Bár már sokan temetik, ettől függetlenül
igenis van jelene. Egyrészt sok alkalmazás épül Java EE technológiára. Ezeket
folyamatosan üzemeltetni kell, karban kell tartani és tovább kell fejleszteni.</p>
<p>Több projektről is hallottam,
melynek célja az volt, hogy a Java EE technológiát lecseréljék,
azonban ennek költsége, időigénye rendkívül magas volt, anélkül, hogy
új funkciók bekerültek volna. Egy ilyen projekt nem a management kedvence.
Több esetben azt is láttam, hogy az új techológiában a fejlesztőcsapat nem volt
kellően jártas, és hasonló szörnyet hozott létre. Volt, ahol ugyanaz a
team dolgozott a régi alkalmazás karbantartásán, valamint az új fejlesztésén.
Elképzelhető, mennyire voltak lelkesek, milyen minőségű munkát végeztek,
mikor a régihez kellett nyúlni. Volt, ahol két külön csapat dolgozott,
és óhatatlanul is kialakultak feszültségek. Mindkét felállásban
megvan a veszélye, hogy lelőjjék az hibásan “refaktor” néven
emlegetett projektet. Pl. elfogy a keret, nem hozza meg
az elvárt eredményt, bejön egy fontosabb projekt, hisz a régi
úgyis működik.</p>
<p>A <em>Clean Architecture</em> könyv szerint is a keretrendszer csak implementációs
részlet. Az érték az üzleti tudásban és funkciókban van. A túlzott
függőség a keretrendszerekre, ezekbe fektetett túlzott energia rendkívül sok
veszéllyel jár.</p>
<p>A Java EE folyamatosan fejlődik, érdemes figyelemmel követni az újdonságokat.
Folyamatosan vannak igények Java EE oktatásokra is, hiszen a projekten dolgozókat meg kell ismertetni
a szabványok új verzióival, valamint új fejlesztők is csatlakoznak, akiket be
kell tanítani. És ezen projekteken gyakori a unit és integrációs tesztek hiánya.
És ez egy részben a fejlesztőknek, de más részben a technológiának is felróható.</p>
<p>Szóval nézzük meg, hogyan lehet modernizálni egy Java EE alkalmazást úgy,
hogy figyelembe vegyük a modern architektúrális elveket,
de ezzel párhuzamosan egyre kevésbé függjünk a keretrendszeren, és hogyan vezessünk be unit és integrációs
teszteket.</p>
Docker Layers Spring Boot alkalmazásnál2020-10-18T20:00:00+00:00http://www.jtechlog.hu/2020/10/18/docker-layers<p>Amennyiben dockerizáljuk a Spring Bootos alkalmazásunkat, oda kell
figyelni néhány dologra. Nem elegendő ugyanis, hogy a jar
fájlunkat bemásoljuk (über jar, szép német kifejezéssel, vagy
fat jar - tehát a jar mely a függőségeket is tartalmazza).</p>
<p>A Docker ugyanis a hatékony adattárolás miatt egy image-et
nem egy megbonthatatlan fájlként tárol, hanem ún. layerekben.
Ugyanis ha kiindulunk egy image-ből, és pl. új fájlokat másolunk,
ezzel létrehozva egy új image-et, nem tárolja el az új image-et
teljes egészében, csak a különbséget, azaz a felmásolt fájlokat.
Ez a különbség a layer. Ezzel jelentős helyet takarít meg, hiszen
a két image-ben közös fájlokat csak egyszer tárolja el. Így
persze egy image több layer fájlból épül fel.</p>
<p>Vegyünk egy egyszerű Spring Boot alkalmazást, és egy hozzá
tartozó <code class="language-plaintext highlighter-rouge">Dockerfile</code> fájlt.</p>
<div class="language-docker highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">FROM</span><span class="s"> adoptopenjdk:14-jre-hotspot</span>
<span class="k">WORKDIR</span><span class="s"> /opt/app</span>
<span class="k">COPY</span><span class="s"> target/*.jar demo.jar</span>
<span class="k">CMD</span><span class="s"> ["java", "-jar", "demo.jar"]</span>
</code></pre></div></div>
<p>Ebben a posztban azt fogom leírni, hogy ez miért nem jó!</p>
<p>Az egyszerűség kedvéért képzeljük el, hogy
ez egy olyan image, mely egy <code class="language-plaintext highlighter-rouge">ubuntu</code> image-ből
épül fel, arra épül rá az AdoptOpenJDK,
kialakítva az <code class="language-plaintext highlighter-rouge">adoptopenjdk</code> image-et, majd
arra a saját alkalmazásunk, egy JAR állománnyal, melynek
eredménye a <code class="language-plaintext highlighter-rouge">demo</code> image. Ez layer szinten elnagyoltan így néz ki.</p>
<p><img src="/artifacts/posts/2020-10-18-docker-layers/docker-layers.png" alt="Docker layers" /></p>
<p>Ebből az ábrából már elég szépen látható, hogy mennyi tárhelyet nyerünk,
ha az <code class="language-plaintext highlighter-rouge">ubuntu</code> és <code class="language-plaintext highlighter-rouge">adoptopenjdk</code> layer csak egyszer kerül letárolásra.
(Gondoljunk bele, ha napi több commit esetén napi több image-et hoz
létre a CI szerver.)</p>
<p>A probléma ott kezdődik, hogy viszont az alkalmazáshoz tartozó réteg, amiben esetleg
egy-két fájl változik, újra és újra letárolásra kerül, hiszen az mindig egy új külön réteget
hoz létre.</p>
<p>A Spring Boot azonban a
<a href="https://spring.io/blog/2020/01/27/creating-docker-images-with-spring-boot-2-3-0-m1">2.3.0.M2 verziótól kezdve beépített támogatást tartalmaz</a>, hogy
magát az alkalmazást is több rétegre bontsuk fel.</p>
RabbitMQ használata Spring Boottal2020-09-11T21:00:00+00:00http://www.jtechlog.hu/2020/09/11/rabbitmq<p>Amennyiben aszinkron üzenetküldést szeretnénk megvalósítani különböző
rendszerek vagy microservice-ek között, a RabbitMQ egy
jó választásnak tűnik. Nyílt forráskódú, széleskörben elterjedt, kellően
pehelysúlyú, könnyen telepíthető különböző környezetekben,
több protokollt és programozási nyelvet is támogat, és könnyen
illeszthető Spring Boothoz. Clusterezhető és monitorozható.
Ezt fogom bemutatni azzal együtt, hogy hogy
lehet unit és integrációst teszteket írni. Ez utóbbihoz a
<a href="https://www.testcontainers.org/">Testcontainers</a> projektet fogom használni,
melynek segítségével JUnit tesztesetekből fogok Docker konténert indítani.</p>
<p>A poszthoz a GitHubon egy példaprojekt is tartozik a <a href="https://github.com/vicziani/jtechlog-rabbitmq">jtechlog-rabbitmq</a>
néven.</p>
Időzónák használata2020-07-22T09:00:00+00:00http://www.jtechlog.hu/2020/07/22/idozonak<p>Az időzóna az a terület, ahol az óráknak azonos időt kéne mutatniuk. Funkcionális okok miatt
ezeket nem a földrajzi hosszúságok határozzák meg, hanem tipikusan az országhatárokhoz igazodnak.
Mindegyik időzónát a UTC világidőhöz (egyezményes világidő) viszonyítják. A UTC a GMT-t váltotta, de ez utóbbi már elavult,
ne használjuk. A magyarországi időzóna a téli időszámításkor a CET (ami egy órával van előrébb
a UTC-nél, jelölése ezért <code class="language-plaintext highlighter-rouge">UTC+1</code>), nyáron pedig CEST (, ami kettővel).</p>
<p>A dátumok formázásra van a ISO-8601 szabvány, ennek felel meg például a
<code class="language-plaintext highlighter-rouge">2011-12-03T10:15:30+01:00[Europe/Budapest]</code> formátum is, mely tartalmazza az
UTC-hez képest az eltolást, és az időzóna nevét.</p>
<p>Ebben a posztban megvizsgálom, hogy hogy lehet kezelni az időzónát operációs rendszer szinten,
adatbázisban, Java SE-ben, valamint egy Springes alkalmazásban, JPA/Hibernate perzisztens
réteggel, és Jackson JSON library-vel.</p>
<p>Talán nem is fontos a teljes poszt megértése, inkább azt érdemes megjegyezni, hogy hol történnek
konverziók, és ezeket hogy érdemes debuggolni.</p>
Óda az integrációs tesztekhez2020-03-22T09:00:00+00:00http://www.jtechlog.hu/2020/03/22/oda-az-integracios-tesztekhez<p>Megrendezésre került 2019. október 17-én a <a href="https://training360.com/">Training360</a>
<em>Nézz be a hype mögé</em> fejlesztői meetupja. Ezen az <em>Integrációs tesztek nehézségei (Javaban)</em>
címmel tartottam előadást, bár inkább az integrációs tesztek pozitívumait
taglaltam.</p>
<p>Figyelem! A következő poszt nyugalom megzavarására alkalmas elemeket tartalmaz.
Célom annak a hangsúlyozása, hogy olyan alapvető állításokat, tételeket is
néha meg kell kérdőjeleznünk, mint a tesztpiramis. Ezért a posztban
találkozhattok némi hangsúly áthelyezéssel, kéretik ezt a helyén kezelni.</p>
<p><img src="/artifacts/posts/2020-03-22-oda-az-integracios-tesztekhez/2019-meetup-photo_750.jpg" alt="Fotó a meetupról" /></p>
<p>A rendezvényre készült <a href="/artifacts/2019-10-meetup/meetup-2019-10.html">diák elérhetőek itt</a>.</p>
<p>A posztban végigveszem a tesztpiramist, és az ezzel kapcsolatos fogalmakat,
sőt fenntartásaimat is. Majd megvizsgálok egy alternatív megközelítést,
mely különösen alkalmazható microservice-ekre. Közben példákat is hozok egy egyszerű
Spring Boot alkalmazás tesztelésére. A példa projekt elérhető a <a href="https://github.com/vicziani/jtechlog-cities">GitHubon</a>.</p>
Clean Architecture2020-03-03T10:00:00+00:00http://www.jtechlog.hu/2020/03/03/clean-architecture<p>Robert C. Martin erőteljes hatást gyakorolt napjaink szoftverfejlesztésre.
Egyike volt az Agile Manifesto aláíróinak, és számos tervezési elv
kötődik a nevéhez. Ő alkotta meg a SOLID elvek rövidítést, mely
saját és mástól átvett elveket is tartalmaz (pl. a Liskov-féle helyettesítési
elvet Barbara Liskovtól). Ő a szerzője a közismert Clean Code
és a The Clean Coder könyveknek. (A Clean Code-ról egy
előző <a href="https://www.jtechlog.hu/2019/02/24/clean-code.html">posztban írtam</a>.) A 2017-ben megjelent
Clean Architecture könyvről szól ez a poszt, és a poszt végén
a saját véleményem is megosztom veletek.</p>
<p><img src="/artifacts/posts/2020-03-03-clean-architecture/clean-architecture-cover.jpg" alt="Clean Architecture könyv" /></p>
<p>A Clean Architecture a szerző által megfogalmazott architektúráról ír,
azonban részletesen bemutatja azokat az elveket is, melyek mentén eljutott a
javasolt architektúráig. Talán nem meglepő, hogy a SOLID elvekből indult ki,
és ezeket próbálja magasabb absztrakciós szinten is alkalmazni. Egy objektumorientált
alkalmazás legfinomabban szemcsézett darabkái az osztályok, több osztály
összetartozó egységét ő komponensnek (component) nevezi (klasszikus modul fogalom), és
a teljes alkalmazást szolgáltatásnak (service). Nála a komponens a
külön release-elhető, csomagolható és deploy-olható egység, Java esetén a JAR,
C# esetén pl. a DLL fájl. A könyv próbál programozási nyelv független maradni,
és főleg Java és C# példákat hoz.</p>
<p>Az architektúra hasonlít is a manapság elterjedt 3-rétegű architektúrához,
azonban jelentős különbségeket is tartalmaz. Azt gondolom, hogy az elveket
mindenképp érdemes megismerni, azt meg mindenki döntse el maga, hogy az
elvek alapján létrehozott architektúrát mennyire szeretné követni.</p>