Bu bloqdakı hər kəsə salam, Quarkus seriyasındakı dördüncü yazı!

Quarkusun MicroProfile və Spring-i necə birləşdirməsi haqqında idi. Bunu xatırladaq “ultra-sürətli atomaltı Java”, aka “GraalVM və OpenJDK HotSpot üçün uyğunlaşdırılmış və ən yaxşı kitabxana və standartlardan yığılmış Kubernetes yönümlü Java yığını” kimi yerləşdirilmişdir. Bu gün biz nümunədən istifadə edərək, Quarkusun imkanlarından istifadə edərək mövcud Java proqramlarını necə modernləşdirməyi göstərəcəyik , Quarkus tərəfindən dəstəklənən CDI və Servlet 3 texnologiyalarından istifadə edir.
Burada qeyd etmək vacibdir ki, həm Quarkus, həm də JBoss EAP mümkün qədər standartlara əsaslanan alətlərdən istifadəni vurğulayır. JBoss EAP-də işləyən tətbiqiniz yoxdur? Heç bir problem yoxdur, o, asanlıqla cari proqram serverinizdən istifadə edərək JBoss EAP-ə köçürülə bilər . Bundan sonra modernləşdirilmiş kodun son və işçi versiyası repozitoriyada olacaq , modulda .
Bu yazını yazarkən istifadə etdik , əsasən və Bina a .
Kodu əldə edək
İlk növbədə, deponun lokal klonunu yaradaq :
$ 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/
Orijinal helloworld necə işlədiyini görək
Əslində, bu tətbiqin mahiyyəti adından aydındır, lakin biz onun kodunu ciddi şəkildə elmi cəhətdən modernləşdirəcəyik. Buna görə də, əvvəlcə bu ərizəyə orijinal formada baxaq.
Helloworld yerləşdirilməsi
1. Terminal açın və JBoss EAP qovluğunun kökünə keçin (onu yükləyə bilərsiniz ), yəni EAP_HOME qovluğuna.
2. JBoss EAP serverini standart profillə işə salın:
$ EAP_HOME/bin/standalone.sh
Qeyd: Windows-da onu işə salmaq üçün EAP_HOMEbinstandalone.bat skripti istifadə olunur.
Bir neçə saniyədən sonra jurnalda belə bir şey görünməlidir:
[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. Brauzerdə açın :8080 və biz bunu görürük:

düyü. 1. JBoss EAP Əsas Səhifəsi.
4. Təlimatdakı təlimatlara əməl edin : helloworld-u genişləndirin və aşağıdakı əmri işlədin (layihənin kök qovluğundan):
$ mvn clean install wildfly:deploy
Bu əmri uğurla yerinə yetirdikdən sonra jurnalda aşağıdakı kimi bir şey görəcəyik:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.224 s
Beləliklə, helloworld tətbiqinin JBoss EAP-də ilk yerləşdirilməsi 8 saniyədən bir qədər çox çəkdi.
Helloworld sınaqdan keçirilir
Təlimatlara uyğun olaraq ciddi şəkildə hərəkət edin , brauzerdə açın :8080/helloworld və biz bunu görürük:

düyü. 2. JBoss EAP-dən orijinal Hello World.
Dəyişikliklər edilməsi
CreateHelloMessage(String name) daxiletmə parametrini World-dən Marco-ya dəyişin:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Aşağıdakı əmri yenidən işə salın:
$ mvn clean install wildfly:deploy
Sonra brauzerdə səhifəni yeniləyirik və mətnin dəyişdiyini görürük:

düyü. 3. JBoss EAP-də Markoya salam.
Helloworld yerləşdirməsini geri qaytarın və JBoss EAP-ı bağlayın
Bu isteğe bağlıdır, lakin yerləşdirməni ləğv etmək istəyirsinizsə, bunu aşağıdakı əmrlə edə bilərsiniz:
$ mvn clean install wildfly:undeploy
JBoss EAP instansiyanızı bağlamaq üçün terminal pəncərəsində sadəcə Ctrl+C düymələrini sıxın.
Helloworld təkmilləşdirilir
İndi orijinal helloworld tətbiqini modernləşdirək.
Yeni filial yaradın
Quickstart layihəsi tamamlandıqdan sonra yeni işçi filialı yaradırıq:
$ git checkout -b quarkus 7.2.0.GA
pom.xml faylının dəyişdirilməsi
Tətbiqi pom.xml faylından dəyişdirməyə başlayacağıq. Quarkus-a XML bloklarını daxil etməyə icazə vermək üçün helloworld qovluğunda aşağıdakı əmri işlədin:
$ mvn io.quarkus:quarkus-maven-plugin:0.23.2:create
Bu məqaləni yazarkən 0.23.2 versiyasından istifadə edilmişdir. Quarkus tez-tez yeni versiyalar buraxır, hansı versiyanın ən son olduğunu vebsaytda öyrənə bilərsiniz .
Yuxarıdakı əmr pom.xml-ə aşağıdakı elementləri daxil edəcək:
- Əmlak , istifadə ediləcək Quarkus versiyasını təyin edir.
- Blok hər Quarkus asılılığı üçün versiya əlavə etməmək üçün Quarkus BOM (materiallar sənədi) idxal etmək.
- Quarkus-maven-plugin proqramın qablaşdırılmasına və inkişaf rejiminin təmin edilməsinə cavabdehdir.
- Proqram icra sənədləri yaratmaq üçün yerli profil.
Bundan əlavə, biz pom.xml-ə aşağıdakı dəyişiklikləri əl ilə edirik:
- Etiketi çıxarmaq blokdan və etiketin üstünə qoyun . Çünki növbəti addımda bloku çıxaracağıq , onda siz saxlamaq lazımdır .
- Blokun çıxarılması , çünki Quarkus ilə işləyərkən bu proqram artıq JBoss-dan ana pom tələb etməyəcək.
- Etiket əlavə edin və etiketin altına qoyun . İstədiyiniz versiya nömrəsini təyin edə bilərsiniz.
- Etiketin çıxarılması , çünki bu proqram artıq MÜHARİBƏ deyil, adi JAR-dır.
- Aşağıdakı asılılıqları dəyişdiririk:
- Javax.enterprise:cdi-api asılılığını io.quarkus:quarkus-arc olaraq dəyişdirin, silin təmin edilmişdir , çünki (sənədlərə görə) bu Quarkus genişləndirilməsi CDI asılılıqlarının inyeksiyasını təmin edir.
- org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec asılılığını io.quarkus:quarkus-undertow olaraq dəyişdirin, silin təmin edilmişdir , çünki (sənədlərə görə) bu Quarkus genişləndirilməsi servletlərə dəstək verir.
- Biz org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec asılılığını silirik, çünki o, indi dəyişdiyimiz asılılıqlarla gəlir.
Bütün dəyişikliklərlə pom.xml faylının versiyası burada yerləşir .
Qeyd edək ki, yuxarıdakı mvn io.quarkus:quarkus-maven-plugin:0.23.2:create əmri nəinki pom.xml faylını dəyişdirir, həm də layihəyə bir sıra komponentləri, yəni aşağıdakı fayl və qovluqları əlavə edir:
- mvnw və mvnw.cmd faylı və .mvn qovluğu: Maven Wrapper sizə həmin versiyanı quraşdırmadan verilmiş Maven versiyasının Maven layihələrini icra etməyə imkan verir.
- Docker qovluğu (src/main/ kataloqunda): Bu yerli və jvm rejimləri üçün nümunə Dockerfiles ehtiva edir (.dockerignore faylı ilə birlikdə).
- Resurslar qovluğu (src/main/ kataloqunda): Bu boş application.properties faylını və nümunə Quarkus index.html başlanğıc səhifəsini ehtiva edir (ətraflı məlumat üçün modernləşdirilmiş helloworld-u işə salmaq bölməsinə baxın).
Helloworld-u işə salın
Tətbiqi sınaqdan keçirmək üçün biz Quarkus-u inkişaf rejimində işə salan quarkus:dev-dən istifadə edirik (ətraflı məlumat üçün təlimatda bu bölməyə baxın ).
Qeyd: Bu addımın xəta ilə nəticələnəcəyi gözlənilir, çünki biz hələ bütün lazımi dəyişiklikləri etməmişik.
İndi onun necə işlədiyini görmək üçün əmri icra edək:
$ ./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
Deməli, işləmir... Niyə?
UnsatisfiedResolutionException HelloWorldServlet sinfinin üzvü olan HelloService sinfinə işarə edir (java üzvü: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). Problem ondadır ki, HelloWorldServlet-ə HelloService-in yeridilmiş nümunəsi lazımdır və onu tapmaq mümkün deyil (hər iki sinif eyni paketdə olsa da).
qayıtmaq vaxtıdır və bunun Quarkusda necə işlədiyini oxuyun , və buna görə də (CDI). Buna görə də, Kontekstlər və Asılılıq Yerləşdirmə təlimatını və bölməni açın oxuyuruq: “Paxla müəyyən edən annotasiyası olmayan lobya sinfi axtarılmır.”
HelloService sinifinə baxaq - həqiqətən belə bir annotasiya yoxdur. Buna görə də əlavə edilməlidir ki, Quarkus lobya axtarıb tapa bilsin. Və bu, vətəndaşlığı olmayan obyekt olduğundan, biz asanlıqla @ApplicationScoped annotasiyasını belə əlavə edə bilərik:
@ApplicationScoped
public class HelloService {
Qeyd: burada inkişaf mühiti sizdən tələb olunan paketi əlavə etməyinizi xahiş edə bilər (aşağıdakı sətirə baxın) və siz bunu əl ilə etməli olacaqsınız, məsələn:
import javax.enterprise.context.ApplicationScoped;
Mənbə lobya üçün ümumiyyətlə göstərilmədiyi halda hansı əhatə dairəsinin istifadə olunacağına şübhə edirsinizsə, sənədləri oxuyun. .
İndi biz yenidən ./mvnw compile quarkus:dev əmri ilə proqramı işə salmağa çalışırıq:
$ ./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]
İndi hər şey səhvsiz gedir.
Modernləşdirilmiş cəhənnəm dünyasının işə salınması
Günlükdə yazıldığı kimi, onu brauzerdə açın :8080 (standart Quarkus başlanğıc səhifəsi) və biz bunu görürük:

düyü. 4. Quarkus dev başlanğıc səhifəsi.
Bu proqram üçün WebServlet annotasiyası aşağıdakı kontekst tərifini ehtiva edir:
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
Buna görə də, biz brauzerə gedirik :8080/HelloWorld və biz aşağıdakıları görürük:

düyü. 5: Hello World tətbiqi üçün Quarkus dev səhifəsi.
Yaxşı, hər şey işləyir.
İndi kodda dəyişikliklər edək. Qeyd edək ki, ./mvnw compile quarkus:dev əmri hələ də işləyir və bizim onu dayandırmaq fikrimiz yoxdur. İndi kodun özündə eyni - çox mənasız - dəyişiklikləri tətbiq etməyə çalışaq və Quarkusun tərtibatçının həyatını necə asanlaşdırdığını görək:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Aşağıdakı ekran görüntüsündə göstərildiyi kimi, Hello Marco-nu görmək üçün faylı yadda saxlayın və veb səhifəni yeniləyin:

düyü. 6. Salam Marco səhifəsi Quarkus dev.
İndi terminalda çıxışı yoxlayaq:
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
Səhifənin yenilənməsi mənbə kodunda dəyişikliklərin aşkarlanmasına səbəb oldu və Quarkus avtomatik olaraq dayandır-başlama prosedurunu həyata keçirdi. Və bütün bunlar cəmi 0.371 saniyə ərzində tamamlandı (burada, "ultra-sürətli atomaltı Java").
Helloworld-u JAR paketində qurmaq
İndi kod lazım olduğu kimi işləyir, gəlin onu aşağıdakı komanda ilə paketləyək:
$ ./mvnw clean package
Bu əmr /target qovluğunda iki JAR faylı yaradır: layihənin sinifləri və resursları ilə birlikdə Maven komandası tərəfindən yığılmış standart artefakt olan helloworld-.jar faylı. Və icra edilə bilən JAR olan helloworld-runner.jar faylı.
Nəzərə alın ki, bu, uber-jar deyil, çünki bütün asılılıqlar sadəcə olaraq /target/lib qovluğuna kopyalanır (JAR faylına paketlənməyib). Buna görə də, bu JAR-ı başqa qovluqdan və ya başqa hostda işə salmaq üçün JAR paketindəki MANIFEST.MF faylındakı Class-Path elementinin tərkibində olduğunu nəzərə alsaq, həm JAR faylının özünü, həm də oradakı /lib qovluğunu kopyalamalısınız. lib qovluqlarından JAR-ların açıq siyahısı
Uber-jar proqramlarını necə yaratmağı öyrənmək üçün təlimata müraciət edin .
JAR-da paketlənmiş helloworld-u işə salın
İndi standart java əmrindən istifadə edərək JAR-ımızı işlədə bilərik:
$ 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]
Bütün bunlar edildikdən sonra brauzerinizə keçin :8080 və hər şeyin lazım olduğu kimi işlədiyini yoxlayın.
helloworld-un yerli icra edilə bilən faylda tərtib edilməsi
Beləliklə, salam dünyamız Quarkus asılılıqlarından istifadə edərək müstəqil Java proqramı kimi işləyir. Ancaq daha da irəli gedə və onu yerli icra edilə bilən fayla çevirə bilərsiniz.
GraalVM quraşdırılır
Bunun üçün ilk növbədə lazımi alətləri quraşdırmalısınız:
1. GraalVM 19.2.0.1-i buradan yükləyin .
2. Yüklənmiş arxivi genişləndirin:
$ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz
3. Untar qovluğuna keçin.
4. Doğma şəkli yükləmək və əlavə etmək üçün aşağıdakı əmri yerinə yetirin:
$ ./bin/gu install native-image
5. 2-ci addımda yaradılmış qovluğu GRAALVM_HOME mühit dəyişəninə qeyd edin:
$ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1)
Digər əməliyyat sistemləri haqqında əlavə məlumat və quraşdırma təlimatları üçün təlimata baxın .
Yerli icra edilə bilən faylda helloworld qurmaq
Təlimatın oxunması : “İndi işə salınma vaxtını və disk ölçüsünü azaltmaq üçün tətbiqimiz üçün yerli icra edilə bilən fayl yaradaq. İcra edilə bilən fayl JVM (daha doğrusu, onun yalnız tətbiqi işə salmaq üçün tələb olunanları ehtiva edən kəsilmiş versiyası) və tətbiqimizin özü də daxil olmaqla, tətbiqi işə salmaq üçün lazım olan hər şeyə sahib olacaq.”
Doğma icra olunan fayl yaratmaq üçün yerli Maven profilini aktivləşdirməlisiniz:
$ ./mvnw package -Pnative
Quraşdırmamız bir dəqiqə 10 saniyə çəkdi və son helloworld—runner f faylı /target qovluğunda yaradıldı.
Yerli helloworld icra edilə bilənini işə salın
Əvvəlki addımda biz /target/helloworld-runner icra edilə bilən faylını aldıq. İndi onu işə salaq:
$ ./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]
Onu yenidən brauzerdə açın :8080 və hər şeyin lazım olduğu kimi işlədiyini yoxlayın.
Ardı var!
Hesab edirik ki, bu yazıda müzakirə olunan Quarkus imkanlarından istifadə edərək Java proqramlarının modernləşdirilməsi metodu (sadə bir nümunədən istifadə etməklə) real həyatda fəal şəkildə istifadə edilməlidir. Bunu edərkən, çox güman ki, bir sıra problemlərlə qarşılaşacaqsınız ki, biz onları növbəti yazıda qismən həll edəcəyik, burada bütün tətbiqi modernləşdirmə prosesinin vacib hissəsi olan performans təkmilləşdirmələrini qiymətləndirmək üçün yaddaş istehlakını necə ölçmək barədə danışacağıq.
Mənbə: www.habr.com
