Kumusta sa lahat sa blog na ito, narito ang ikaapat na post sa serye ng Quarkus!

ay tungkol sa kung paano pinagsama ng Quarkus ang MicroProfile at Spring. Paalalahanan ka namin ay nakaposisyon bilang "ultra-fast subatomic Java", aka "Kubernetes-oriented Java stack, na iniayon para sa GraalVM at OpenJDK HotSpot at binuo mula sa pinakamahusay na mga library at pamantayan." Ngayon ay ipapakita namin kung paano i-modernize ang mga umiiral na Java application gamit ang mga kakayahan ng Quarkus, gamit ang halimbawa , na gumagamit ng CDI at Servlet 3 na teknolohiya na sinusuportahan ng Quarkus.
Mahalagang tandaan dito na parehong binibigyang-diin ng Quarkus at JBoss EAP ang paggamit ng mga tool na nakabatay sa mga pamantayan hangga't maaari. Walang application na tumatakbo sa JBoss EAP? Walang problema, madali itong mailipat mula sa iyong kasalukuyang server ng application sa JBoss EAP gamit . Pagkatapos nito, ang pangwakas at gumaganang bersyon ng modernized na code ay magiging available sa repositoryo , sa modyul .
Sa pagsulat ng post na ito ay ginamit namin , karamihan at Gusali a .
Kunin natin ang code
Una sa lahat, gumawa tayo ng lokal na clone ng repositoryo :
$ 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/
Tingnan natin kung paano gumagana ang orihinal na helloworld
Sa totoo lang, ang kakanyahan ng application na ito ay malinaw mula sa pangalan, ngunit gagawin naming makabago ang code nito nang mahigpit na siyentipiko. Samakatuwid, una, tingnan natin ang application na ito sa orihinal nitong anyo.
Nagde-deploy ng helloworld
1. Magbukas ng terminal at pumunta sa root ng JBoss EAP folder (maaari mo itong i-download ), iyon ay, sa EAP_HOME folder.
2. Ilunsad ang JBoss EAP server gamit ang default na profile:
$ EAP_HOME/bin/standalone.sh
Tandaan: sa Windows Ang EAP_HOMEbinstandalone.bat script ay ginagamit para sa paglulunsad.
Pagkatapos ng ilang segundo, dapat lumitaw ang isang bagay na tulad nito sa log:
[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. Buksan sa isang browser :8080 at nakikita natin ito:

kanin. 1. JBoss EAP Home Page.
4. Sundin ang mga tagubilin sa manwal : palawakin ang helloworld at i-execute (mula sa project root folder) ang sumusunod na command:
$ mvn clean install wildfly:deploy
Matapos matagumpay na maisakatuparan ang utos na ito, makikita natin ang isang bagay tulad ng sumusunod sa log:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.224 s
Kaya, ang unang deployment ng helloworld application sa JBoss EAP ay tumagal lamang ng mahigit 8 segundo.
Sinusubukan ang helloworld
Mahigpit na kumilos ayon sa mga tagubilin , buksan sa browser :8080/helloworld at nakita namin ito:

kanin. 2. Orihinal na Hello World mula sa JBoss EAP.
Gumagawa ng mga pagbabago
Baguhin ang input parameter createHelloMessage(String name) mula sa World patungong Marco:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Patakbuhin muli ang sumusunod na command:
$ mvn clean install wildfly:deploy
Pagkatapos ay i-refresh namin ang pahina sa browser at makita na nagbago ang teksto:

kanin. 3. Hello Marco sa JBoss EAP.
Ibalik ang helloworld deployment at isara ang JBoss EAP
Opsyonal ito, ngunit kung gusto mong kanselahin ang deployment, magagawa mo ito gamit ang sumusunod na command:
$ mvn clean install wildfly:undeploy
Para i-shut down ang iyong JBoss EAP instance, pindutin lang ang Ctrl+C sa terminal window.
Ina-upgrade ang helloworld
Ngayon, i-modernize natin ang orihinal na application ng helloworld.
Gumawa ng bagong sangay
Lumilikha kami ng bagong nagtatrabahong sangay pagkatapos makumpleto ang quickstart na proyekto:
$ git checkout -b quarkus 7.2.0.GA
Pagbabago ng pom.xml file
Sisimulan naming baguhin ang application mula sa pom.xml file. Upang payagan ang Quarkus na magpasok ng mga bloke ng XML dito, patakbuhin ang sumusunod na command sa folder ng helloworld:
$ mvn io.quarkus:quarkus-maven-plugin:0.23.2:create
Sa pagsulat ng artikulong ito, ginamit ang bersyon 0.23.2. Ang Quarkus ay madalas na naglalabas ng mga bagong bersyon, maaari mong malaman kung aling bersyon ang pinakabago sa website .
Ilalagay ng command sa itaas ang mga sumusunod na elemento sa pom.xml:
- Ari-arian , na tumutukoy sa bersyon ng Quarkus na gagamitin.
- I-block upang mag-import ng Quarkus BOM (bill of materials), upang hindi magdagdag ng bersyon para sa bawat dependency ng Quarkus.
- Ang quarkus-maven-plugin ay responsable para sa packaging ng application at pagbibigay ng development mode.
- Ang katutubong profile para sa paglikha ng mga executable ng application.
Bilang karagdagan, manu-mano naming ginagawa ang mga sumusunod na pagbabago sa pom.xml:
- Hinugot ang tag Galing sa kanto at ilagay ito sa itaas ng tag . Dahil sa susunod na hakbang ay aalisin natin ang block , pagkatapos ay kailangan mong i-save .
- Pag-alis ng block , dahil kapag tumatakbo kasama ang Quarkus, ang application na ito ay hindi na mangangailangan ng parent pom mula sa JBoss.
- Magdagdag ng tag at ilagay ito sa ilalim ng tag . Maaari mong tukuyin ang numero ng bersyon na gusto mo.
- Pag-alis ng tag , dahil ang application na ito ay hindi na isang WAR, ngunit isang regular na JAR.
- Binabago namin ang mga sumusunod na dependencies:
- Baguhin ang dependency na javax.enterprise:cdi-api sa io.quarkus:quarkus-arc, inaalis ibinigay , dahil (ayon sa mga doc) ang Quarkus extension na ito ay nagbibigay ng iniksyon ng mga dependency ng CDI.
- Baguhin ang dependency org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec sa io.quarkus:quarkus-undertow, inaalis ibinigay , dahil (ayon sa mga doc) ang Quarkus extension na ito ay nagbibigay ng suporta para sa mga servlet.
- Inalis namin ang dependency ng org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec dahil kasama ito sa mga dependency na binago namin.
Ang bersyon ng pom.xml file kasama ang lahat ng mga pagbabago ay matatagpuan sa .
Tandaan na ang mvn io.quarkus:quarkus-maven-plugin:0.23.2:create command sa itaas ay hindi lamang nagbabago sa pom.xml file, ngunit nagdaragdag din ng ilang bahagi sa proyekto, katulad ng mga sumusunod na file at folder:
- Ang mvnw at mvnw.cmd file at ang .mvn folder: Ang Maven Wrapper ay nagbibigay-daan sa iyo na magpatakbo ng mga proyekto ng Maven ng isang ibinigay na bersyon ng Maven nang hindi ini-install ang bersyon na iyon.
- Docker folder (sa src/main/ directory): Naglalaman ito ng mga halimbawang Dockerfiles para sa native at jvm modes (kasama ang .dockerignore file).
- Folder ng mga mapagkukunan (sa src/main/ directory): Naglalaman ito ng walang laman na application.properties file at sample na Quarkus index.html na panimulang pahina (tingnan ang Patakbuhin ang modernized na helloworld para sa higit pang mga detalye).
Ilunsad ang helloworld
Upang subukan ang application, ginagamit namin ang quarkus:dev, na naglulunsad ng Quarkus sa development mode (para sa higit pang mga detalye, tingnan ang seksyong ito sa manual ).
Tandaan: Ang hakbang na ito ay inaasahang magreresulta sa isang error, dahil hindi pa namin nagagawa ang lahat ng kinakailangang pagbabago.
Ngayon patakbuhin natin ang utos upang makita kung paano ito gumagana:
$ ./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
Kaya, hindi ito gumagana... Bakit?
Ang UnsatisfiedResolutionException ay tumuturo sa HelloService class, na isang miyembro ng HelloWorldServlet class (java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). Ang problema ay ang HelloWorldServlet ay nangangailangan ng isang injected na halimbawa ng HelloService, at hindi ito mahahanap (kahit na ang parehong mga klase ay nasa parehong pakete).
Oras na para bumalik sa at basahin kung paano ito gumagana sa Quarkus , at samakatuwid (CDI). Samakatuwid, buksan ang gabay sa Contexts and Dependency Injection at sa seksyon mababasa natin: "Ang isang klase ng bean na walang anotasyong tumutukoy sa bean ay hindi hinahanap."
Tingnan natin ang klase ng HelloService - wala talaga itong anotasyon. Samakatuwid, dapat itong idagdag upang mahanap at mahanap ni Quarkus ang sitaw. At dahil ito ay isang stateless object, madali nating maidagdag ang @ApplicationScoped annotation tulad nito:
@ApplicationScoped
public class HelloService {
Tandaan: dito maaaring hilingin sa iyo ng development environment na idagdag ang kinakailangang package (tingnan ang linya sa ibaba), at kakailanganin mong gawin ito nang manu-mano, tulad nito:
import javax.enterprise.context.ApplicationScoped;
Kung nagdududa ka tungkol sa kung aling saklaw ang dapat gamitin sa kaso kung kailan hindi ito tinukoy para sa source bean, basahin ang dokumentasyon .
Ngayon ay muli naming sinubukang ilunsad ang application gamit ang command ./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]
Ngayon ang lahat ay napupunta nang walang mga pagkakamali.
Inilunsad ang modernized na helloworld
Tulad ng nakasulat sa log, buksan ito sa browser :8080 (ang default na panimulang pahina ng Quarkus) at nakita namin ito:

kanin. 4. Panimulang pahina ng Quarkus dev.
Ang WebServlet annotation para sa application na ito ay naglalaman ng sumusunod na kahulugan ng konteksto:
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
Samakatuwid, pumunta kami sa browser sa :8080/HelloWorld at nakikita natin ang sumusunod:

kanin. 5: Ang pahina ng Quarkus dev para sa application na Hello World.
Well, gumagana ang lahat.
Ngayon ay gumawa tayo ng mga pagbabago sa code. Tandaan na ang ./mvnw compile quarkus:dev command ay tumatakbo pa rin at wala kaming intensyon na ihinto ito. Ngayon subukan nating ilapat ang pareho - napakawalang halaga - mga pagbabago sa mismong code at tingnan kung paano pinapadali ng Quarkus ang buhay para sa developer:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
I-save ang file at pagkatapos ay i-refresh ang web page upang makita ang Hello Marco, tulad ng ipinapakita sa screenshot sa ibaba:

kanin. 6. Hello Marco page sa Quarkus dev.
Ngayon suriin natin ang output sa terminal:
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
Ang pag-refresh ng page ay nag-trigger ng pagtuklas ng mga pagbabago sa source code, at ang Quarkus ay awtomatikong nagsagawa ng stop-start procedure. At lahat ng ito ay nakumpleto sa loob lamang ng 0.371 segundo (narito, ang "ultra-fast subatomic Java").
Pagbuo ng helloworld sa isang JAR package
Ngayon na gumagana ang code ayon sa nararapat, i-package natin ito gamit ang sumusunod na command:
$ ./mvnw clean package
Lumilikha ang command na ito ng dalawang JAR file sa /target na folder: ang helloworld-.jar file, na isang karaniwang artifact na binuo ng Maven team kasama ng mga klase at mapagkukunan ng proyekto. At ang helloworld-runner.jar file, na isang executable na JAR.
Pakitandaan na ito ay hindi isang uber-jar, dahil ang lahat ng mga dependency ay kinokopya lamang sa /target/lib folder (hindi naka-package sa isang JAR file). Samakatuwid, upang patakbuhin ang JAR na ito mula sa isa pang folder o sa isa pang host, kailangan mong kopyahin ang JAR file mismo at ang /lib folder doon, dahil ang Class-Path na elemento sa MANIFEST.MF file sa JAR package ay naglalaman ng isang tahasang listahan ng mga JAR mula sa mga folder ng lib
Upang matutunan kung paano lumikha ng mga uber-jar na application, mangyaring sumangguni sa tutorial .
Ilunsad ang helloworld na nakabalot sa JAR
Ngayon ay maaari na nating patakbuhin ang ating JAR gamit ang karaniwang utos ng 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]
Pagkatapos ng lahat ng ito, pumunta sa iyong browser sa :8080 at tingnan kung gumagana ang lahat ayon sa nararapat.
Kino-compile ang helloworld sa isang native na executable na file
Kaya ang aming helloworld ay tumatakbo bilang isang standalone na Java application gamit ang Quarkus dependencies. Ngunit maaari kang pumunta nang higit pa at gawin itong isang katutubong maipapatupad na file.
Pag-install ng GraalVM
Una sa lahat, para dito kailangan mong i-install ang mga kinakailangang tool:
1. I-download ang GraalVM 19.2.0.1 mula sa .
2. Palawakin ang na-download na archive:
$ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz
3. Pumunta sa untar folder.
4. Patakbuhin ang command sa ibaba upang i-download at idagdag ang katutubong larawan:
$ ./bin/gu install native-image
5. Irehistro ang folder na ginawa sa hakbang 2 sa GRAALVM_HOME environment variable:
$ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1)
Para sa karagdagang impormasyon at mga tagubilin sa pag-install sa ibang mga OS, mangyaring sumangguni sa manwal. .
Pagbuo ng helloworld sa isang native na executable na file
Pagbasa ng manwal : “Ngayon, gumawa tayo ng native executable file para sa ating application para mabawasan ang oras ng paglulunsad nito at laki ng disk. Ang executable file ay magkakaroon ng lahat ng kailangan upang patakbuhin ang application, kabilang ang JVM (o sa halip, isang pinutol na bersyon nito, na naglalaman lamang ng kung ano ang kinakailangan upang patakbuhin ang application) at ang aming application mismo."
Upang lumikha ng isang katutubong executable na file, kailangan mong paganahin ang katutubong Maven profile:
$ ./mvnw package -Pnative
Ang aming build ay tumagal ng isang minuto at 10 segundo, at ang huling helloworld—runner f file ay ginawa sa /target na folder.
Patakbuhin ang native na helloworld executable
Sa nakaraang hakbang, natanggap namin ang executable file /target/helloworld—runner. Ngayon, patakbuhin natin ito:
$ ./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]
Buksan ito muli sa browser :8080 at tingnan kung gumagana ang lahat ayon sa nararapat.
Itutuloy!
Naniniwala kami na ang paraan ng pag-modernize ng mga application ng Java gamit ang mga kakayahan ng Quarkus na tinalakay sa post na ito (kahit na gumagamit ng isang simpleng halimbawa) ay dapat na aktibong gamitin sa totoong buhay. Sa paggawa nito, malamang na makakatagpo ka ng maraming problema, na bahagyang tatalakayin natin sa susunod na post, kung saan pag-uusapan natin kung paano sukatin ang pagkonsumo ng memorya upang masuri ang mga pagpapabuti ng pagganap, isang mahalagang bahagi ng buong proseso ng modernisasyon ng aplikasyon.
Pinagmulan: www.habr.com
