Üdvözöljük mindenkit a blogban, és itt van a Quarkus sorozat negyedik bejegyzése!

az volt, hogyan kapcsolja össze a Quarkus a MicroProfile-t és a Springet. Emlékezzünk arra, hogy úgy pozicionálja magát, mint az „ultrasebességű szubatom Java”, a „Kubernetes-orientált Java stack, amely a GraalVM és az OpenJDK HotSpot köré épül, és a legjobb könyvtárakból és szabványokból áll össze”. Ma azt fogjuk megmutatni, hogyan lehet modernizálni a már meglévő Java alkalmazásokat a Quarkus lehetőségeit kihasználva, a , amely a Quarkus által támogatott technológiákat, mint például a CDI és a Servlet 3 használja.
Fontos megjegyezni, hogy a Quarkus és a JBoss EAP is arra törekszik, hogy a lehető legnagyobb mértékben szabványokon alapuló eszközöket használjon. Nincs alkalmazásod a JBoss EAP-n? Nem probléma, könnyen átvihető a jelenlegi alkalmazásszerverről JBoss EAP-re a segítségével. Ezt követően a modernizált kód végső és működő verziója elérhető lesz a repozitoriumában, a .
bejegyzés írása közben a , főként a és a .
készítése.
Kód beszerzése :
$ git clone https://github.com/jboss-developer/jboss-eap-quickstarts.git
Cloning into 'jboss-eap-quickstarts'...
remote: Enumerating objects: 148133, done.
remote: Total 148133 (delta 0), reused 0 (delta 0), pack-reused 148133
Receiving objects: 100% (148133/148133), 59.90 MiB | 7.62 MiB/s, done.
Resolving deltas: 100% (66476/66476), done.
$ cd jboss-eap-quickstarts/helloworld/
Nézzük meg, hogyan működik az alap helloworld.
Valójában az alkalmazás lényege a nevéből egyértelműen kiderül, de szigorúan tudományosan fogjuk modernizálni a kódját. Tehát először is nézzük meg ezt az alkalmazást az eredeti formájában.
Helloworld telepítése
1. Nyisd meg a terminált, és lépj a JBoss EAP mappájának gyökérébe (letöltheted ), azaz az EAP_HOME mappába.
2. Indítsd el a JBoss EAP szervert az alapértelmezett profilal:
$ EAP_HOME/bin/standalone.sh
Megjegyzés: Windows esetén az EAP_HOMEbinstandalone.bat szkriptet használd az indításhoz.
Néhány másodpercen belül a naplóban a következőnek kell megjelennie:
[org.jboss.as] (Controller Boot Thread) WFLYSRV0025: JBoss EAP 7.2.0.GA (WildFly Core 6.0.11.Final-redhat-00001) elindult 3315ms alatt - 306/527 szolgáltatás indult el (321 szolgáltatás késleltetett, passzív vagy igény szerint).
3. Nyisd meg a böngészőt a :8080 címen, és ezt látod:

1. ábra. JBoss EAP kezdőlapja.
4. Kövesd az útmutatót a : telepítsük a helloworld-ot, majd a projekt gyökérmappájából futtassuk a következő parancsot:
$ mvn clean install wildfly:deploy
A parancs sikeres végrehajtása után a naplóban körülbelül a következőket fogjuk látni:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.224 s
Így az első helloworld alkalmazás telepítése a JBoss EAP alatt kicsit több mint 8 másodpercet vett igénybe.
Teszteljük a helloworld-ot
Szigorúan a kézikönyv szerint eljárva , nyissuk meg a böngészőben :8080/helloworld, és ezt látjuk:

Ábra 2. Az alap Hello World a JBoss EAP-ból.
Változtatásokat végzünk
Megváltoztatjuk a bemeneti paramétert createHelloMessage(String name) a World helyett Marco-ra:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Ismét végrehajtjuk a következő parancsot:
$ mvn clean install wildfly:deploy
Ezután frissítjük az oldalt a böngészőben, és látjuk, hogy a szöveg megváltozott:

Ábra 3. Hello Marco a JBoss EAP-ban.
Visszavonjuk a helloworld telepítését és leállítjuk a JBoss EAP-t
Ez nem kötelező, de ha szeretné visszavonni a telepítést, azt a következő parancs végrehajtásával teheti meg:
$ mvn clean install wildfly:undeploy
A JBoss EAP példány leállításához egyszerűen nyomja meg a Ctrl+C billentyűt a terminál ablakban.
Modernizáljuk a helloworld-ot
Most a helloworld alkalmazás modernizálásával foglalkozunk.
Új ág létrehozása
Új munkához szükséges ágat hozunk létre a quickstart projekt futása után:
$ git checkout -b quarkus 7.2.0.GA
Megváltoztatjuk a pom.xml fájlt
Az alkalmazást a pom.xml fájl megváltoztatásával kezdjük. Ahhoz, hogy a Quarkus XML blokkokat tudjon beilleszteni, futtassuk a következő parancsot a helloworld mappában:
$ mvn io.quarkus:quarkus-maven-plugin:0.23.2:create
A cikk írása során a 0.23.2-es verziót használták. A Quarkus gyakran kiad új verziókat, a legfrissebb verziót az alábbi oldalon lehet megtekinteni: .
A fenti parancs a pom.xml-be az alábbi elemeket illeszti be:
- A <quarkus.version> tulajdonság, amely a használandó Quarkus verziót határozza meg.
- A <dependencyManagement> blokk a Quarkus BOM (anyagjegyzék) importálásához, hogy ne kelljen verziót adni minden Quarkus függőséghez.
- A quarkus-maven-plugin, amely felelős az alkalmazás csomagolásáért és biztosítja a fejlesztési módot.
- A natív profil az alkalmazás végrehajtható fájljainak létrehozásához.
Ezenkívül a pom.xml-ben manuálisan elvégezzük a következő módosításokat:
- Kivesszük a <groupId> címkét a <parent> blokkból és fölé helyezzük a <artifactId> címkét. Mivel a következő lépésben eltávolítjuk a <parent> blokkot, meg kell őriznünk a <groupId>-t.
- Eltávolítjuk a <parent> blokkot, mivel a Quarkus használata során ennek az alkalmazásnak már nincs szüksége a JBoss szülő pom fájljára.
- Hozzáadjuk a <version> taget, és elhelyezzük a <artifactId> tag alatt. A verziószámot bármilyen kívánt értékre megadhatjuk.
- Eltávolítjuk a <packaging> taget, mivel ez az alkalmazás már nem WAR, hanem egy szokványos JAR.
- A következő függőségeket módosítjuk:
- Megváltoztatjuk az javax.enterprise:cdi-api függőséget io.quarkus:quarkus-arc-ra, eltávolítva a <scope>provided</scope> elemet, mivel (a dokumentációk szerint) ez a Quarkus-kibővítés biztosítja a CDI függőségek injektálását.
- Megváltoztatjuk az org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec függőséget io.quarkus:quarkus-undertow-ra, eltávolítva a <scope>provided</scope> elemet, mivel (a dokumentációk szerint) ez a Quarkus-kibővítés támogatja a servlet-eket.
- Eltávolítjuk az org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec függőséget, mivel ez az újrafogalmazott függőségekkel együtt jár.
A pom.xml fájl verziója az összes módosítással itt található: .
Figyeljen arra, hogy a fenti mvn io.quarkus:quarkus-maven-plugin:0.23.2:create parancs nemcsak a pom.xml fájlt módosítja, hanem számos komponenst is hozzáad a projekthez, nevezetesen a következő fájlokat és mappákat:
- mvnw és mvnw.cmd fájlok és a .mvn mappa: a Maven Wrapper lehetővé teszi a megadott Maven verziójú projektek futtatását anélkül, hogy telepítenie kellene a verziót.
- docker mappa (a src/main/ könyvtárban): itt találhatók a Dockerfile példafájlok native és jvm üzemmódokhoz (a .dockerignore fájl mellett).
- resources mappa (a src/main/ könyvtárban): itt található egy üres application.properties fájl, valamint a Quarkus index.html induló oldalának mintája (további információ a Modernizált helloworld futtatása című részben található).
Indítjuk a helloworld-ot
Az alkalmazás teszteléséhez a quarkus:dev parancsot használjuk, amely elindítja a Quarkust fejlesztési módban (további részletekért lásd a következő szakaszt a ).
Megjegyzés: ez a lépés várhatóan hibához vezet, mivel még nem végeztük el az összes szükséges módosítást.
Most kiadunk egy parancsot, hogy megnézzük, hogyan működik:
$ ./mvnw compile quarkus:dev
[INFO] Projekteket kutatása...
[INFO]
[INFO] ----------------< org.jboss.eap.quickstarts:helloworld >----------------
[INFO] Gyorsstart építése: helloworld quarkus
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld ---
[INFO] 'UTF-8' kódolás használata a szűrt erőforrások másolásához.
[INFO] 2 erőforrás másolása
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld ---
[INFO] Nincs mit fordítani - az összes osztály naprakész
[INFO]
[INFO] --- quarkus-maven-plugin:0.23.2:dev (default-cli) @ helloworld ---
Hallgatózás transport dt_socket címen: 5005
INFO [io.qua.dep.QuarkusAugmentor] Quarkus augmentáció kezdete
INFO [org.jbo.threads] JBoss Threads verzió 3.0.0.Final
ERROR [io.qua.dev.DevModeMain] A quarkus indítása sikertelen: java.lang.RuntimeException: io.quarkus.builder.BuildException: Építési hiba: Az építés hibákat észlelt
[hiba]: Az io.quarkus.arc.deployment.ArcProcessor#validate lépés kivételt dobott: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Nem kielégítő függőség az org.jboss.as.quickstarts.helloworld.HelloService típushoz és a [@Default] kvalifikátorokhoz
- java tag: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService
- osztály bean deklarálva [típusok=[javax.servlet.ServletConfig, java.io.Serializable, org.jboss.as.quickstarts.helloworld.HelloWorldServlet, javax.servlet.GenericServlet, javax.servlet.Servlet, java.lang.Object, javax.servlet.http.HttpServlet], kvalifikátorok=[@Default, @Any], cél=org.jboss.as.quickstarts.helloworld.HelloWorldServlet]
at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:841)
at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:214)
at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:106)
at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:249)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at io.quarkus.deployment.ExtensionLoader$1.execute(ExtensionLoader.java:780)
at io.quarkus.builder.BuildContext.run(BuildContext.java:415)
at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1426)
at java.lang.Thread.run(Thread.java:748)
at org.jboss.threads.JBossThread.run(JBossThread.java:479)
Oka: javax.enterprise.inject.UnsatisfiedResolutionException: Nem kielégítő függőség az org.jboss.as.quickstarts.helloworld.HelloService típushoz és a [@Default] kvalifikátorokhoz
- java tag: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService
- osztály bean deklarálva [típusok=[javax.servlet.ServletConfig, java.io.Serializable, org.jboss.as.quickstarts.helloworld.HelloWorldServlet, javax.servlet.GenericServlet, javax.servlet.Servlet, java.lang.Object, javax.servlet.http.HttpServlet], kvalifikátorok=[@Default, @Any], cél=org.jboss.as.quickstarts.helloworld.HelloWorldServlet]
at io.quarkus.arc.processor.Beans.resolveInjectionPoint(Beans.java:428)
at io.quarkus.arc.processor.BeanInfo.init(BeanInfo.java:371)
at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:206)
... 14 több
Hát, nem működik... Miért van ez?
A UnsatisfiedResolutionException exception indicates the HelloService class, which is a member of the HelloWorldServlet class (java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). The issue is that HelloWorldServlet needs an injected instance of HelloService, but it cannot be found (even though both classes are in the same package).
It's time to go back to and read about how it works in Quarkus , and therefore, also (CDI). So, let's open the Contexts and Dependency Injection guide and in the section we read: "A bean class that does not have a defining bean annotation is not searched for."
Looking at the HelloService class, it indeed lacks such an annotation. Therefore, we need to add it so Quarkus can search for and find the bean. Since this is a stateless object, we can simply add the @ApplicationScoped annotation as follows:
@ApplicationScoped
public class HelloService {
Megjegyzés: Here, the development environment may prompt you to add the required package (see the line below), and this must be done manually, like this:
import javax.enterprise.context.ApplicationScoped;
If in doubt about which scope to use when none is specified for the original bean, study the documentation .
Now let's try to run the application again with the command ./mvnw compile quarkus:dev:
$ ./mvnw compile quarkus:dev
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------------------
[INFO] Building Quickstart: helloworld quarkus
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 2 resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /home/mrizzi/git/forked/jboss-eap-quickstarts/helloworld/target/classes
[INFO]
[INFO] --- quarkus-maven-plugin:0.23.2:dev (default-cli) @ helloworld ---
Listening for transport dt_socket at address: 5005
INFO [io.qua.dep.QuarkusAugmentor] (main) Beginning quarkus augmentation
INFO [io.qua.dep.QuarkusAugmentor] (main) Quarkus augmentation completed in 576ms
INFO [io.quarkus] (main) Quarkus 0.23.2 started in 1.083s. Listening on: http://0.0.0.0:8080
INFO [io.quarkus] (main) Profile dev activated. Live Coding activated.
INFO [io.quarkus] (main) Installed features: [cdi]
Now everything goes without errors.
We launch the upgraded helloworld
As written in the log, we open in the browser :8080 (the default Quarkus start page) and see the following:

Fig. 4. Start page of Quarkus dev.
In the WebServlet annotation of this application, the following context definition is set:
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
Ezért a böngészőben a következő címre lépünk: :8080/HelloWorld, és ezt látjuk:

5. ábra: A Quarkus fejlesztői oldal Hello World alkalmazás számára.
Na, most már működik.
Most módosítjuk a kódot. Vegyük észre, hogy a . /mvnw compile quarkus:dev parancs még mindig működik, és nem szándékozunk leállítani. Most próbáljunk meg ugyanolyan – teljesen triviális – módosításokat alkalmazni a kódra, és nézzük meg, hogyan könnyíti meg a Quarkus a fejlesztők életét:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Mentjük a fájlt, majd frissítjük a weboldalt, hogy lássuk a Hello Marco feliratot, ahogy az az alábbi képernyőképen látható:

6. ábra: A Hello Marco oldal a Quarkus fejlesztői módban.
Most ellenőrizzük a terminál kimenetét:
INFO [io.qua.dev] (vert.x-worker-thread-3) Változott forrásfájlok észlelve, újrafordítás [ /home/mrizzi/git/forked/jboss-eap-quickstarts/helloworld/src/main/java/org/jboss/as/quickstarts/helloworld/HelloWorldServlet.java]
INFO [io.quarkus] (vert.x-worker-thread-3) A Quarkus 0,003 s alatt leállt
INFO [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) A quarkus bővítés elindítása
INFO [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) A quarkus bővítés 232 ms alatt befejeződött
INFO [io.quarkus] (vert.x-worker-thread-3) A Quarkus 0.23.2 0,257 s alatt elindult. Figyel a következő címen: http://0.0.0.0:8080
INFO [io.quarkus] (vert.x-worker-thread-3) A dev profil aktiválva. Élő kódolás aktiválva.
INFO [io.quarkus] (vert.x-worker-thread-3) Telepített funkciók: [cdi]
INFO [io.qua.dev] (vert.x-worker-thread-3) A forró csere teljes ideje: 0,371 s
Az oldal frissítése észlelte a forráskód változásait, és a Quarkus automatikusan végrehajtotta a 'stop-start' eljárást. Mindez mindössze 0,371 másodperc alatt megtörtént (itt van az a klasszikus „szupergyors, szubatomikus Java”).
A helloworld csomagolása JAR csomagba
Most, hogy a kód helyesen működik, csomagoljuk a következő paranccsal:
$ ./mvnw clean package
Ez a parancs kettő JAR fájlt hoz létre a /target mappában: a helloworld-.jar fájl, amely a Maven parancs által összeszerelt standard artefakt, valamint a hello—runner.jar fájl, amely egy végrehajtható JAR-t képvisel.
Ne feledje, hogy ez nem egy uber-jar, mivel minden függőség egyszerűen átmásolva lett a /target/lib mappába (és nem csomagolták a JAR fájlba). Ezért, ha ezt a JAR-t egy másik mappából vagy másik hoszton kívánja futtatni, mind a JAR fájlt, mind a /lib mappát át kell másolni, figyelembe véve, hogy a MANIFEST.MF fájlban található Class-Path elem egyértelműen felsorolja a lib mappában található JAR fájlokat.
Ha Ön uber-jar alkalmazásokat szeretne létrehozni, kérjük, nézze meg a kézikönyvet .
A helloworld elindítása, csomagolva JAR formátumban
Most elindíthatjuk a JAR-t a következő standard java parancs segítségével:
$ java -jar ./target/helloworld--runner.jar
INFO [io.quarkus] (main) Quarkus 0.23.2 elindult 0.673s alatt. Figyel a következő címen: http://0.0.0.0:8080
INFO [io.quarkus] (main) A prod profil aktiválva.
INFO [io.quarkus] (main) Telepített funkciók: [cdi]
Miután mindez megtörtént, lépjen be a böngészőbe a következő címen: :8080 és ellenőrizze, hogy minden megfelelően működik.
A helloworld összegyűjtése natív végrehajtható fájllá
Tehát a helloworld alkalmazásunk standalone Java alkalmazásként működik, kihasználva a Quarkus függőségeit. De van lehetőség tovább lépni, és natív végrehajtható fájlra konvertálni.
GraalVM telepítése
Elsősorban a szükséges eszközöket kell telepíteni:
1. Töltse le a GraalVM 19.2.0.1 verziót a következő címen: .
2. Csomagolja ki a letöltött archívumot:
$ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz
3. Menjen az untar mappába.
4. Futassa az alábbi parancsot, hogy letöltse és hozzáadja a natív képet:
$ ./bin/gu install native-image
5. Állítsa be a 2. lépésben létrehozott mappa elérési útját a GRAALVM_HOME környezeti változóban:
$ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1)
További információk és telepítési utasítások más operációs rendszerekhez a következő útmutatóban találhatók: .
A helloworld natív végrehajtható fájlba való összegyűjtése
Olvassa el az útmutatót : „Most létrehozunk egy natív végrehajtható fájlt az alkalmazásunkhoz, amely csökkenti a betöltési időt és a lemezméretet. A végrehajtható fájl tartalmazni fog mindent, ami szükséges az alkalmazás futtatásához, beleértve a JVM keretrendszert (pontosabban annak csökkentett verzióját, amely csak az alkalmazás futtatásához szükséges elemeket tartalmazza) és magát az alkalmazást.”
A natív végrehajtható fájl létrehozásához aktiválni kell a Maven natív profilt:
$ ./mvnw package -Pnative
Az összesítés 1 perc 10 másodpercet vett igénybe, és a helloworld-runner végrehajtható fájl a /target mappában jött létre.
Futtatjuk a helloworld natív végrehajtható fájlt
Az előző lépésben a /target/helloworld-runner végrehajtható fájlt kaptuk. Most indítsuk el:
$ ./target/helloworld--runner
INFO [io.quarkus] (main) Quarkus 0.23.2 elindult 0.006s alatt. Figyel a következő címen: http://0.0.0.0:8080
INFO [io.quarkus] (main) A prod profil aktiválva.
INFO [io.quarkus] (main) Telepített funkciók: [cdi]
Ismét nyissa meg a böngészőt :8080 és ellenőrizze, hogy minden megfelelően működik.
Folytatás következik!
Úgy véljük, hogy a bejegyzésben bemutatott (még ha egy egyszerű példán keresztül is) Java-alkalmazások Quarkus képességeivel történő modernizálásának módszerét aktívan érdemes alkalmazni a való életben. E közben valószínűleg számos problémával is találkozni fog, amelyek megoldásait részben a következő bejegyzésben tárgyaljuk, ahol arról lesz szó, hogyan mérhetjük a memóriafogyasztást a teljesítményjavítás, a modernizálási folyamat fontos részének értékelésére.
Forrás: habr.com
