Skip to content

Getting Started with Quarkus

jfarcand edited this page Feb 18, 2026 · 7 revisions

Getting Started with Quarkus

Build a real-time chat application with Atmosphere and Quarkus 3.21+.

Prerequisites

  • JDK 21+
  • Maven 3.9+

1. Create the Project

<properties>
    <quarkus.version>3.31.3</quarkus.version>
    <maven.compiler.release>21</maven.compiler.release>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-bom</artifactId>
            <version>${quarkus.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.atmosphere</groupId>
        <artifactId>atmosphere-quarkus-extension</artifactId>
        <version>4.0.0</version>
    </dependency>

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-undertow</artifactId>
    </dependency>

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-websockets</artifactId>
    </dependency>

    <dependency>
        <groupId>io.quarkus</groupId>
        <artifactId>quarkus-jackson</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-maven-plugin</artifactId>
            <version>${quarkus.version}</version>
            <extensions>true</extensions>
            <executions>
                <execution>
                    <goals><goal>build</goal></goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

2. Configure

In application.properties:

quarkus.atmosphere.packages=com.example.chat

The extension auto-configures the AtmosphereServlet and handles build-time annotation scanning.

Available Properties

Property Default Description
quarkus.atmosphere.packages (none) Packages to scan for annotations
quarkus.atmosphere.servlet-path /atmosphere/* Servlet URL mapping
quarkus.atmosphere.session-support false Enable HttpSession support
quarkus.atmosphere.heartbeat-interval-in-seconds (default) Heartbeat frequency

3. Create the Chat Service

The code is identical to other deployment models — @ManagedService works the same everywhere:

@ManagedService(path = "/atmosphere/chat",
    atmosphereConfig = "org.atmosphere.cpr.maxInactiveActivity=120000")
public class Chat {

    @Inject
    private AtmosphereResource r;

    @Inject
    private AtmosphereResourceEvent event;

    @Ready
    public void onReady() {
        // Connection is ready
    }

    @Disconnect
    public void onDisconnect() {
        if (event.isClosedByClient()) {
            // Client closed the connection
        }
    }

    @Message(encoders = {JacksonEncoder.class}, decoders = {JacksonDecoder.class})
    public Message onMessage(Message message) {
        return message;
    }
}

You also need a Message class and JacksonEncoder/JacksonDecoder — these are identical to the Spring Boot guide. See Getting Started with Spring Boot for the full code.

4. Add the Client

Place atmosphere.js in src/main/resources/META-INF/resources/javascript/. You can grab the latest build from atmosphere.js releases or install via npm:

npm install atmosphere.js@5
cp node_modules/atmosphere.js/dist/atmosphere.js src/main/resources/META-INF/resources/javascript/

Create src/main/resources/META-INF/resources/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Atmosphere 4.0 Chat — Quarkus</title>
    <script src="javascript/atmosphere.js"></script>
    <style>
        body { font-family: sans-serif; max-width: 600px; margin: 40px auto; }
        #messages { height: 300px; overflow-y: auto; border: 1px solid #ccc; padding: 10px; margin-bottom: 10px; }
        #messages p { margin: 4px 0; }
        #input { width: 100%; padding: 8px; font-size: 14px; }
    </style>
</head>
<body>
    <h2>Atmosphere 4.0 Chat — Quarkus</h2>
    <div id="messages"></div>
    <input id="input" placeholder="Enter your name, then start chatting..." disabled />
    <script src="javascript/app.js"></script>
</body>
</html>

Create src/main/resources/META-INF/resources/javascript/app.js:

document.addEventListener('DOMContentLoaded', async () => {
    const messages = document.getElementById('messages');
    const input = document.getElementById('input');
    let author = null;

    function addMessage(text) {
        const p = document.createElement('p');
        p.textContent = text;
        messages.appendChild(p);
        messages.scrollTop = messages.scrollHeight;
    }

    const subscription = await atmosphere.atmosphere.subscribe(
        {
            url: `${location.protocol}//${location.host}/atmosphere/chat`,
            transport: 'websocket',
            fallbackTransport: 'long-polling',
            trackMessageLength: true,
            contentType: 'application/json'
        },
        {
            open: (response) => {
                addMessage(`Connected via ${response.transport}. Enter your name:`);
                input.disabled = false;
                input.focus();
            },
            message: (response) => {
                const body = response.responseBody.trim();
                if (body.length <= 1) return; // heartbeat
                try {
                    const msg = JSON.parse(body);
                    addMessage(`${msg.author}: ${msg.message}`);
                } catch (e) { /* ignore */ }
            },
            close: () => addMessage('Disconnected.'),
            error: () => addMessage('Connection error.')
        }
    );

    input.addEventListener('keydown', (e) => {
        if (e.key !== 'Enter' || !input.value.trim()) return;
        if (!author) author = input.value.trim();
        subscription.push(JSON.stringify({
            author: author,
            message: input.value.trim()
        }));
        input.value = '';
    });
});

5. Run in Dev Mode

mvn quarkus:dev

Open http://localhost:8080 and start chatting!

Native Image

The Quarkus extension supports GraalVM native compilation:

mvn package -Dnative
./target/atmosphere-quarkus-chat-4.0.0-runner

The extension registers all Atmosphere classes for reflection at build time, so native images work out of the box.

How It Works

The Quarkus extension differs from other deployment models in how it initializes:

  1. Build timeAtmosphereProcessor scans for Atmosphere annotations and registers classes for reflection
  2. Build time — JSR-356 WebSocket endpoints are registered via AtmosphereRecorder
  3. RuntimeQuarkusAtmosphereServlet initializes the framework with the pre-scanned annotation map
  4. RuntimeQuarkusAtmosphereObjectFactory delegates bean creation to the Arc CDI container

This build-time processing is what makes Quarkus startup fast and native-image compatible.

Clone this wiki locally