Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Introduction to Eclipse Vert.x - My First Vert.x Application

March 13, 2018
Clement Escoffier
Related topics:
JavaMicroservices
Related products:
Red Hat build of Eclipse Vert.x

Share:

    Let’s say, you heard someone saying that Eclipse Vert.x is awesome. Ok great, but you may want to try it yourself. The next logical question is “where do I start?”. This article is a good starting point. It shows: how to build a very simple Vert.x application (nothing fancy), how it is tested, and how it is packaged and executed. Basically everything you need to know before building your own groundbreaking application.

    The code developed in this article is available on GitHub. This is part of the "Introduction to Vert.x Series". The code for this post is located in the https://github.com/redhat-developer/introduction-to-eclipse-vertx repository in the post-1directory.

    Let’s start!

    First, let’s create a project. In this post we use Apache Maven, but you can use Gradle or the build process tool you prefer. You could use the Maven jar archetype to create the structure, but basically you just need a directory with:

    • a src/main/java directory
    • a src/test/java directory
    • a pom.xml file

    So, you would get something like:

    .
    ├── pom.xml
    ├── src
    │   ├── main
    │   │   └── java
    │   └── test
    │       └── java
    

    Let’s create the pom.xml file with the following content:

    4.0.0
    
      io.vertx.intro
      my-first-app
      1.0-SNAPSHOT
    
      
        3.5.0
        1.0.13
      
    
      
        
          io.vertx
          vertx-core
          ${vertx.version}
        
      
    
      
        
          
            maven-compiler-plugin
            3.7.0
            
              1.8
              1.8
            
          
          
            io.fabric8
            vertx-maven-plugin
            ${vmp.version}
            
              
                vmp
                
                  initialize
                  package
                
              
            
            
              true

    This pom.xml file is pretty straightforward:

    • It declares a dependency on the `vertx-core`, the Vert.x version is declared as a property.
    • It configures the `maven-compiler-plugin` to use Java 8.
    • It declares the `vertx-maven-plugin`; we will come back to this in a bit.

    Vert.x requires at least Java 8, so don't try to run a Vert.x application on a Java 6 or 7 JVM; it won't work.

    The vertx-maven-plugin is an optional plugin that packages your app and provides additional functionality (documentation is here). Otherwise you can use the maven-shade-plugin or any other packaging plugin. The vertx-maven-plugin is convenient as it packages the application without any configuration. It also provides a redeploy feature, restarting the application when you update the code or the resources.

    Let’s code!

    Ok, now we have made the pom.xml file. Let’s do some real coding. Create the src/main/java/io/vertx/intro/first/MyFirstVerticle.java file with the following content:

    package io.vertx.intro.first;
    
    import io.vertx.core.AbstractVerticle;
    import io.vertx.core.Future;
    
    public class MyFirstVerticle extends AbstractVerticle {
    
        @Override
        public void start(Future fut) {
            vertx
                .createHttpServer()
                .requestHandler(r ->
                    r.response()
                     .end("
    <h1>Hello from my first Vert.x application</h1>
    
    "))
                .listen(8080, result -> {
                    if (result.succeeded()) {
                        fut.complete();
                    } else {
                        fut.fail(result.cause());
                    }
                });
        }
    }

    This is actually our not fancy application. The class extends AbstractVerticle. In the Vert.x world, a verticle is a component. By extending AbstractVerticle, our class gets access to the vertx field, and the vertx instance on which the verticle is deployed.

    The start method is called when the verticle is deployed. We could also implement a stop method (called when the verticle is undeployed), but in this case Vert.x takes care of the garbage for us. The start method receives a Future object that lets us notify Vert.x when our start sequence has been completed or reports an error if anything bad happens. One of the particularities of Vert.x is its asynchronous and non-blocking aspect. When our verticle is going to be deployed it won’t wait until the start method has been completed. So, the Future parameter is important for notification of the completion. Notice that you can also implement a version of the start method without the Future parameter. In this case, Vert.x considers the verticle deployed when the start method returns.

    The start method creates an HTTP server and attaches a request handler to it. The request handler is a function (here a lambda), which is passed into the requestHandler method, and is called every time the server receives a request. In this code, we just reply Hello (Nothing fancy I told you). Finally, the server is bound to the 8080 port. As this may fail (because the port may already be used), we pass another lambda expression called with the result (and so are able to check whether or not the connection has succeeded). As mentioned above, it calls either fut.complete in case of success, or fut.fail to report an error.

    Before trying the application, edit the pom.xml file and add the vertx.verticle entry in the properties:

    3.5.0
        1.0.13
        <!-- line to add: -->
        io.vertx.intro.first.MyFirstVerticle

    This property instructs Vert.x to deploy this class when it starts.

    Let’s try to compile the application using:

    mvn compile vertx:run

    The application is started; open your browser to http://localhost:8080 and you should see the Hello message. If you change the message in the code and save the file, the application is restarted with the updated message.

    Hit CTRL+C to stop the application.

    That’s all for the application.

    Let’s test

    Well, that’s good to have developed an application but we can never be too careful, so let’s test it. The test uses JUnit and vertx-unit - a framework delivered with Vert.x to make the testing of Vert.x application more natural.

    Open the pom.xml file to add the two following dependencies:

    junit
      junit
      4.12
      test
    
    
      io.vertx
      vertx-unit
      ${vertx.version}
      test

    Now create the src/test/java/io/vertx/intro/first/MyFirstVerticleTest.java with the following content:

    package io.vertx.intro.first;
    
    import io.vertx.core.Vertx;
    import io.vertx.ext.unit.Async;
    import io.vertx.ext.unit.TestContext;
    import io.vertx.ext.unit.junit.VertxUnitRunner;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    
    @RunWith(VertxUnitRunner.class)
    public class MyFirstVerticleTest {
    
        private Vertx vertx;
    
        @Before
        public void setUp(TestContext context) {
            vertx = Vertx.vertx();
            vertx.deployVerticle(MyFirstVerticle.class.getName(),
                context.asyncAssertSuccess());
        }
    
        @After
        public void tearDown(TestContext context) {
            vertx.close(context.asyncAssertSuccess());
        }
    
        @Test
        public void testMyApplication(TestContext context) {
            final Async async = context.async();
    
            vertx.createHttpClient().getNow(8080, "localhost", "/",
                response ->
                    response.handler(body -> {
                        context.assertTrue(body.toString().contains("Hello"));
                        async.complete();
                    }));
        }
    }

    This is a JUnit test case for our verticle. The test uses vertx-unit, so we configure a custom runner (with the @RunWith annotation). vertx-unit makes easy to test asynchronous interactions, which are the basis of Vert.x applications.

    In the setUp method (called before each test), we create an instance of vertx and deploy our verticle. You may have noticed that unlike the traditional JUnit @Before method, it receives a TestContext object. This object lets us control the asynchronous aspect of our test. For instance, when we deploy our verticle, it starts asynchronously, as do most Vert.x interactions. We cannot check anything until it gets started correctly. So, as a second argument of the deployVerticle method, we pass a result handler: context.asyncAssertSuccess(). It fails the test if the verticle does not start correctly. In addition, it waits until the verticle has completed its start sequence. Remember, in our verticle, we call fut.complete(). So it waits until this method is called, and in the case of failures, fails the test.

    Well, the tearDown (called after each test) method is straightforward, and just closes the vertx instance we created.

    Let’s now have a look at the test of our application: the testMyApplication method. The test emits a request to our application and checks the result. Emitting the request and receiving the response is asynchronous. So we need a way to control this. Like the setUp and tearDown methods, the test method receives a TestContext. From this object we create an async handle (async) that lets us notify the test framework when the test has completed (using async.complete()).

    So, once the async handle is created, we create an HTTP client and emit an HTTP request handled by our application with the getNow() method (getNow is just a shortcut for get(...).end()). The response is handled by a handler. In this function, we retrieve the response body by passing another function to the handler method. The body argument is the response body (as a buffer object). We check that the body contains"Hello" and declare the test complete.

    Let’s take a minute to mention the assertions. Unlike in traditional JUnit tests, it uses context.assert.... Indeed, if the assertion fails, it will interrupt the test immediately. So it’s important to use these assertions because of the asynchronous aspect of the Vert.x application and tests. However, Vert.x Unit provides hooks to let you use Hamcrest or AssertJ, as demonstrated in this example and this other example.

    Our test can be run from an IDE, or using Maven:

    mvn clean test

    Packaging

    So, let’s sum up. We have an application and a test. Let’s now package the application. In this post we package the application in a fat jar. A fat jar is a standalone executable Jar file containing all the dependencies required to run the application. This is a very convenient way to package Vert.x applications, as it’s only one file. It also makes them easy to execute.

    To create a fat jar, just run:

    mvn clean package

    The vertx-maven-plugin is taking care of the packaging and creates the target/my-first-app-1.0-SNAPSHOT.jar file embedding our application along with all the dependencies (including Vert.x itself). Check the size: around 6MB; and this includes everything to run the application.

    Executing our application

    Well, it’s nice to have a jar, but we want to see our application running! As stated above, thanks to the fat jar packaging, running the Vert.x application is easy:

    java -jar target/my-first-app-1.0-SNAPSHOT.jar

    Then, open a browser to http://localhost:8080.

    To stop the application, hit CTRL+C.

    Conclusion

    This Vert.x crash course has presented: how you can develop a simple application using Vert.x; how to test it, package it, and run it. So you now have a great start on the road to building an amazing system on top of Vert.x. Next time we will see how to configure our application. Don't forget that the code from this blog post series is available in this repository.

    Happy coding & Stay tuned!

    Last updated: April 22, 2022

    Recent Posts

    • How Trilio secures OpenShift virtual machines and containers

    • How to implement observability with Node.js and Llama Stack

    • How to encrypt RHEL images for Azure confidential VMs

    • How to manage RHEL virtual machines with Podman Desktop

    • Speech-to-text with Whisper and Red Hat AI Inference Server

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue