Осы блогтағылардың барлығына сәлем, міне, Quarkus сериясының төртінші жазбасы!

Quarkus MicroProfile және Spring біріктіретіні туралы болды. Естеріңізге сала кетейік Ол «ультра жылдам субатомдық Java» ретінде орналастырылған, яғни «Кубернетеске бағытталған, GraalVM және OpenJDK HotSpot үшін бейімделген және ең жақсы кітапханалар мен стандарттардан жиналған». Бүгін біз мысалды пайдалана отырып, Quarkus мүмкіндіктерін пайдалана отырып, бар Java қолданбаларын жаңарту жолын көрсетеміз , ол Quarkus қолдайтын CDI және Servlet 3 технологияларын пайдаланады.
Мұнда Quarkus және JBoss EAP мүмкіндігінше стандарттарға негізделген құралдарды пайдалануды ерекше атап өткен жөн. JBoss EAP жүйесінде жұмыс істейтін қолданба жоқ па? Мәселе жоқ, оны ағымдағы қолданба серверінен JBoss EAP бағдарламасына оңай көшіруге болады . Осыдан кейін жаңартылған кодтың соңғы және жұмыс нұсқасы репозиторийде қолжетімді болады , модульде .
Бұл постты жазғанда біз пайдаландық , негізінде және ғимарат а .
Кодты алайық
Ең алдымен, репозиторийдің жергілікті клонын жасайық :
$ 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/
Түпнұсқа әлем қалай жұмыс істейтінін көрейік
Шындығында, бұл қосымшаның мәні атауынан түсінікті, бірақ біз оның кодын қатаң түрде ғылыми түрде жаңартамыз. Сондықтан, алдымен, осы қосымшаны бастапқы түрінде қарастырайық.
Әдемі әлемді орналастыру
1. Терминалды ашып, JBoss EAP қалтасының түбіріне өтіңіз (оны жүктеп алуға болады ), яғни EAP_HOME қалтасына.
2. JBoss EAP серверін әдепкі профильмен іске қосыңыз:
$ EAP_HOME/bin/standalone.sh
Ескертпе: туралы Windows Іске қосу үшін EAP_HOMEbinstandalone.bat скрипті қолданылады.
Бірнеше секундтан кейін журналда келесідей нәрсе пайда болуы керек:
[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. Браузерде ашыңыз :8080 және біз мынаны көреміз:

Күріш. 1. JBoss EAP негізгі беті.
4. Нұсқаулықтағы нұсқауларды орындаңыз : helloworld кеңейтіп, келесі пәрменді іске қосыңыз (жобаның түбірлік қалтасынан):
$ mvn clean install wildfly:deploy
Бұл пәрменді сәтті орындағаннан кейін журналда келесідей нәрсені көреміз:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.224 s
Осылайша, JBoss EAP жүйесінде helloworld қолданбасын бірінші рет орналастыру 8 секундтан астам уақытты алды.
Әдемі әлемді сынау
Нұсқауларға сәйкес қатаң түрде әрекет ету , браузерде ашыңыз :8080/helloworld және біз мынаны көреміз:

Күріш. 2. JBoss EAP ұсынған түпнұсқа Hello World.
Өзгерістер енгізу
CreateHelloMessage (Жол атауы) енгізу параметрін Әлемнен Маркоға өзгертіңіз:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Келесі пәрменді қайта іске қосыңыз:
$ mvn clean install wildfly:deploy
Содан кейін біз браузердегі бетті жаңартып, мәтіннің өзгергенін көреміз:

Күріш. 3. JBoss EAP бағдарламасындағы Марко сәлем.
Heloworld орналастыруын кері қайтарыңыз және JBoss EAP өшіріңіз
Бұл міндетті емес, бірақ орналастырудан бас тартқыңыз келсе, мұны келесі пәрмен арқылы орындауға болады:
$ mvn clean install wildfly:undeploy
JBoss EAP данасын өшіру үшін терминал терезесінде жай ғана Ctrl+C басыңыз.
Әдемі әлемді жаңарту
Енді түпнұсқа helloworld қосымшасын жаңартайық.
Жаңа филиал жасаңыз
Жылдам іске қосу жобасы аяқталғаннан кейін біз жаңа жұмыс тармағын жасаймыз:
$ git checkout -b quarkus 7.2.0.GA
pom.xml файлын өзгерту
Біз қолданбаны өзгертуді pom.xml файлынан бастаймыз. Quarkus оған XML блоктарын кірістіруге рұқсат беру үшін helloworld қалтасында келесі пәрменді орындаңыз:
$ mvn io.quarkus:quarkus-maven-plugin:0.23.2:create
Бұл мақаланы жазу кезінде 0.23.2 нұсқасы пайдаланылды. Quarkus жиі жаңа нұсқаларды шығарады, сіз веб-сайттан қай нұсқаның соңғы екенін біле аласыз .
Жоғарыдағы пәрмен келесі элементтерді pom.xml ішіне кірістіреді:
- Меншік , ол қолданылатын Quarkus нұсқасын көрсетеді.
- Блоктау әр Quarkus тәуелділігі үшін нұсқаны қоспау үшін Quarkus BOM (материалдар тізімі) импорттаңыз.
- Quarkus-maven-плагин қолданбаны орау және әзірлеу режимін қамтамасыз ету үшін жауап береді.
- Бағдарламаның орындалатын файлдарын жасауға арналған жергілікті профиль.
Сонымен қатар, біз pom.xml файлына келесі өзгертулерді қолмен енгіземіз:
- Тегті шығару блоктан және оны тегтің үстіне қойыңыз . Өйткені келесі қадамда біз блокты алып тастаймыз , содан кейін сақтау керек .
- Блокты жою , себебі Quarkus бағдарламасымен жұмыс істегенде, бұл қолданбаға JBoss ұсынған ата-аналық пом қажет болмайды.
- Тег қосыңыз және оны тегтің астына қойыңыз . Қалаған нұсқа нөмірін көрсетуге болады.
- Тегті жою , өйткені бұл қолданба енді WAR емес, кәдімгі JAR.
- Біз келесі тәуелділіктерді өзгертеміз:
- Javax.enterprise:cdi-api тәуелділігін io.quarkus:quarkus-arc етіп өзгерту, жою қамтамасыз етілген , өйткені (құжаттарға сәйкес) бұл Quarkus кеңейтімі CDI тәуелділіктерін енгізуді қамтамасыз етеді.
- org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec тәуелділігін io.quarkus:quarkus-undertow етіп өзгертіңіз, жою қамтамасыз етілген , себебі (құжаттарға сәйкес) бұл Quarkus кеңейтімі сервлеттерге қолдау көрсетеді.
- Біз org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec тәуелділігін алып тастаймыз, себебі ол біз өзгерткен тәуелділіктермен бірге келеді.
Барлық өзгертулері бар pom.xml файлының нұсқасы мына жерде орналасқан .
Жоғарыдағы mvn io.quarkus:quarkus-maven-plugin:0.23.2:create пәрмені pom.xml файлын өзгертіп қана қоймай, сонымен қатар жобаға бірқатар құрамдастарды, атап айтқанда келесі файлдар мен қалталарды қосатынын ескеріңіз:
- mvnw және mvnw.cmd файлы және .mvn қалтасы: Maven Wrapper берілген Maven нұсқасының Maven жобаларын сол нұсқаны орнатпай іске қосуға мүмкіндік береді.
- Docker қалтасы (src/main/ каталогында): Бұл жергілікті және jvm режимдеріне арналған Docker файлдарының мысалын қамтиды (.dockerignore файлымен бірге).
- Ресурстар қалтасы (src/main/ каталогында): Бұл бос application.properties файлын және Quarkus index.html үлгісінің бастапқы бетін қамтиды (қосымша мәліметтер алу үшін Жаңартылған helloworld іске қосу бөлімін қараңыз).
Сәлем әлемін іске қосыңыз
Қолданбаны сынау үшін біз Quarkus әзірлеу режимінде іске қосатын 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] 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
Сонымен, ол жұмыс істемейді... Неге?
UnsatisfiedResolutionException HelloWorldServlet сыныбының мүшесі болып табылатын HelloService сыныбына нұсқайды (java мүшесі: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). Мәселе мынада, HelloWorldServlet бағдарламасына HelloService инъекциялық данасы қажет және оны табу мүмкін емес (осы класстардың екеуі бір бумада болса да).
Қайту уақыты келді және оның Кваркуста қалай жұмыс істейтінін оқыңыз , демек (CDI). Сондықтан контекстер мен тәуелділікті енгізу нұсқаулығын және бөлімді ашыңыз біз оқимыз: «Бұршақты анықтайтын аннотациясы жоқ бұршақ класы ізделмейді».
HelloService класын қарастырайық - бұл шын мәнінде мұндай аннотация жоқ. Сондықтан оны Кваркус бұршақты іздеп таба алатындай етіп қосу керек. Бұл азаматтығы жоқ нысан болғандықтан, біз @ApplicationScoped аннотациясын келесідей оңай қоса аламыз:
@ApplicationScoped
public class HelloService {
Ескертпе: мұнда әзірлеу ортасы қажетті буманы қосуды сұрауы мүмкін (төмендегі жолды қараңыз) және мұны келесідей қолмен орындауға тура келеді:
import javax.enterprise.context.ApplicationScoped;
Бастапқы бұршақ үшін мүлде көрсетілмеген жағдайда қандай көлемді пайдалану керектігіне күмәндансаңыз, құжаттаманы оқыңыз. .
Енді біз қосымшаны ./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]
Енді бәрі қатесіз өтеді.
Модернизацияланған әсем әлемді іске қосу
Журналда жазылғандай, оны браузерде ашыңыз :8080 (әдепкі Quarkus бастапқы беті) және біз мынаны көреміз:

Күріш. 4. Quarkus dev бастапқы беті.
Бұл қолданбаға арналған WebServlet аннотациясында келесі мәтінмән анықтамасы бар:
@WebServlet("/HelloWorld")
public class HelloWorldServlet extends HttpServlet {
Сондықтан біз браузерге барамыз :8080/HelloWorld және біз мынаны көреміз:

Күріш. 5: Hello World қолданбасына арналған Quarkus dev беті.
Жақсы, бәрі жұмыс істейді.
Енді кодқа өзгертулер енгізейік. ./mvnw compile quarkus:dev пәрмені әлі жұмыс істеп тұрғанын және оны тоқтату ниетіміз жоқ екенін ескеріңіз. Енді кодқа бірдей - өте тривиальды өзгертулерді қолдануға тырысайық және Quarkus әзірлеуші өмірін қалай жеңілдететінін көрейік:
writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");
Төмендегі скриншотта көрсетілгендей, Hello Marco көру үшін файлды сақтаңыз, содан кейін веб-бетті жаңартыңыз:

Күріш. 6. Сәлем Марко беті Quarkus dev.
Енді терминалдағы шығысты тексерейік:
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
Бетті жаңарту бастапқы кодтағы өзгерістерді анықтауды іске қосты және Quarkus автоматты түрде тоқтату-бастау процедурасын орындады. Мұның бәрі небәрі 0.371 секундта аяқталды (міне, «ультра жылдам субатомдық Java»).
JAR бумасына мейірім әлемін құру
Енді код қажетінше жұмыс істейді, оны келесі пәрменмен буып алайық:
$ ./mvnw clean package
Бұл пәрмен /target қалтасында екі JAR файлын жасайды: helloworld-.jar файлы, ол жобаның сыныптары мен ресурстарымен бірге Maven тобы жинаған стандартты артефакт болып табылады. Және орындалатын JAR болып табылатын helloworld-runner.jar файлы.
Бұл uber-jar емес екенін ескеріңіз, өйткені барлық тәуелділіктер /target/lib қалтасына көшіріледі (JAR файлына бумаланбаған). Сондықтан, осы JAR файлын басқа қалтадан немесе басқа хостта іске қосу үшін JAR бумасындағы MANIFEST.MF файлындағы Class-Path элементі бар екенін ескере отырып, JAR файлының өзін де, /lib қалтасын да көшіру керек. lib қалталарындағы JAR файлдарының нақты тізімі
Uber-jar қолданбаларын жасау жолын білу үшін оқу құралын қараңыз .
JAR пакетінде салынған helloworld бағдарламасын іске қосыңыз
Енді стандартты java пәрменін пайдаланып JAR-ды іске қоса аламыз:
$ 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]
Осының барлығын орындағаннан кейін браузеріңізге өтіңіз :8080 және бәрі дұрыс жұмыс істейтінін тексеріңіз.
helloworld файлын жергілікті орындалатын файлға құрастыру
Сонымен, біздің helloworld Quarkus тәуелділіктерін пайдалана отырып, дербес Java қолданбасы ретінде жұмыс істейді. Бірақ сіз одан әрі барып, оны жергілікті орындалатын файлға айналдыра аласыз.
GraalVM орнатылуда
Ең алдымен, бұл үшін сізге қажетті құралдарды орнату керек:
1. GraalVM 19.2.0.1 нұсқасын мына жерден жүктеп алыңыз .
2. Жүктелген мұрағатты кеңейтіңіз:
$ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz
3. Untar қалтасына өтіңіз.
4. Жергілікті кескінді жүктеп алу және қосу үшін төмендегі пәрменді орындаңыз:
$ ./bin/gu install native-image
5. 2-қадамда жасалған қалтаны GRAALVM_HOME ортасының айнымалы мәніне тіркеңіз:
$ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1)
Басқа операциялық жүйелер туралы қосымша ақпаратты және орнату нұсқауларын нұсқаулықтан қараңыз .
Жергілікті орындалатын файлға helloworld құру
Нұсқаулықты оқу : «Енді іске қосу уақыты мен диск өлшемін азайту үшін қолданбамыз үшін жергілікті орындалатын файлды жасайық. Орындалатын файлда қолданбаны іске қосу үшін қажеттінің бәрі болады, соның ішінде JVM (дәлірек айтсақ, қолданбаны іске қосу үшін қажет нәрсені ғана қамтитын оның қысқартылған нұсқасы) және біздің қолданбаның өзі.
Жергілікті орындалатын файлды жасау үшін жергілікті Maven профилін қосу керек:
$ ./mvnw package -Pnative
Біздің құрастыру бір минут 10 секундқа созылды және соңғы helloworld — runner f файлы /target қалтасында жасалды.
Жергілікті helloworld орындалатын файлын іске қосыңыз
Алдыңғы қадамда біз /target/helloworld— runner орындалатын файлын алдық. Енді оны іске қосайық:
$ ./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]
Оны браузерде қайтадан ашыңыз :8080 және бәрі дұрыс жұмыс істейтінін тексеріңіз.
Жалғасы бар!
Біз осы постта талқыланған Quarkus мүмкіндіктерін пайдаланып Java қолданбаларын модернизациялау әдісін (қарапайым мысалды қолданса да) нақты өмірде белсенді түрде қолдану керек деп есептейміз. Бұл ретте сіз бірқатар мәселелерге тап болуыңыз мүмкін, оларды біз келесі мақалада ішінара қарастырамыз, онда өнімділікті жақсартуды бағалау үшін жадты тұтынуды қалай өлшеуге болатыны туралы айтатын боламыз, бұл қолданбаны модернизациялау процесінің маңызды бөлігі.
Ақпарат көзі: www.habr.com
