Simplest Possible Quarkus Extension 📎
<modelVersion>4.0.0</modelVersion>
<groupId>com.airhacks</groupId>
<version>0.0.5</version>
<artifactId>quarkus-airhacks-extension-parent</artifactId>
<packaging>pom</packaging>
<modules>
<module>runtime</module>
<module>deployment</module>
</modules>
The runtime module contains the implementation of the functionality. In our sample it is a simplistic Servlet
:
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet
public class AirhacksServlet extends HttpServlet {
public AirhacksServlet() {
System.out.println("AirhacksServlet()");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().print("hello from airhacks extension");
}
}
The responsibility of the deployment
module is the exposure of metadata and configuration as early in the build cycle, as possible:
package com.airhacks;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.undertow.deployment.ServletBuildItem;
class AirhacksProcessor {
static final String FEATURE_NAME = "airhacks-extension";
@BuildStep
ServletBuildItem createAirhacksServlet() {
System.out.println("AirhacksProcessor.createAirhacksServlet");
ServletBuildItem servletBuildItem = ServletBuildItem.builder(FEATURE_NAME, AirhacksServlet.class.getName())
.addMapping(FEATURE_NAME)
.build();
return servletBuildItem;
}
@BuildStep
FeatureBuildItem createFeatureItem() {
System.out.println("AirhacksProcessor.createFeatureItem");
return new FeatureBuildItem(FEATURE_NAME);
}
}
A quarkus project (create with: mvn io.quarkus:quarkus-maven-plugin:[CURRENT_VERSION]:create
) needs to declare the dependency to the runtime
module:
<dependency>
<groupId>com.airhacks</groupId>
<artifactId>quarkus-airhacks-extension</artifactId>
<version>0.0.5</version>
</dependency>
mvn install
produces the following output:
[io.quarkus.deployment.QuarkusAugmentor] Beginning quarkus augmentation
[org.jboss.threads] JBoss Threads version 3.0.0.Beta4
AirhacksProcessor.createFeatureItem
AirhacksProcessor.createAirhacksServlet
...indicating both BuildStep
methods were invoked in the build phase.
Quarkus indicates the availability of the airhacks-extension after launch (java -jar target/[NAME]-1.0-SNAPSHOT-runner.jar
) with a log statement:
2019-06-30 10:47:23,863 INFO [io.quarkus] (main) Quarkus 0.16.1 started in 0.738s. Listening on: http://[::]:8080
2019-06-30 10:47:23,872 INFO [io.quarkus] (main) Installed features: [airhacks-extension, cdi, resteasy]
The extension becomes available under: curl http://localhost:8080/airhacks-extension
. The first call invokes the servlet's constructor with
the debug statement: AirhacksServlet()
.
The extension mechanism makes the servlet also available for native compilation with mvn clean install -Pnative
.
The start by direct calling the binary target/[NAME]-1.0-SNAPSHOT-runner
is quicker:
2019-06-30 10:55:19,670 INFO [io.quarkus] (main) Quarkus 0.16.1 started in 0.085s. Listening on: http://[::]:8080
2019-06-30 10:55:19,672 INFO [io.quarkus] (main) Installed features: [airhacks-extension, cdi, resteasy]
consumes less memory (around 8MB), but comes with the same behavior.
The sample code is available from: https://github.com/AdamBien/airhacks-quarkus-extension
See you at Web, MicroProfile and Java EE Workshops at Munich Airport, Terminal 2 or Virtual Dedicated Workshops / consulting. Is Munich's airport too far? Learn from home: airhacks.io.