![]() |
|
Quarkus: Modernize “helloworld” JBoss EAP quickstart, Part 1 - Printable Version +- Sick Gaming (https://sickgaming.net) +-- Forum: Programming (https://sickgaming.net/forum-76.html) +--- Forum: Java & JVM Languages (https://sickgaming.net/forum-78.html) +--- Thread: Quarkus: Modernize “helloworld” JBoss EAP quickstart, Part 1 (/thread-99041.html) |
Quarkus: Modernize “helloworld” JBoss EAP quickstart, Part 1 - xSicKxBot - 03-22-2022 Quarkus: Modernize “helloworld” JBoss EAP quickstart, Part 1 Quarkus is, in its own words, “Supersonic subatomic Java” and a “Kubernetes native Java stack tailored for GraalVM & OpenJDK HotSpot, crafted from the best of breed Java libraries and standards.” For the purpose of illustrating how to modernize an existing Java application to Quarkus, I will use the Red Hat JBoss Enterprise Application Platform (JBoss EAP) quickstarts Code: helloworldIt’s important to note that both Quarkus and JBoss EAP rely on providing developers with tools based—as much as possible—on standards. If your application is not already running on JBoss EAP, there’s no problem. You can migrate it from your current application server to JBoss EAP using the Red Hat Application Migration Toolkit. After that, the final and working modernized version of the code is available in the https://github.com/mrizzi/jboss-eap-quickstarts/tree/quarkus repository inside the Code: helloworldThis article is based on the guides Quarkus provides, mainly Creating Your First Application and Building a Native Executable. Get the code To start, clone the JBoss EAP quickstarts repository locally, running: Code: $ 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/Code: helloworldThe name of the quickstart is a strong clue about what this application does, but let’s follow a scientific approach in modernizing this code, so first things first: Try the application as it is. Deploy Code: helloworld
Code: $ EAP_HOME/bin/standalone.shNote: For Windows, use the Code: EAP_HOME\bin\standalone.batAfter a few seconds, the log should look like: Code: [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)
![]() Figure 1: The JBoss EAP home page.
Code: $ mvn clean install wildfly:deployThis command should end successfully with a log like this: Code: [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.224 sThe Code: helloworldTest Code: helloworldFollowing the Access the Application guide, open Code: http://127.0.0.1:8080/helloworld![]() Figure 2: JBoss EAP’s Hello World. Make changes Change the Code: createHelloMessage(String name)Code: WorldCode: MarcoCode: writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");Execute again the command: Code: $ mvn clean install wildfly:deployand then refresh the web page in the browser to check the message displayed changes, as shown in Figure 3: ![]() Figure 3: JBoss EAP’s Hello Marco. Undeploy Code: helloworldIf you want to undeploy (optional) the application before shutting down JBoss EAP, run the following command: Code: $ mvn clean install wildfly:undeployTo shut down the JBoss EAP instance, enter Ctrl+C in the terminal where it’s running. Let’s modernize Code: helloworldNow we can leave the original Code: helloworldCreate a new branch Create a new working branch once the quickstart project finishes executing: Code: $ git checkout -b quarkus 7.2.0.GACode: pom.xmlThe time has come to start changing the application. starting from the Code: pom.xmlCode: helloworldCode: $ mvn io.quarkus:quarkus-maven-plugin:0.23.2:createThis article uses the 0.23.2 version. To know which is the latest version is, please refer to https://github.com/quarkusio/quarkus/releases/latest/, since the Quarkus release cycles are short. This command changed the Code: pom.xml
Further changes required to Code: pom.xml
The Code: pom.xmlNote that the above Code: mvn io.quarkus:quarkus-maven-plugin:0.23.2:createCode: pom.xml
Run Code: helloworldTo test the application, use Code: quarkus:devNote: We expect this step to fail as changes are still required to the application, as detailed in this section. Now run the command to check if and how it works: Code: $ ./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 moreIt failed. Why? What happened? The Code: UnsatisfiedResolutionExceptionCode: HelloServiceCode: HelloWorldServletCode: java member: org.jboss.as.quickstarts.helloworld.HelloWorldServlet#helloServiceCode: HelloWorldServletCode: HelloServiceIt’s time to return to Quarkus guides to leverage the documentation and understand how Code: @InjectLooking at the Code: HelloServiceCode: @ApplicationScopedCode: @ApplicationScoped public class HelloService {Note: The IDE should prompt you to add the required package shown here (add it manually if need be): Code: import javax.enterprise.context.ApplicationScoped;If you’re in doubt about which scope to apply when the original bean has no scope defined, please refer to the JSR 365: Contexts and Dependency Injection for Java 2.0—Default scope documentation. Now, try again to run the application, executing again the Code: ./mvnw compile quarkus:devCode: $ ./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]This time the application runs successfully. Run the modernized Code: helloworldAs the terminal log suggests, open a browser to Code: http://0.0.0.0:8080![]() Figure 4: The Quarkus dev landing page. This application has the following context’s definition in the Code: WebServletCode: @WebServlet("/HelloWorld") public class HelloWorldServlet extends HttpServlet {Hence, you can browse to Code: http://0.0.0.0:8080/HelloWorld![]() Figure 5: The Quarkus dev Hello World page. It works! Make changes Please, pay attention to the fact that the Code: ./mvnw compile quarkus:devCode: writer.println("<h1>" + helloService.createHelloMessage("Marco") + "</h1>");Save the file, and then refresh the web page to check that Code: Hello Marco![]() Figure 6: The Quarkus dev Hello Marco page. Take time to check the terminal output: Code: 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.371sRefreshing the page triggered the source code change detection and the Quarkus automagic “stop-and-start.” All of this executed in just 0.371 seconds (that’s part of the Quarkus “Supersonic Subatomic Java” experience). Build the Code: helloworldNow that the code works as expected, it can be packaged using the command: Code: $ ./mvnw clean packageThis command creates two JARs in the Code: /targetCode: helloworld-<version>.jarCode: helloworld-<version>-runner.jarPlease pay attention to the fact that this is not an uber-jar, because all of the dependencies are copied into the Code: /target/libCode: /libCode: Class-PathCode: MANIFEST.MFCode: libTo create an uber-jar application, please refer to the Uber-Jar Creation Quarkus guide. Run the Code: helloworldNow, the packaged JAR can be executed using the standard Code: javaCode: $ 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]As done above, open the Code: http://0.0.0.0:8080Build the Code: helloworldSo far so good. The Code: helloworldInstall GraalVM First of all, the tools for creating the native executable have to be installed:
Code: $ tar xvzf graalvm-ce-linux-amd64-19.2.0.1.tar.gz
Code: $ ./bin/gu install native-image
Code: $ export GRAALVM_HOME={untar-folder}/graalvm-ce-19.2.0.1More details and install instructions for other operating systems are available in Building a Native Executable—Prerequisites Quarkus guide. Build the Code: helloworldAs stated in the Building a Native Executable—Producing a native executable Quarkus guide, “Let’s now produce a native executable for our application. It improves the startup time of the application and produces a minimal disk footprint. The executable would have everything to run the application including the ‘JVM’ (shrunk to be just enough to run the application), and the application.” To create the native executable, the Maven Code: nativeCode: $ ./mvnw package -PnativeThe build took me about 1:10 minutes and the result is the Code: helloworld-<version>-runnerCode: /targetRun the Code: helloworldThe Code: /target/helloworld-<version>-runnerCode: $ ./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]As done before, open the Code: http://0.0.0.0:8080Next steps I believe that this modernization, even of a basic application, is the right way to approach a brownfield application using technologies available in Quarkus. This way, you can start facing the issues and tackling them to understand and learn how to solve them. In part two of this series, I’ll look at how to capture memory consumption data in order to evaluate performance improvements, which is a fundamental part of the modernization process. https://www.addtoany.com/add_to/facebook?linkurl=https%3A%2F%2Fdevelopers.redhat.com%2Fblog%2F2019%2F11%2F07%2Fquarkus-modernize-helloworld-jboss-eap-quickstart-part-1%2F&linkname=Quarkus%3A%20Modernize%20%E2%80%9Chelloworld%E2%80%9D%20JBoss%20EAP%20quickstart%2C%20Part%201https://www.addtoany.com/add_to/twitter?linkurl=https%3A%2F%2Fdevelopers.redhat.com%2Fblog%2F2019%2F11%2F07%2Fquarkus-modernize-helloworld-jboss-eap-quickstart-part-1%2F&linkname=Quarkus%3A%20Modernize%20%E2%80%9Chelloworld%E2%80%9D%20JBoss%20EAP%20quickstart%2C%20Part%201https://www.addtoany.com/add_to/linkedin?linkurl=https%3A%2F%2Fdevelopers.redhat.com%2Fblog%2F2019%2F11%2F07%2Fquarkus-modernize-helloworld-jboss-eap-quickstart-part-1%2F&linkname=Quarkus%3A%20Modernize%20%E2%80%9Chelloworld%E2%80%9D%20JBoss%20EAP%20quickstart%2C%20Part%201https://www.addtoany.com/add_to/email?linkurl=https%3A%2F%2Fdevelopers.redhat.com%2Fblog%2F2019%2F11%2F07%2Fquarkus-modernize-helloworld-jboss-eap-quickstart-part-1%2F&linkname=Quarkus%3A%20Modernize%20%E2%80%9Chelloworld%E2%80%9D%20JBoss%20EAP%20quickstart%2C%20Part%201https://www.addtoany.com/add_to/print?linkurl=https%3A%2F%2Fdevelopers.redhat.com%2Fblog%2F2019%2F11%2F07%2Fquarkus-modernize-helloworld-jboss-eap-quickstart-part-1%2F&linkname=Quarkus%3A%20Modernize%20%E2%80%9Chelloworld%E2%80%9D%20JBoss%20EAP%20quickstart%2C%20Part%201https://www.addtoany.com/add_to/reddit?linkurl=https%3A%2F%2Fdevelopers.redhat.com%2Fblog%2F2019%2F11%2F07%2Fquarkus-modernize-helloworld-jboss-eap-quickstart-part-1%2F&linkname=Quarkus%3A%20Modernize%20%E2%80%9Chelloworld%E2%80%9D%20JBoss%20EAP%20quickstart%2C%20Part%201https://www.addtoany.com/add_to/flipboard?linkurl=https%3A%2F%2Fdevelopers.redhat.com%2Fblog%2F2019%2F11%2F07%2Fquarkus-modernize-helloworld-jboss-eap-quickstart-part-1%2F&linkname=Quarkus%3A%20Modernize%20%E2%80%9Chelloworld%E2%80%9D%20JBoss%20EAP%20quickstart%2C%20Part%201 The post Quarkus: Modernize “helloworld” JBoss EAP quickstart, Part 1 appeared first on Red Hat Developer. |