Quarkus: rakenduste moderniseerimine, kasutades Helloworldi näitena JBoss EAP Quickstartist

Tere kõigile siin blogis, siin on Quarkuse sarja neljas postitus!

Quarkus: rakenduste moderniseerimine, kasutades Helloworldi näitena JBoss EAP Quickstartist

Eelmine postitus rääkis sellest, kuidas Quarkus ühendab MicroProfile'i ja Spring. Tuletagem seda meelde Kvarkus on paigutatud kui "ülikiire subatomaarne Java" ehk "Kubernetesile orienteeritud Java pinu, mis on kohandatud GraalVM-i ja OpenJDK HotSpoti jaoks ning koostatud parimatest raamatukogudest ja standarditest." Täna näitame näite varal, kuidas Quarkuse võimalusi kasutades olemasolevaid Java rakendusi moderniseerida helloworldi rakendused Red Hat JBoss Enterprise Application Platformi (JBoss EAP) kiirkäivituse hoidlast, mis kasutab Quarkuse toetatud CDI ja Servlet 3 tehnoloogiaid.

Siinkohal on oluline märkida, et nii Quarkus kui ka JBoss EAP rõhutavad võimalikult standardipõhiste tööriistade kasutamist. Kas teil pole JBoss EAP-s rakendust? Pole probleemi, selle saab hõlpsasti migreerida teie praegusest rakendusserverist JBoss EAP-i kasutades Red Hat rakenduse migratsiooni tööriistakomplekt. Pärast seda on ajakohastatud koodi lõplik ja tööversioon hoidlas saadaval github.com/mrizzi/jboss-eap-quickstarts/tree/quarkus, moodulis Tere, Maailm.

Selle postituse kirjutamisel kasutasime Quarkuse käsiraamatud, põhimõtteliselt Esimese rakenduse loomine ja hoone a Algne käivitatav.

Võtame koodi

Kõigepealt loome hoidlast kohaliku klooni JBoss EAP kiirstarti:

$ 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/

Vaatame, kuidas algne helloworld töötab

Tegelikult selgub selle rakenduse olemus nimest, kuid me ajakohastame selle koodi rangelt teaduslikult. Seetõttu vaatame esmalt seda rakendust selle algsel kujul.

Helloworldi juurutamine

1. Avage terminal ja minge JBoss EAP kausta juure (saate selle alla laadida siin), see tähendab kausta EAP_HOME.

2. Käivitage JBoss EAP server vaikeprofiiliga:

$ EAP_HOME/bin/standalone.sh

Märkus: Windowsis kasutatakse selle käivitamiseks skripti EAP_HOMEbinstandalone.bat.

Mõne sekundi pärast peaks logisse ilmuma midagi sellist:

[org.jboss.as] (Controller Boot Thread) WFLYSRV0025: JBoss EAP 7.2.0.GA (WildFly Core 6.0.11.Final-redhat-00001) started in 3315ms - Started 306 of 527 services (321 services are lazy, passive or on-demand)

3. Avage brauseris 127.0.0.1:8080 ja me näeme seda:

Quarkus: rakenduste moderniseerimine, kasutades Helloworldi näitena JBoss EAP Quickstartist

Riis. 1. JBoss EAP koduleht.

4. Järgige juhendis toodud juhiseid Looge ja juurutage kiirstart: laiendage helloworldi ja käivitage (projekti juurkaustast) järgmine käsk:

$ mvn clean install wildfly:deploy

Pärast selle käsu edukat täitmist näeme logis midagi sellist:

[INFO] ------------------------------------------------------------------------ 
[INFO] BUILD SUCCESS 
[INFO] ------------------------------------------------------------------------ 
[INFO] Total time: 8.224 s

Seega võttis rakenduse helloworld esimene juurutamine JBoss EAP-s veidi üle 8 sekundi.

Helloworldi testimine

Käitumine rangelt vastavalt juhistele Juurdepääs rakendusele, avage brauseris 127.0.0.1:8080/helloworld ja me näeme seda:

Quarkus: rakenduste moderniseerimine, kasutades Helloworldi näitena JBoss EAP Quickstartist

Riis. 2. Algne Hello World JBoss EAP-lt.

Muudatuste tegemine

Muutke sisendparameetri createHelloMessage(String name) väärtusest World väärtuseks Marco:

writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");

Käivitage järgmine käsk uuesti:

$ mvn clean install wildfly:deploy

Seejärel värskendame lehte brauseris ja näeme, et tekst on muutunud:

Quarkus: rakenduste moderniseerimine, kasutades Helloworldi näitena JBoss EAP Quickstartist

Riis. 3. Tere Marco JBoss EAP-s.

Taastage helloworldi juurutus ja sulgege JBoss EAP

See on valikuline, kuid kui soovite juurutamise tühistada, saate seda teha järgmise käsuga:

$ mvn clean install wildfly:undeploy

JBoss EAP eksemplari sulgemiseks vajutage lihtsalt terminaliaknas klahvikombinatsiooni Ctrl+C.

Helloworldi uuendamine

Nüüd moderniseerime algset helloworldi rakendust.

Looge uus haru

Loome uue tööharu pärast kiirstardi projekti lõppu:

$ git checkout -b quarkus 7.2.0.GA

Faili pom.xml muutmine

Alustame rakenduse muutmist failist pom.xml. Et Quarkus saaks sellesse XML-plokke sisestada, käivitage kaustas helloworld järgmine käsk:

$ mvn io.quarkus:quarkus-maven-plugin:0.23.2:create

Selle artikli kirjutamisel kasutati versiooni 0.23.2. Quarkus annab sageli välja uusi versioone, milline versioon on värskeim, saad teada kodulehelt github.com/quarkusio/quarkus/releases/latest.

Ülaltoodud käsk lisab faili pom.xml järgmised elemendid:

  • Kinnisvara , mis määrab kasutatava Quarkuse versiooni.
  • Blokeeri importida Quarkuse BOM-i (bill of material), et mitte lisada iga Quarkuse sõltuvuse jaoks versiooni.
  • quarkus-maven-plugin vastutab rakenduse pakendamise ja arendusrežiimi pakkumise eest.
  • Algprofiil rakenduse käivitatavate failide loomiseks.

Lisaks teeme failis pom.xml käsitsi järgmised muudatused:

  1. Sildi välja tõmbamine blokist ja asetage see sildi kohale . Sest järgmises etapis eemaldame ploki , siis peate salvestama .
  2. Ploki eemaldamine , sest Quarkusega töötades ei vaja see rakendus enam JBossi vanemat.
  3. Lisa silt ja asetage see sildi alla . Saate määrata soovitud versiooninumbri.
  4. Sildi eemaldamine , kuna see rakendus pole enam WAR, vaid tavaline JAR.
  5. Muudame järgmisi sõltuvusi:
    1. Muutke sõltuvus javax.enterprise:cdi-api väärtuseks io.quarkus:quarkus-arc, eemaldamine ette nähtud , kuna (dokumentide järgi) pakub see Quarkuse laiendus CDI sõltuvusi.
    2. Muutke sõltuvus org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec väärtuseks io.quarkus:quarkus-undertow, eemaldamine ette nähtud , sest (dokumentide järgi) pakub see Quarkuse laiendus servlette tuge.
    3. Eemaldame sõltuvuse org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec, kuna see tuleb koos äsja muudetud sõltuvustega.

Faili pom.xml versioon koos kõigi muudatustega asub aadressil github.com/mrizzi/jboss-eap-quickstarts/blob/quarkus/helloworld/pom.xml.

Pange tähele, et ülaltoodud käsk mvn io.quarkus:quarkus-maven-plugin:0.23.2:create ei muuda mitte ainult faili pom.xml, vaid lisab projekti ka mitmeid komponente, nimelt järgmised failid ja kaustad:

  • Failid mvnw ja mvnw.cmd ning kaust .mvn: Maven Wrapper võimaldab teil käivitada antud Maveni versiooni Maveni projekte ilma seda versiooni installimata.
  • Dockeri kaust (kataloogis src/main/): see sisaldab Dockeri failide näidisfaile alg- ja jvm-režiimide jaoks (koos failiga .dockerignore).
  • Ressursikaust (kataloogis src/main/): see sisaldab tühja faili application.properties ja Quarkuse index.html avalehe näidist (lisateabe saamiseks vaadake jaotist Moderniseeritud helloworldi käivitamine).

Käivitage helloworld
Rakenduse testimiseks kasutame quarkus:dev, mis käivitab Quarkuse arendusrežiimis (lisateavet leiate juhendi sellest jaotisest Arendusrežiim).

Märkus: See samm toob eeldatavasti kaasa vea, kuna me pole veel kõiki vajalikke muudatusi teinud.

Nüüd käivitame käsu, et näha, kuidas see töötab:

$ ./mvnw compile quarkus:dev
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< org.jboss.eap.quickstarts:helloworld >----------------
[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] Nothing to compile - all classes are up to date
[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] Beginning quarkus augmentation
INFO  [org.jbo.threads] JBoss Threads version 3.0.0.Final
ERROR [io.qua.dev.DevModeMain] Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
	[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.jboss.as.quickstarts.helloworld.HelloService and qualifiers [@Default]
	- java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService
	- declared on CLASS bean [types=[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], qualifiers=[@Default, @Any], target=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)
Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.jboss.as.quickstarts.helloworld.HelloService and qualifiers [@Default]
	- java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService
	- declared on CLASS bean [types=[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], qualifiers=[@Default, @Any], target=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 more

Niisiis, see ei tööta... Miks?

UnsatisfiedResolutionException osutab klassile HelloService, mis on klassi HelloWorldServlet liige (java liige: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). Probleem on selles, et HelloWorldServlet vajab HelloService'i sisestatud eksemplari ja seda ei leita (kuigi mõlemad klassid on samas paketis).

On aeg tagasi pöörduda dokumentatsioon ja lugege, kuidas see Quarkuses töötab Süstige, ning seetõttu Kontekstid ja sõltuvuse süstimine (CDI). Seetõttu avage kontekstide ja sõltuvuse süstimise juhend ja jaotises Oa avastus loeme: "Oaklassi, millel pole uba määratlevat annotatsiooni, ei otsita."

Vaatame HelloService’i klassi – sellel tõesti sellist märkust pole. Seetõttu tuleb see lisada, et Quarkus saaks uba otsida ja leida. Ja kuna see on olekuta objekt, saame hõlpsasti lisada @ApplicationScoped märkuse järgmiselt:

@ApplicationScoped
public class HelloService {

Märkus: siin võib arenduskeskkond paluda teil lisada vajalik pakett (vt allolevat rida) ja peate seda tegema käsitsi, näiteks järgmiselt:

import javax.enterprise.context.ApplicationScoped;

Kui kahtlete, millist ulatust tuleks kasutada juhul, kui see pole lähteoa jaoks üldse määratud, lugege dokumentatsiooni JSR 365: kontekstid ja sõltuvuse sisestamine Java 2.0 jaoks – vaikeulatus.

Nüüd proovime uuesti rakendust käivitada käsuga ./mvnw compile quarkus:dev:

$ ./mvnw compile quarkus:dev
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------< org.jboss.eap.quickstarts:helloworld >----------------
[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]

Nüüd läheb kõik vigadeta.

Moderniseeritud helloworldi käivitamine
Nagu logis kirjas, avage see brauseris 0.0.0.0:8080 (Quarkuse vaikimisi avaleht) ja näeme järgmist:

Quarkus: rakenduste moderniseerimine, kasutades Helloworldi näitena JBoss EAP Quickstartist

Riis. 4. Quarkus dev avaleht.

Selle rakenduse WebServleti annotatsioon sisaldab järgmist kontekstimääratlust:

@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {

Nii et läheme brauseri juurde 0.0.0.0:8080/HelloWorld ja näeme järgmist:

Quarkus: rakenduste moderniseerimine, kasutades Helloworldi näitena JBoss EAP Quickstartist

Riis. 5: Quarkuse arendaja leht rakenduse Hello World jaoks.

Noh, kõik töötab.

Nüüd teeme koodis muudatused. Pange tähele, et ./mvnw kompileerimiskäsk quarkus:dev töötab endiselt ja me ei kavatse seda peatada. Proovime nüüd rakendada samu – väga triviaalseid – muudatusi ka koodis endas ja vaatame, kuidas Quarkus arendaja elu lihtsamaks teeb:

writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");

Salvestage fail ja seejärel värskendage veebilehte, et näha Tere Marcot, nagu on näidatud alloleval ekraanipildil:

Quarkus: rakenduste moderniseerimine, kasutades Helloworldi näitena JBoss EAP Quickstartist

Riis. 6. Tere Marco leht Quarkuse dev.

Nüüd kontrollime terminali väljundit:

INFO  [io.qua.dev] (vert.x-worker-thread-3) Changed source files detected, recompiling [/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) Quarkus stopped in 0.003s
INFO  [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) Beginning quarkus augmentation
INFO  [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) Quarkus augmentation completed in 232ms
INFO  [io.quarkus] (vert.x-worker-thread-3) Quarkus 0.23.2 started in 0.257s. Listening on: http://0.0.0.0:8080
INFO  [io.quarkus] (vert.x-worker-thread-3) Profile dev activated. Live Coding activated.
INFO  [io.quarkus] (vert.x-worker-thread-3) Installed features: [cdi]
INFO  [io.qua.dev] (vert.x-worker-thread-3) Hot replace total time: 0.371s

Lehe värskendamine käivitas lähtekoodi muudatuste tuvastamise ja Quarkus sooritas automaatselt stop-start protseduuri. Ja kõik see valmis kõigest 0.371 sekundiga (siin see on, "ülikiire subatomaarne Java").

Helloworldi ehitamine JAR-paketiks
Nüüd, kui kood töötab nii, nagu peab, pakendame selle järgmise käsuga:

$ ./mvnw clean package

See käsk loob kaks JAR-faili kausta /target: faili helloworld-.jar, mis on Maveni meeskonna koostatud standardne artefakt koos projekti klasside ja ressurssidega. Ja faili helloworld-runner.jar, mis on käivitatav JAR.

Pange tähele, et see ei ole uber-jar, kuna kõik sõltuvused kopeeritakse lihtsalt kausta /target/lib (mitte JAR-faili pakitud). Seetõttu peate selle JAR-i käivitamiseks teisest kaustast või mõnest teisest masinast kopeerima nii JAR-faili enda kui ka sinna kausta /lib, arvestades, et JAR-paketi failis MANIFEST.MF on element Class-Path. selgesõnaline JAR-ide loend lib-kaustadest
Uber-jari rakenduste loomise kohta lisateabe saamiseks vaadake õpetust Uber-Jari loomine.

Käivitage JAR-i pakendatud helloworld

Nüüd saame oma JAR-i käivitada standardse java-käsu abil:

$ java -jar ./target/helloworld-<version>-runner.jar
INFO  [io.quarkus] (main) Quarkus 0.23.2 started in 0.673s. Listening on: http://0.0.0.0:8080
INFO  [io.quarkus] (main) Profile prod activated.
INFO  [io.quarkus] (main) Installed features: [cdi]

Kui see kõik on tehtud, minge oma brauserisse aadressil 0.0.0.0:8080 ja kontrollige, kas kõik töötab nii nagu peab.

Helloworldi kompileerimine natiivseks täitmisfailiks

Nii et meie helloworld töötab eraldiseisva Java-rakendusena, kasutades Quarkuse sõltuvusi. Kuid võite minna kaugemale ja muuta selle natiivseks käivitatavaks failiks.

GraalVM-i installimine
Esiteks peate selleks installima vajalikud tööriistad:

1. Laadige alla GraalVM 19.2.0.1 github.com/oracle/graal/releases/tag/vm-19.2.0.1.

2. Laiendage allalaaditud arhiivi:

$ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz

3. Minge kausta untar.

4. Algkujutise allalaadimiseks ja lisamiseks käivitage allolev käsk:

$ ./bin/gu install native-image

5. Registreerige sammus 2 loodud kaust keskkonnamuutujasse GRAALVM_HOME:

$ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1)

Teiste operatsioonisüsteemide kohta lisateabe ja installijuhiste saamiseks vaadake juhendit. Algkäivitusfaili loomine – eeltingimused.

Helloworldi loomine natiivseks täitmisfailiks
Käsiraamatu lugemine Natiivse käivitatava faili loomine – algkäivitusfaili loomine: "Nüüd loome oma rakenduse jaoks käivitatava faili, et vähendada selle käivitusaega ja ketta suurust. Käivitatavas failis on kõik rakenduse käitamiseks vajalik, sealhulgas JVM (või õigemini selle kärbitud versioon, mis sisaldab ainult seda, mis on rakenduse käitamiseks vajalik) ja meie rakendus ise.

Natiivse käivitatava faili loomiseks peate lubama loomuliku Maveni profiili:

$ ./mvnw package -Pnative

Meie ehitamine võttis aega ühe minuti ja 10 sekundit ning viimane helloworld-runner f fail loodi kaustas /target.

Käivitage algne käivitatav fail helloworld

Eelmises etapis saime käivitatava faili /target/helloworld—runner. Nüüd käivitame selle:

$ ./target/helloworld-<version>-runner
INFO  [io.quarkus] (main) Quarkus 0.23.2 started in 0.006s. Listening on: http://0.0.0.0:8080
INFO  [io.quarkus] (main) Profile prod activated.
INFO  [io.quarkus] (main) Installed features: [cdi]

Avage see uuesti brauseris 0.0.0.0:8080 ja kontrollige, kas kõik töötab nii nagu peab.

Jätkub!

Usume, et selles postituses käsitletud Quarkuse võimalusi kasutades Java rakenduste moderniseerimise meetodit (ehkki lihtsa näite abil) tuleks päriselus aktiivselt kasutada. Seda tehes puutute tõenäoliselt kokku mitmete probleemidega, mida käsitleme osaliselt järgmises postituses, kus räägime sellest, kuidas mõõta mälutarbimist, et hinnata jõudluse paranemist, mis on oluline osa kogu rakenduste moderniseerimisprotsessist.

Allikas: www.habr.com

Lisa kommentaar