Pozdravljeni vsi na tem blogu, tukaj je četrta objava v seriji Quarkus!
Tukaj je pomembno omeniti, da tako Quarkus kot JBoss EAP poudarjata uporabo orodij, ki čim bolj temeljijo na standardih. Nimate aplikacije, ki se izvaja na JBoss EAP? Ni problema, enostavno ga je mogoče preseliti z vašega trenutnega aplikacijskega strežnika na JBoss EAP z uporabo
Pri pisanju te objave smo uporabili
Vzemimo kodo
Najprej ustvarimo lokalni klon repozitorija
$ 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/
Poglejmo, kako deluje izvirni helloworld
Pravzaprav je bistvo te aplikacije jasno iz imena, vendar bomo njeno kodo posodobili strogo znanstveno. Zato si najprej poglejmo to aplikacijo v izvirni obliki.
Uvajanje helloworld
1. Odprite terminal in pojdite v koren mape JBoss EAP (lahko jo prenesete
2. Zaženite strežnik JBoss EAP s privzetim profilom:
$ EAP_HOME/bin/standalone.sh
Opomba: V sistemu Windows se za zagon uporablja skript EAP_HOMEbinstandalone.bat.
Po nekaj sekundah bi se moralo v dnevniku prikazati nekaj takega:
[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. Odprite v brskalniku
riž. 1. Domača stran JBoss EAP.
4. Sledite navodilom v priročniku
$ mvn clean install wildfly:deploy
Po uspešni izvedbi tega ukaza bomo v dnevniku videli nekaj takega:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.224 s
Tako je prva uvedba aplikacije helloworld na JBoss EAP trajala nekaj več kot 8 sekund.
Testiranje helloworld
Delujte strogo v skladu z navodili
riž. 2. Original Hello World iz JBoss EAP.
Izvajanje sprememb
Spremenite vhodni parameter createHelloMessage(ime niza) iz World v Marco:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Ponovno zaženite naslednji ukaz:
$ mvn clean install wildfly:deploy
Nato osvežimo stran v brskalniku in vidimo, da se je besedilo spremenilo:
riž. 3. Pozdravljen Marco v JBoss EAP.
Povrnite uvedbo helloworld in zaustavite JBoss EAP
To ni obvezno, vendar če želite preklicati uvajanje, lahko to storite z naslednjim ukazom:
$ mvn clean install wildfly:undeploy
Če želite zaustaviti svoj primerek JBoss EAP, preprosto pritisnite Ctrl+C v terminalskem oknu.
Nadgradnja helloworld
Zdaj pa posodobimo originalno aplikacijo helloworld.
Ustvari novo vejo
Po končanem projektu hitrega zagona ustvarimo novo delujočo vejo:
$ git checkout -b quarkus 7.2.0.GA
Spreminjanje datoteke pom.xml
Aplikacijo bomo začeli spreminjati iz datoteke pom.xml. Če želite dovoliti Quarkusu, da vanj vstavi bloke XML, zaženite naslednji ukaz v mapi helloworld:
$ mvn io.quarkus:quarkus-maven-plugin:0.23.2:create
Pri pisanju tega članka je bila uporabljena različica 0.23.2. Quarkus pogosto izdaja nove različice, katera različica je najnovejša, lahko izveste na spletni strani
Zgornji ukaz bo v pom.xml vstavil naslednje elemente:
- Lastnost , ki določa različico Quarkusa za uporabo.
- blok za uvoz Quarkus BOM (seznam materialov), da ne bi dodali različice za vsako Quarkus odvisnost.
- Vtičnik quarkus-maven-plugin je odgovoren za pakiranje aplikacije in zagotavljanje razvojnega načina.
- Izvorni profil za ustvarjanje izvršljivih datotek aplikacije.
Poleg tega ročno izvedemo naslednje spremembe v pom.xml:
- Iz bloka vzamemo oznako in jo postavimo nad oznako . Ker bomo v naslednjem koraku izbrisali blok , moramo shraniti .
- Blok odstranimo, ker pri delu s Quarkusom ta aplikacija ne potrebuje več nadrejenega poma iz JBossa.
- Dodajte oznako in jo postavite pod oznako . Določite lahko želeno številko različice.
- Oznako odstranimo, ker ta aplikacija ni več WAR, ampak navaden JAR.
- Spreminjamo naslednje odvisnosti:
- Odvisnost javax.enterprise:cdi-api spremenimo v io.quarkus:quarkus-arc, pri čemer odstranimo provided, saj (v skladu z dokumenti) ta razširitev Quarkus zagotavlja vstavljanje odvisnosti CDI.
- Spremenimo odvisnost org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec v io.quarkus:quarkus-undertow, pri čemer odstranimo provided, saj je (v skladu z dokumenti) ta razširitev Quarkus zagotavlja podporo za servlet 'ov.
- Odstranimo odvisnost org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec, ker prihaja z odvisnostmi, ki smo jih pravkar spremenili.
Različica datoteke pom.xml z vsemi spremembami se nahaja na
Upoštevajte, da zgornji ukaz mvn io.quarkus:quarkus-maven-plugin:0.23.2:create ne samo spremeni datoteko pom.xml, ampak projektu doda tudi številne komponente, in sicer naslednje datoteke in mape:
- Datoteki mvnw in mvnw.cmd ter mapa .mvn: Maven Wrapper vam omogoča zagon projektov Maven dane različice Maven brez namestitve te različice.
- Mapa Docker (v imeniku src/main/): vsebuje primere datotek Docker za izvorni način in način jvm (skupaj z datoteko .dockerignore).
- Mapa Viri (v imeniku src/main/): vsebuje prazno datoteko application.properties in vzorčno začetno stran Quarkus index.html (za več podrobnosti glejte Zagon posodobljenega helloworld).
Zaženite helloworld
Za testiranje aplikacije uporabljamo quarkus:dev, ki zažene Quarkus v razvojnem načinu (za več podrobnosti glejte ta razdelek v priročniku
Opomba: Ta korak bo pričakovano povzročil napako, ker še nismo naredili vseh potrebnih sprememb.
Zdaj pa zaženimo ukaz, da vidimo, kako deluje:
$ ./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
Torej, ne deluje ... Zakaj?
UnsatisfiedResolutionException kaže na razred HelloService, ki je član razreda HelloWorldServlet (član java: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). Težava je v tem, da HelloWorldServlet potrebuje vbrizgan primerek HelloService in ga ni mogoče najti (čeprav sta oba razreda v istem paketu).
Čas je za vrnitev
Poglejmo razred HelloService – v resnici nima takšne opombe. Zato ga je treba dodati, da lahko Quarkus išče in najde fižol. In ker je to objekt brez stanja, lahko preprosto dodamo opombo @ApplicationScoped, kot je ta:
@ApplicationScoped
public class HelloService {
Opomba: tukaj vas lahko razvojno okolje prosi, da dodate zahtevani paket (glejte spodnjo vrstico) in to boste morali storiti ročno, takole:
import javax.enterprise.context.ApplicationScoped;
Če ste v dvomih, kateri obseg naj se uporabi v primeru, ko za izvorni gradnik sploh ni določen, preberite dokumentacijo
Zdaj ponovno poskusimo zagnati aplikacijo z ukazom ./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]
Zdaj gre vse brez napak.
Lansiranje posodobljenega helloworld
Kot piše v dnevniku, ga odprite v brskalniku
riž. 4. Začetna stran Quarkus dev.
Opomba WebServlet za to aplikacijo vsebuje naslednjo definicijo konteksta:
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
Zato gremo v brskalnik na
riž. 5: Stran za razvijalce Quarkus za aplikacijo Hello World.
No, vse deluje.
Zdaj pa spremenimo kodo. Upoštevajte, da se ukaz ./mvnw compile quarkus:dev še vedno izvaja in ga ne nameravamo ustaviti. Zdaj pa poskusimo uporabiti iste - zelo trivialne - spremembe v sami kodi in poglejmo, kako Quarkus olajša življenje razvijalcem:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Shranite datoteko in nato osvežite spletno stran, da vidite Hello Marco, kot je prikazano na spodnjem posnetku zaslona:
riž. 6. Stran Hello Marco v Quarkus dev.
Zdaj pa preverimo izhod v terminalu:
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
Osvežitev strani je sprožila zaznavo sprememb v izvorni kodi, Quarkus pa je samodejno izvedel proceduro stop-start. In vse to je bilo dokončano v samo 0.371 sekunde (tukaj je tista "ultra hitra subatomska Java").
Vgradnja helloworld v paket JAR
Zdaj, ko koda deluje, kot bi morala, jo zapakirajmo z naslednjim ukazom:
$ ./mvnw clean package
Ta ukaz ustvari dve datoteki JAR v mapi /target: datoteko helloworld-.jar, ki je standardni artefakt, ki ga je skupina Maven sestavila skupaj z razredi in viri projekta. In datoteka helloworld-runner.jar, ki je izvršljiva datoteka JAR.
Upoštevajte, da to ni uber-jar, saj so vse odvisnosti preprosto prekopirane v mapo /target/lib (niso pakirane v datoteko JAR). Če želite torej zagnati ta JAR iz druge mape ali na drugem gostitelju, morate tam kopirati samo datoteko JAR in mapo /lib, glede na to, da element Class-Path v datoteki MANIFEST.MF v paketu JAR vsebuje ekspliciten seznam datotek JAR iz map lib
Če želite izvedeti, kako ustvariti aplikacije uber-jar, si oglejte vadnico
Zaženite helloworld, pakiran v JAR
Zdaj lahko zaženemo naš JAR s standardnim ukazom java:
$ 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]
Ko vse to storite, pojdite v brskalnik na
Prevajanje helloworld v izvorno izvršljivo datoteko
Torej naš helloworld deluje kot samostojna aplikacija Java z uporabo odvisnosti Quarkus. Lahko pa greste dlje in jo spremenite v izvorno izvršljivo datoteko.
Namestitev GraalVM
Najprej morate za to namestiti potrebna orodja:
1. Prenesite GraalVM 19.2.0.1 iz
2. Razširite preneseni arhiv:
$ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz
3. Pojdite v mapo untar.
4. Zaženite spodnji ukaz za prenos in dodajanje izvorne slike:
$ ./bin/gu install native-image
5. Registrirajte mapo, ustvarjeno v koraku 2, v spremenljivko okolja GRAALVM_HOME:
$ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1)
Za več informacij in navodila za namestitev v drugih operacijskih sistemih glejte priročnik
Vgradnja helloworld v izvorno izvršljivo datoteko
Branje priročnika
Če želite ustvariti izvorno izvršljivo datoteko, morate omogočiti izvorni profil Maven:
$ ./mvnw package -Pnative
Naša izdelava je trajala eno minuto in 10 sekund, končna datoteka helloworld—runner f pa je bila ustvarjena v mapi /target.
Zaženite izvirno izvršljivo datoteko helloworld
V prejšnjem koraku smo prejeli izvršljivo datoteko /target/helloworld—runner. Zdaj pa ga zaženimo:
$ ./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]
Ponovno ga odprite v brskalniku
Se nadaljuje!
Menimo, da bi bilo treba metodo posodobitve aplikacij Java z uporabo zmogljivosti Quarkus, obravnavano v tej objavi (čeprav z uporabo preprostega primera), aktivno uporabljati v resničnem življenju. Pri tem boste verjetno naleteli na številne težave, ki jih bomo delno obravnavali v naslednjem prispevku, kjer bomo govorili o tem, kako izmeriti porabo pomnilnika za oceno izboljšav zmogljivosti, ki je pomemben del celotnega procesa posodobitve aplikacije.
Vir: www.habr.com