Quarkus: modernizacja aplikacji na przykładzie helloworld z JBoss EAP Quickstart

Cześć wszystkim na tym blogu, oto czwarty post z serii o Quarkus!

Quarkus: modernizacja aplikacji na przykładzie helloworld z JBoss EAP Quickstart

Poprzedni post dotyczył tego, jak Quarkus łączy MicroProfile i Spring. Przypomnijmy, że Quarkus jest pozycjonowany jako „superszybka subatomowa Java”, czyli „kubernetesowy stos Java, zoptymalizowany pod GraalVM i OpenJDK HotSpot, zbudowany z najlepszych bibliotek i standardów”. Dziś pokażemy, jak zmodernizować już istniejące aplikacje Java, wykorzystując możliwości Quarkus, na przykładzie aplikacji helloworld z repozytorium Red Hat JBoss Enterprise Application Platform (JBoss EAP) Quickstart, w której wykorzystano technologie wspierane przez Quarkus: CDI i Servlet 3.

Warto podkreślić, że zarówno Quarkus, jak i JBoss EAP kładą nacisk na korzystanie z narzędzi maksymalnie opartych na standardach. Nie masz aplikacji działającej na JBoss EAP? Nie ma problemu, można ją łatwo przenieść z obecnego serwera aplikacji na JBoss EAP za pomocą Red Hat Application Migration Toolkit. Po tym zaktualizowana i działająca wersja kodu będzie dostępna w repozytorium github.com/mrizzi/jboss-eap-quickstarts/tree/quarkus, w module helloworld.

Podczas pisania tego postu korzystano z przewodników po Quarkus, głównie Tworzenie pierwszej aplikacji i Budowanie wykonywalnego pliku binarnego.

Zdobywamy kod

Najpierw utworzymy lokalną kopię repozytorium JBoss EAP quickstarts:

$ git clone https://github.com/jboss-developer/jboss-eap-quickstarts.git
Klonowanie do 'jboss-eap-quickstarts'...
remote: Enumerowanie obiektów: 148133, ukończono.
remote: Łącznie 148133 (delta 0), ponownie wykorzystano 0 (delta 0), produkty ponownie użyto 148133
Odbieranie obiektów: 100% (148133/148133), 59.90 MiB | 7.62 MiB/s, ukończono.
Rozwiązywanie delty: 100% (66476/66476), ukończono.
$ cd jboss-eap-quickstarts/helloworld/

Zobaczmy, jak działa oryginalna aplikacja helloworld

Osobiście sens tej aplikacji jest jasny z samej nazwy, ale będziemy modernizować jej kod w sposób naukowy. Dlatego najpierw przyjrzyjmy się tej aplikacji w jej oryginalnej formie.

Rozpoczynamy helloworld

1. Otwórz terminal i przejdź do katalogu głównego JBoss EAP (można go pobrać tutaj), czyli do folderu EAP_HOME.

2. Uruchom serwer JBoss EAP z domyślnym profilem:

$ EAP_HOME/bin/standalone.sh

Uwaga: na Windows używany jest skrypt EAP_HOMEbinstandalone.bat.

Po kilku sekundach w logu powinno się pojawić mniej więcej to:

[org.jboss.as] (Wątek rozruchowy kontrolera) WFLYSRV0025: JBoss EAP 7.2.0.GA (WildFly Core 6.0.11.Final-redhat-00001) uruchomiony w 3315 ms - Uruchomiono 306 z 527 usług (321 usług jest leniwych, pasywnych lub na żądanie)

3. Otwórz w przeglądarce 127.0.0.1:8080 i zobacz to:

Quarkus: modernizacja aplikacji na przykładzie helloworld z JBoss EAP Quickstart

Rys. 1. Strona główna JBoss EAP.

4. Postępuj według instrukcji w przewodniku Budowanie i wdrażanie Quickstart: rozwijamy helloworld i wykonujemy (z głównego folderu projektu) następującą komendę:

$ mvn clean install wildfly:deploy

Po pomyślnym wykonaniu tej komendy w logu zobaczymy mniej więcej to:

[INFO] ------------------------------------------------------------------------ 
[INFO] SUKCES BUDOWY 
[INFO] ------------------------------------------------------------------------ 
[INFO] Całkowity czas: 8.224 s

Zatem pierwsze wdrożenie aplikacji helloworld na JBoss EAP zajęło nieco ponad 8 sekund.

Testujemy helloworld

Działając ściśle według instrukcji Dostęp do aplikacji, otwieramy w przeglądarce 127.0.0.1:8080/helloworld i widzimy coś takiego:

Quarkus: modernizacja aplikacji na przykładzie helloworld z JBoss EAP Quickstart

Rys. 2. Oryginalne Hello World z JBoss EAP.

Wprowadzamy zmiany

Zmiana parametru wejściowego createHelloMessage(String name) z World na Marco:

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

Ponownie wykonujemy następującą komendę:

$ mvn clean install wildfly:deploy

Następnie odświeżamy stronę w przeglądarce i widzimy, że tekst się zmienił:

Quarkus: modernizacja aplikacji na przykładzie helloworld z JBoss EAP Quickstart

Rys. 3. Hello Marco w JBoss EAP.

Cofamy wdrożenie helloworld i kończymy działanie JBoss EAP

To nie jest konieczne, ale jeśli chcesz anulować wdrożenie, możesz to zrobić następującą komendą:

$ mvn clean install wildfly:undeploy

Aby zakończyć działanie instancji JBoss EAP, po prostu naciśnij Ctrl+C w oknie terminala.

Modernizujemy helloworld

Teraz zajmiemy się modernizacją oryginalnej aplikacji helloworld.

Tworzymy nową gałąź

Tworzymy nową roboczą gałąź po zakończeniu wykonywania projektu quickstart:

$ git checkout -b quarkus 7.2.0.GA

Zmiana pliku pom.xml

Aplikację zaczniemy zmieniać od pliku pom.xml. Aby Quarkus mógł wstawiać do niego bloki XML, wykonamy następującą komendę w folderze helloworld:

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

Podczas pisania tego artykułu używana była wersja 0.23.2. Quarkus często wydaje nowe wersje, aby dowiedzieć się, która wersja jest najnowsza, sprawdź stronę github.com/quarkusio/quarkus/releases/latest.

Powyższa komenda wstawi do pom.xml następujące elementy:

  • Właściwość , określająca używaną wersję Quarkus.
  • Blok do importowania Quarkus BOM (bill of materials), aby nie dodawać wersji dla każdej zależności Quarkus.
  • Plugin quarkus-maven-plugin, odpowiedzialny za pakowanie aplikacji i zapewniający tryb dewelopera.
  • Profil native do tworzenia plików wykonywalnych aplikacji.

Ponadto, w pom.xml ręcznie wprowadzamy następujące zmiany:

  1. Wyciągamy tag z bloku i umieszczamy go powyżej tagu . Ponieważ w następnym kroku usuniemy blok , musimy zachować .
  2. Usuwamy blok , ponieważ podczas pracy z Quarkus ta aplikacja nie potrzebuje już rodzica pom z JBoss.
  3. Dodajemy znacznik i umieszczamy go pod znacznikiem . Numer wersji można podać dowolny.
  4. Usuwamy znacznik , ponieważ ta aplikacja nie jest już WAR, a zwykłym JAR.
  5. Modyfikujemy następujące zależności:
    1. Zamieniamy zależność javax.enterprise:cdi-api na io.quarkus:quarkus-arc, usuwając provided, ponieważ (zgodnie z dokumentacją) to Quarkus-rozszerzenie zapewnia wstrzykiwanie zależności CDI.
    2. Zamieniamy zależność org.jboss.spec.javax.servlet:jboss-servlet-api_4.0_spec na io.quarkus:quarkus-undertow, usuwając provided, ponieważ (zgodnie z dokumentacją) to Quarkus-rozszerzenie zapewnia wsparcie dla servletów.
    3. Usuwamy zależność org.jboss.spec.javax.annotation:jboss-annotations-api_1.3_spec, ponieważ jest ona dostarczana z zależnościami, które właśnie zmieniliśmy.

Wersja pliku pom.xml ze wszystkimi zmianami znajduje się pod adresem github.com/mrizzi/jboss-eap-quickstarts/blob/quarkus/helloworld/pom.xml.

Zauważ, że powyższa komenda mvn io.quarkus:quarkus-maven-plugin:0.23.2:create nie tylko zmienia plik pom.xml, ale również dodaje do projektu szereg komponentów, a mianowicie, następujące pliki i foldery:

  • Plik mvnw i mvnw.cmd oraz folder .mvn: Maven Wrapper pozwala na uruchamianie projektów Maven w określonej wersji Maven bez instalacji tej wersji.
  • Folder docker (w katalogu src/main/): znajdują się tam przykłady plików Dockerfile dla trybów native i jvm (razem z plikiem .dockerignore).
  • Folder resources (w katalogu src/main/): znajduje się tam pusty plik application.properties i próbkowy plik startowy Quarkus index.html (więcej informacji w Rozdziale Uruchom nowoczesny helloworld).

Uruchamiamy helloworld
Aby przetestować aplikację, używamy quarkus:dev, który uruchamia Quarkus w trybie programistycznym (więcej informacji w tym rozdziale przewodnika po Tryb rozwoju).

Uwaga: ten krok spowoduje spodziewany błąd, ponieważ nie wprowadziliśmy jeszcze wszystkich wymaganych zmian.

Teraz uruchamiamy polecenie, aby sprawdzić, jak to zadziała:

$ ./mvnw compile quarkus:dev
[INFO] Skanowanie projektów...
[INFO]
[INFO] ----------------< org.jboss.eap.quickstarts:helloworld >----------------
[INFO] Budowanie Quickstart: helloworld quarkus
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld ---
[INFO] Używanie kodowania 'UTF-8' do kopiowania przefiltrowanych zasobów.
[INFO] Kopiowanie 2 zasobów
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld ---
[INFO] Nic do skompilowania - wszystkie klasy są aktualne
[INFO]
[INFO] --- quarkus-maven-plugin:0.23.2:dev (default-cli) @ helloworld ---
Nasłuchiwanie na transporcie dt_socket pod adresem: 5005
INFO  [io.qua.dep.QuarkusAugmentor] Rozpoczynanie augmentacji quarkus
INFO  [org.jbo.threads] Wersja wątków JBoss 3.0.0.Final
ERROR [io.qua.dev.DevModeMain] Nie udało się uruchomić quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Błąd budowy: Budowa nie powiodła się z powodu błędów
	[error]: Krok budowy io.quarkus.arc.deployment.ArcProcessor#validate spowodował wyjątek: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Niezaspokojona zależność dla typu org.jboss.as.quickstarts.helloworld.HelloService i kwalifikatory [@Default]
	- członek java: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService
	- zadeklarowane w BEANIE klasy [typy=[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], kwalifikatory=[@Default, @Any], cel=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)
Przyczyna: javax.enterprise.inject.UnsatisfiedResolutionException: Niezaspokojona zależność dla typu org.jboss.as.quickstarts.helloworld.HelloService i kwalifikatory [@Default]
	- członek java: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService
	- zadeklarowane w BEANIE klasy [typy=[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], kwalifikatory=[@Default, @Any], cel=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 więcej

No, to nie działa… A dlaczego?

Wyjątek UnsatisfiedResolutionException wskazuje na klasę HelloService, która jest członkiem klasy HelloWorldServlet (java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloService). Problematyczne jest to, że HelloWorldServlet wymaga wstrzykniętego egzemplarza HelloService, którego nie udaje się znaleźć (choć obie klasy znajdują się w tym samym pakiecie).

Czas na powrót do dokumentacji i przeczytanie, jak w Quarkus działa Inject, a zatem i Contexts and Dependency Injection (CDI). Dlatego otwieramy podręcznik Contexts and Dependency Injection i w części Bean Discovery czytamy: „Klasa bean, która nie ma określonej adnotacji bean, nie jest wyszukiwana.”

Patrzymy na klasę HelloService – rzeczywiście nie ma takiej adnotacji. Dlatego trzeba ją dodać, aby Quarkus mógł szukać i znajdować bean. A ponieważ jest to obiekt stateless, możemy bez problemu dodać adnotację @ApplicationScoped w następujący sposób:

@ApplicationScoped
public class HelloService {

Uwaga: w tym miejscu środowisko programistyczne może poprosić o dodanie wymaganego pakietu (patrz poniżej), co trzeba będzie zrobić ręcznie, w ten sposób:

import javax.enterprise.context.ApplicationScoped;

Jeśli nie jesteś pewien, jaki zakres użyć w przypadku, gdy dla źródłowego bean'a nie jest on w ogóle określony, przestudiuj dokumentację JSR 365: Contexts and Dependency Injection for Java 2.0—default scope.

Teraz znowu próbujemy uruchomić aplikację poleceniem .\/mvnw compile quarkus:dev:

$ .\/mvnw compile quarkus:dev
[INFO] Skanowanie projektów...
[INFO]
[INFO] ----------------< org.jboss.eap.quickstarts:helloworld >----------------
[INFO] Budowanie Quickstart: helloworld quarkus
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ helloworld ---
[INFO] Używanie kodowania 'UTF-8' do kopiowania filtrowanych zasobów.
[INFO] Kopiowanie 2 zasobów
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ helloworld ---
[INFO] Wykryto zmiany - rekompilacja modułu!
[INFO] Kompilowanie 2 plików źródłowych do /home/mrizzi/git/forked/jboss-eap-quickstarts/helloworld/target/classes
[INFO]
[INFO] --- quarkus-maven-plugin:0.23.2:dev (default-cli) @ helloworld ---
Nasłuchujący na transporcie dt_socket na adresie: 5005
INFO  [io.qua.dep.QuarkusAugmentor] (main) Rozpoczęcie augmentacji quarkus
INFO  [io.qua.dep.QuarkusAugmentor] (main) Augmentacja quarkus zakończona w 576ms
INFO  [io.quarkus] (main) Quarkus 0.23.2 uruchomiony w 1.083s. Nasłuchuje na: http:\/\/0.0.0.0:8080
INFO  [io.quarkus] (main) Aktywowana profil dev. Aktywowana żywa edycja.
INFO  [io.quarkus] (main) Zainstalowane funkcje: [cdi]

Teraz wszystko przebiega bez błędów.

Uruchamiamy zmodernizowany helloworld
Jak napisano w dzienniku, otwieramy w przeglądarce 0.0.0.0:8080 (domowa strona Quarkus w ustawieniach domyślnych) i widzimy to:

Quarkus: modernizacja aplikacji na przykładzie helloworld z JBoss EAP Quickstart

Rys. 4. Domowa strona Quarkus dev.

W adnotacji WebServlet tego programu zapisano następujące definicje kontekstu:

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

Dlatego przechodzimy w przeglądarce do 0.0.0.0:8080/HelloWorld i widzimy następujące:

Quarkus: modernizacja aplikacji na przykładzie helloworld z JBoss EAP Quickstart

Rys. 5: Strona The Quarkus dev dla aplikacji Hello World.

No więc, wszystko działa.

A teraz wprowadzamy zmiany w kodzie. Zwróć uwagę, że polecenie ./mvnw compile quarkus:dev nadal działa i nie zamierzamy go zatrzymywać. Teraz spróbujemy zastosować te same – najbardziej trywialne – zmiany w samym kodzie i zobaczymy, jak Quarkus ułatwia życie programiście:

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

Zapisujemy plik, a następnie odświeżamy stronę internetową, aby zobaczyć napis Hello Marco, jak pokazano na zrzucie ekranu poniżej:

Quarkus: modernizacja aplikacji na przykładzie helloworld z JBoss EAP Quickstart

Rys. 6. Strona Hello Marco w Quarkus dev.

Teraz sprawdzimy wyjście w terminalu:

INFO  [io.qua.dev] (vert.x-worker-thread-3) Wykryto zmiany w plikach źródłowych, rekompilowanie [/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 zatrzymany w 0.003s
INFO  [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) Rozpoczęcie augmentacji quarkus
INFO  [io.qua.dep.QuarkusAugmentor] (vert.x-worker-thread-3) Augmentacja quarkus zakończona w 232ms
INFO  [io.quarkus] (vert.x-worker-thread-3) Quarkus 0.23.2 uruchomiony w 0.257s. Słuchanie na: http://0.0.0.0:8080
INFO  [io.quarkus] (vert.x-worker-thread-3) Profil dev aktywowany. Aktywowane kodowanie na żywo.
INFO  [io.quarkus] (vert.x-worker-thread-3) Zainstalowane funkcje: [cdi]
INFO  [io.qua.dev] (vert.x-worker-thread-3) Całkowity czas wymiany na gorąco: 0.371s

Odświeżenie strony wyzwoliło wykrycie zmian w kodzie źródłowym, a Quarkus automatycznie wykonał procedurę 'stop-start'. I wszystko to zostało zrealizowane w zaledwie 0.371 sekundy (oto ona, ta 'super szybka subatomowa Java').

Budujemy helloworld w pakiet JAR
Teraz, gdy kod działa jak należy, zapakujemy go następującym poleceniem:

$ ./mvnw clean package

To polecenie tworzy dwa pliki JAR w folderze /target: plik helloworld-.jar, który jest standardowym artefaktem budowanym przez polecenie Maven wraz z klasami i zasobami projektu. I plik helloworld—runner.jar, który jest wykonywalnym JAR-em.

Zwróć uwagę, że to nie jest uber-jar, ponieważ wszystkie zależności są po prostu kopiowane do folderu /target/lib (a nie pakowane w plik JAR). Dlatego, aby uruchomić ten JAR z innego folderu lub na innym hoście, należy skopiować zarówno plik JAR, jak i folder /lib, pamiętając, że element Class-Path w pliku MANIFEST.MF w pakiecie JAR zawiera jawne wyliczenie JAR-ów z folderu lib.
Aby dowiedzieć się, jak tworzyć aplikacje uber-jar, zapoznaj się z przewodnikiem Tworzenie Uber-Jar.

Uruchamiamy helloworld, zapakowane w JAR

Teraz możemy uruchomić nasz JAR za pomocą standardowego polecenia java:

$ java -jar ./target/helloworld--runner.jar
INFO  [io.quarkus] (main) Quarkus 0.23.2 uruchomiono w 0.673s. Nasłuchuje na: http://0.0.0.0:8080
INFO  [io.quarkus] (main) Profil prod aktywowany.
INFO  [io.quarkus] (main) Zainstalowane funkcje: [cdi]

Po wykonaniu wszystkich tych kroków, otwórz przeglądarkę i przejdź do 0.0.0.0:8080 i sprawdź, czy wszystko działa jak należy.

Budujemy helloworld w natywny plik wykonywalny

Zatem nasz helloworld działa jako samodzielna aplikacja Java, wykorzystując zależności Quarkus. Ale możemy pójść dalej i przekształcić go w natywny plik wykonywalny.

Instalujemy GraalVM
Przede wszystkim musimy zainstalować potrzebne narzędzia:

1. Pobieramy GraalVM 19.2.0.1 z github.com/oracle/graal/releases/tag/vm-19.2.0.1.

2. Rozpakowujemy pobrany archiwum:

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

3. Przechodzimy do folderu untar.

4. Uruchamiamy poniższe polecenie, aby pobrać i dodać natywny obraz:

$ ./bin/gu install native-image

5. Ustawiamy folder utworzony w kroku 2 w zmiennej środowiskowej GRAALVM_HOME:

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

Dalsze informacje i instrukcje dotyczące instalacji na innych systemach operacyjnych można znaleźć w przewodniku Budowanie natywnego pliku wykonywalnego—Wymagania wstępne.

Przystępujemy do budowy helloworld w natywny plik wykonywalny
Czytamy przewodnik Budowanie natywnego pliku wykonywalnego—Produkcja natywnego pliku wykonywalnego: „A teraz stworzymy natywny plik wykonywalny dla naszej aplikacji, aby skrócić czas jej uruchamiania i rozmiar na dysku. Plik wykonywalny będzie zawierał wszystko, co potrzebne do uruchomienia aplikacji, w tym JVM (a właściwie jego okrojoną wersję, zawierającą tylko to, co jest potrzebne do wykonania aplikacji) oraz samą naszą aplikację.”

Aby stworzyć natywny plik wykonywalny, musimy włączyć profil natywny Maven:

$ ./mvnw package -Pnative

Nasza budowa zajęła jedną minutę i 10 sekund, a końcowy plik helloworld-runner został utworzony w folderze /target.

Uruchamiamy natywny plik wykonywalny helloworld

Na poprzednim kroku uzyskaliśmy plik wykonywalny /target/helloworld-runner. Teraz go uruchommy:

$ ./target/helloworld--runner
INFO  [io.quarkus] (main) Quarkus 0.23.2 uruchomiono w 0.006s. Nasłuchuje na: http://0.0.0.0:8080
INFO  [io.quarkus] (main) Profil prod aktywowany.
INFO  [io.quarkus] (main) Zainstalowane funkcje: [cdi]

Ponownie otwieramy w przeglądarce 0.0.0.0:8080 i sprawdzamy, czy wszystko działa jak należy.

Ciąg dalszy nastąpi!

Uważamy, że metoda modernizacji aplikacji Java omówiona w tym poście (chociaż na prostym przykładzie) z wykorzystaniem możliwości Quarkus powinna być aktywnie stosowana w praktyce. W związku z tym prawdopodobnie napotkasz szereg problemów, rozwiązania których częściowo przedstawimy w następnym poście, w którym omówimy pomiar zużycia pamięci w celu oceny poprawy wydajności, co jest ważną częścią całego procesu modernizacji aplikacji.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster