google-site-verification: google61fe8ba583a51912.html
Quarkus: Supersonic Subatomic Java Framework

Quarkus is a Kubernetes-native Java framework tailored for GraalVM and OpenJDK HotSpot, designed to create lightweight, fast-startup applications ideal for serverless, cloud, and containerized environments.

Why Quarkus? The Supersonic Advantage

  • Ultra-Fast Startup: As low as 0.008 seconds
  • Low Memory Footprint: ~10x less memory than traditional Java
  • Developer Joy: Live coding with hot reload
  • Unified Configuration: Single configuration system
  • Container First: Built for Kubernetes and Docker

Getting Started

Project Setup

<!-- pom.xml --> <?xml version="1.0" encoding="UTF-8"?> <project> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>quarkus-supersonic</artifactId> <version>1.0.0</version> <properties> <compiler-plugin.version>3.11.0</compiler-plugin.version> <maven.compiler.release>17</maven.compiler.release> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id> <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id> <quarkus.platform.version>3.4.0</quarkus.platform.version> <surefire-plugin.version>3.0.0</surefire-plugin.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>${quarkus.platform.artifact-id}</artifactId> <version>${quarkus.platform.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- Core Quarkus --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-arc</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive-jackson</artifactId> </dependency> <!-- Web & JSON --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-vertx</artifactId> </dependency> <!-- Data Persistence --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-hibernate-validator</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-hibernate-orm-panache</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-jdbc-postgresql</artifactId> </dependency> <!-- Reactive --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-mutiny</artifactId> </dependency> <!-- Security --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-oidc</artifactId> </dependency> <!-- Monitoring --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-micrometer</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-smallrye-health</artifactId> </dependency> <!-- Testing --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>${quarkus.platform.group-id}</groupId> <artifactId>quarkus-maven-plugin</artifactId> <version>${quarkus.platform.version}</version> <extensions>true</extensions> <executions> <execution> <goals> <goal>build</goal> <goal>generate-code</goal> <goal>generate-code-tests</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </xml>

Configuration

# application.properties # Application Configuration quarkus.application.name=supersonic-api quarkus.application.version=1.0.0 # HTTP Server Configuration quarkus.http.port=8080 quarkus.http.host=0.0.0.0 quarkus.http.cors=true # Database Configuration quarkus.datasource.db-kind=postgresql quarkus.datasource.username=quarkus quarkus.datasource.password=quarkus quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/quarkusdb quarkus.hibernate-orm.database.generation=update quarkus.hibernate-orm.log.sql=true # JSON Configuration quarkus.jackson.fail-on-unknown-properties=true quarkus.jackson.write-dates-as-timestamps=false # Security Configuration quarkus.oidc.auth-server-url=http://localhost:8180/auth/realms/quarkus quarkus.oidc.client-id=quarkus-app quarkus.http.auth.permission.authenticated.paths=/* quarkus.http.auth.permission.authenticated.policy=authenticated # Monitoring quarkus.micrometer.export.prometheus.path=/metrics quarkus.health.extensions.enabled=true # Dev Mode Configuration quarkus.log.category."com.example".level=DEBUG quarkus.hibernate-orm.log.sql=true

Reactive REST Endpoints

Traditional Imperative Endpoints

package com.example.service; import javax.enterprise.context.ApplicationScoped; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.util.List; @Path("/api/v1/users") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @ApplicationScoped public class UserResource { private final UserService userService; public UserResource(UserService userService) { this.userService = userService; } @GET public List<User> getAllUsers(@QueryParam("page") @DefaultValue("0") int page, @QueryParam("size") @DefaultValue("20") int size) { return userService.findAllUsers(page, size); } @GET @Path("/{id}") public Response getUserById(@PathParam("id") Long id) { return userService.findUserById(id) .map(user -> Response.ok(user).build()) .orElse(Response.status(Response.Status.NOT_FOUND).build()); } @POST public Response createUser(User user) { User created = userService.createUser(user); return Response.status(Response.Status.CREATED).entity(created).build(); } @PUT @Path("/{id}") public Response updateUser(@PathParam("id") Long id, User user) { User updated = userService.updateUser(id, user); return Response.ok(updated).build(); } @DELETE @Path("/{id}") public Response deleteUser(@PathParam("id") Long id) { userService.deleteUser(id); return Response.noContent().build(); } }

Reactive Endpoints with Mutiny

package com.example.service; import io.smallrye.mutiny.Uni; import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.tags.Tag; import org.jboss.resteasy.reactive.ResponseStatus; import javax.enterprise.context.ApplicationScoped; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; import java.util.List; @Path("/api/v2/reactive/users") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @ApplicationScoped @Tag(name = "Reactive Users", description = "Reactive User Management API") public class ReactiveUserResource { private final ReactiveUserService userService; public ReactiveUserResource(ReactiveUserService userService) { this.userService = userService; } @GET @Operation(summary = "Get all users reactively") public Uni<List<User>> getAllUsersReactive( @QueryParam("page") @DefaultValue("0") int page, @QueryParam("size") @DefaultValue("20") int size) { return userService.findAllUsersReactive(page, size); } @GET @Path("/{id}") @Operation(summary = "Get user by ID reactively") public Uni<Response> getUserByIdReactive(@PathParam("id") Long id) { return userService.findUserByIdReactive(id) .map(user -> Response.ok(user).build()) .onFailure(NotFoundException.class).recoverWithItem( () -> Response.status(Response.Status.NOT_FOUND).build() ); } @POST @ResponseStatus(201) @Operation(summary = "Create a new user reactively") public Uni<User> createUserReactive(User user) { return userService.createUserReactive(user); } @GET @Path("/stream") @Produces(MediaType.SERVER_SENT_EVENTS) @Operation(summary = "Stream users as Server-Sent Events") public Multi<User> streamUsers() { return userService.streamUsers(); } }

Data Persistence with Panache

Entity with Active Record Pattern

package com.example.entity; import io.quarkus.hibernate.orm.panache.PanacheEntity; import io.quarkus.hibernate.orm.panache.PanacheEntityBase; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.UpdateTimestamp; import javax.persistence.*; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import java.time.LocalDateTime; import java.util.List; @Entity @Table(name = "users") @NamedQueries({ @NamedQuery(name = "User.findByEmail", query = "FROM User WHERE email = :email"), @NamedQuery(name = "User.findActiveUsers", query = "FROM User WHERE active = true") }) public class User extends PanacheEntityBase { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Long id; @NotBlank @Size(min = 2, max = 50) @Column(nullable = false) public String firstName; @NotBlank @Size(min = 2, max = 50) @Column(nullable = false) public String lastName; @Email @NotBlank @Column(unique = true, nullable = false) public String email; @Column(nullable = false) public Boolean active = true; @CreationTimestamp @Column(updatable = false) public LocalDateTime createdAt; @UpdateTimestamp public LocalDateTime updatedAt; // Active Record methods public static User findByEmail(String email) { return find("email", email).firstResult(); } public static List<User> findActiveUsers() { return list("active", true); } public static List<User> findByName(String name) { return find("firstName like ?1 or lastName like ?1", "%" + name + "%").list(); } public static long deleteByEmail(String email) { return delete("email", email); } }

Repository Pattern with Panache

package com.example.repository; import io.quarkus.hibernate.orm.panache.PanacheRepository; import io.quarkus.panache.common.Parameters; import io.quarkus.panache.common.Sort; import javax.enterprise.context.ApplicationScoped; import java.util.List; import java.util.Optional; @ApplicationScoped public class UserRepository implements PanacheRepository<User> { public Optional<User> findByEmailOptional(String email) { return find("email", email).firstResultOptional(); } public List<User> findByName(String name, int page, int size) { return find("firstName like :name or lastName like :name", Parameters.with("name", "%" + name + "%")) .page(page, size) .list(); } public List<User> findActiveUsersSorted(int page, int size) { return find("active", Sort.by("lastName", "firstName"), true) .page(page, size) .list(); } public long countActiveUsers() { return count("active", true); } public boolean existsByEmail(String email) { return count("email", email) > 0; } }

Business Service Layer

Imperative Service

package com.example.service; import com.example.entity.User; import com.example.repository.UserRepository; import javax.enterprise.context.ApplicationScoped; import javax.transaction.Transactional; import javax.validation.Valid; import java.util.List; import java.util.Optional; @ApplicationScoped public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public List<User> findAllUsers(int page, int size) { return userRepository.findAll() .page(page, size) .list(); } public Optional<User> findUserById(Long id) { return userRepository.findByIdOptional(id); } @Transactional public User createUser(@Valid User user) { if (userRepository.existsByEmail(user.email)) { throw new IllegalArgumentException("Email already exists: " + user.email); } userRepository.persist(user); return user; } @Transactional public User updateUser(Long id, @Valid User userDetails) { User user = userRepository.findByIdOptional(id) .orElseThrow(() -> new NotFoundException("User not found with id: " + id)); user.firstName = userDetails.firstName; user.lastName = userDetails.lastName; user.active = userDetails.active; userRepository.persist(user); return user; } @Transactional public void deleteUser(Long id) { User user = userRepository.findByIdOptional(id) .orElseThrow(() -> new NotFoundException("User not found with id: " + id)); userRepository.delete(user); } public List<User> searchUsers(String query, int page, int size) { return userRepository.findByName(query, page, size); } }

Reactive Service with Mutiny

package com.example.service; import io.smallrye.mutiny.Multi; import io.smallrye.mutiny.Uni; import io.smallrye.mutiny.infrastructure.Infrastructure; import org.hibernate.reactive.mutiny.Mutiny; import javax.enterprise.context.ApplicationScoped; import javax.validation.Valid; import java.time.Duration; import java.util.List; import java.util.concurrent.Executor; @ApplicationScoped public class ReactiveUserService { private final Mutiny.SessionFactory sessionFactory; private final Executor executor; public ReactiveUserService(Mutiny.SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; this.executor = Infrastructure.getDefaultWorkerPool(); } public Uni<List<User>> findAllUsersReactive(int page, int size) { return sessionFactory.withSession(session -> session.createQuery("FROM User u WHERE u.active = true ORDER BY u.lastName, u.firstName", User.class) .setFirstResult(page * size) .setMaxResults(size) .getResultList() ); } public Uni<User> findUserByIdReactive(Long id) { return sessionFactory.withSession(session -> session.find(User.class, id) ).onItem().ifNull().failWith(() -> new NotFoundException("User not found with id: " + id) ); } public Uni<User> createUserReactive(@Valid User user) { return sessionFactory.withTransaction((session, transaction) -> session.createQuery("SELECT COUNT(u) FROM User u WHERE u.email = :email", Long.class) .setParameter("email", user.email) .getSingleResult() .chain(count -> { if (count > 0) { return Uni.createFrom().failure( new IllegalArgumentException("Email already exists: " + user.email) ); } return session.persist(user).replaceWith(user); }) ); } public Multi<User> streamUsers() { return sessionFactory.withSession(session -> session.createQuery("FROM User u WHERE u.active = true", User.class) .getResultList() ).toMulti().flatMap(list -> Multi.createFrom().iterable(list)) .onOverflow().buffer(); } public Uni<User> updateUserReactive(Long id, @Valid User userDetails) { return sessionFactory.withTransaction((session, transaction) -> session.find(User.class, id) .onItem().ifNotNull().transformToUni(user -> { user.firstName = userDetails.firstName; user.lastName = userDetails.lastName; user.active = userDetails.active; return session.merge(user); }) .onItem().ifNull().failWith(() -> new NotFoundException("User not found with id: " + id) ) ); } }

Event-Driven Architecture

Event Producer

package com.example.event; import io.quarkus.vertx.ConsumeEvent; import io.smallrye.mutiny.Uni; import io.smallrye.reactive.messaging.ce.OutgoingCloudEventMetadata; import io.vertx.mutiny.core.eventbus.EventBus; import org.eclipse.microprofile.reactive.messaging.Channel; import org.eclipse.microprofile.reactive.messaging.Emitter; import org.eclipse.microprofile.reactive.messaging.Message; import javax.enterprise.context.ApplicationScoped; import java.util.UUID; @ApplicationScoped public class UserEventProducer { private final EventBus eventBus; private final Emitter<UserEvent> userEventEmitter; public UserEventProducer(EventBus eventBus, @Channel("user-events") Emitter<UserEvent> userEventEmitter) { this.eventBus = eventBus; this.userEventEmitter = userEventEmitter; } public Uni<Void> publishUserCreated(User user) { UserEvent event = UserEvent.created(user); // Local event bus for intra-app communication eventBus.send("user-created", event); // Cloud Events for inter-service communication OutgoingCloudEventMetadata<String> metadata = OutgoingCloudEventMetadata.<String>builder() .withId(UUID.randomUUID().toString()) .withType("user.created") .withSource("quarkus/user-service") .build(); userEventEmitter.send(Message.of(event).addMetadata(metadata)); return Uni.createFrom().voidItem(); } @ConsumeEvent("user-created") public void handleUserCreated(UserEvent event) { // Process the event locally System.out.println("Received user created event: " + event.getUserId()); } } // Event Class class UserEvent { private String type; private Long userId; private String userEmail; private LocalDateTime timestamp; public static UserEvent created(User user) { UserEvent event = new UserEvent(); event.type = "USER_CREATED"; event.userId = user.id; event.userEmail = user.email; event.timestamp = LocalDateTime.now(); return event; } // getters and setters }

Security with JWT

Security Configuration

package com.example.security; import io.quarkus.oidc.runtime.OidcJwtCallerPrincipal; import io.quarkus.security.identity.SecurityIdentity; import org.eclipse.microprofile.jwt.Claims; import org.eclipse.microprofile.jwt.JsonWebToken; import javax.annotation.security.PermitAll; import javax.annotation.security.RolesAllowed; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Context; import javax.ws.rs.core.SecurityContext; import java.security.Principal; @Path("/api/auth") @ApplicationScoped public class SecurityResource { @Inject SecurityIdentity securityIdentity; @Inject JsonWebToken jwt; @GET @Path("/me") @RolesAllowed("user") public UserInfo getCurrentUser() { String email = jwt.getClaim(Claims.email); String name = jwt.getClaim(Claims.name); return new UserInfo( securityIdentity.getPrincipal().getName(), name, email, securityIdentity.getRoles() ); } @GET @Path("/public") @PermitAll public String publicEndpoint() { return "This is public"; } @GET @Path("/admin") @RolesAllowed("admin") public String adminEndpoint() { return "Admin only"; } } class UserInfo { private final String username; private final String name; private final String email; private final Set<String> roles; // constructor and getters }

Testing

Unit Tests

package com.example.service; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.mockito.InjectMock; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import javax.inject.Inject; import java.util.List; import java.util.Optional; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @QuarkusTest class UserServiceTest { @Inject UserService userService; @InjectMock UserRepository userRepository; @Test void testFindUserById_WhenUserExists() { // Given User mockUser = new User(); mockUser.id = 1L; mockUser.firstName = "John"; mockUser.lastName = "Doe"; mockUser.email = "[email protected]"; Mockito.when(userRepository.findByIdOptional(1L)) .thenReturn(Optional.of(mockUser)); // When Optional<User> result = userService.findUserById(1L); // Then assertTrue(result.isPresent()); assertEquals("John", result.get().firstName); assertEquals("Doe", result.get().lastName); } @Test void testFindUserById_WhenUserNotExists() { // Given Mockito.when(userRepository.findByIdOptional(999L)) .thenReturn(Optional.empty()); // When Optional<User> result = userService.findUserById(999L); // Then assertFalse(result.isPresent()); } }

Integration Tests

package com.example.resource; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.security.TestSecurity; import io.restassured.http.ContentType; import org.junit.jupiter.api.Test; import static io.restassured.RestAssured.given; import static org.hamcrest.CoreMatchers.*; @QuarkusTest @TestHTTPEndpoint(UserResource.class) class UserResourceTest { @Test @TestSecurity(user = "testuser", roles = {"user"}) void testGetAllUsers() { given() .when().get() .then() .statusCode(200) .contentType(ContentType.JSON) .body("$.size()", greaterThanOrEqualTo(0)); } @Test @TestSecurity(user = "testuser", roles = {"user"}) void testCreateUser() { String userJson = """ { "firstName": "Jane", "lastName": "Smith", "email": "[email protected]", "active": true } """; given() .contentType(ContentType.JSON) .body(userJson) .when().post() .then() .statusCode(201) .body("firstName", is("Jane")) .body("email", is("[email protected]")); } }

Native Compilation with GraalVM

Dockerfile for Native Image

FROM quay.io/quarkus/quarkus-micro-image:2.0 WORKDIR /work/ COPY target/*-runner /work/application RUN chmod 775 /work EXPOSE 8080 CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]

Build Configuration

# Add to application.properties for native optimization quarkus.native.enable-https=true quarkus.native.additional-build-args=--initialize-at-build-time=com.example.* quarkus.package.type=native quarkus.container-image.build=true quarkus.container-image.group=myorg quarkus.container-image.name=supersonic-api

Monitoring and Health Checks

Custom Health Checks

package com.example.health; import org.eclipse.microprofile.health.HealthCheck; import org.eclipse.microprofile.health.HealthCheckResponse; import org.eclipse.microprofile.health.Readiness; import org.eclipse.microprofile.health.Liveness; import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class DatabaseHealthCheck implements HealthCheck { @Override public HealthCheckResponse call() { boolean isHealthy = checkDatabaseConnection(); return HealthCheckResponse.named("Database connection") .status(isHealthy) .withData("database", "PostgreSQL") .build(); } private boolean checkDatabaseConnection() { // Implement actual database connectivity check return true; } } @Liveness @ApplicationScoped class LivenessCheck implements HealthCheck { @Override public HealthCheckResponse call() { return HealthCheckResponse.named("Application live") .up() .build(); } } @Readiness @ApplicationScoped class ReadinessCheck implements HealthCheck { @Override public HealthCheckResponse call() { return HealthCheckResponse.named("Application ready") .up() .build(); } }

Performance Optimization

Caching with Redis

package com.example.cache; import io.quarkus.redis.datasource.ReactiveRedisDataSource; import io.quarkus.redis.datasource.RedisDataSource; import io.quarkus.redis.datasource.value.ReactiveValueCommands; import io.quarkus.redis.datasource.value.ValueCommands; import io.smallrye.mutiny.Uni; import javax.enterprise.context.ApplicationScoped; import java.time.Duration; @ApplicationScoped public class UserCache { private final ValueCommands<String, User> userCommands; private final ReactiveValueCommands<String, User> reactiveUserCommands; public UserCache(RedisDataSource ds, ReactiveRedisDataSource reactiveDs) { this.userCommands = ds.value(User.class); this.reactiveUserCommands = reactiveDs.value(User.class); } public void cacheUser(String key, User user, Duration ttl) { userCommands.setex(key, ttl.toSeconds(), user); } public User getCachedUser(String key) { return userCommands.get(key); } public Uni<User> getCachedUserReactive(String key) { return reactiveUserCommands.get(key); } public Uni<Void> cacheUserReactive(String key, User user, Duration ttl) { return reactiveUserCommands.setex(key, ttl.toSeconds(), user); } }

Deployment

Kubernetes Deployment

apiVersion: apps/v1 kind: Deployment metadata: name: supersonic-api labels: app: supersonic-api spec: replicas: 3 selector: matchLabels: app: supersonic-api template: metadata: labels: app: supersonic-api spec: containers: - name: supersonic-api image: myorg/supersonic-api:latest ports: - containerPort: 8080 env: - name: QUARKUS_DATASOURCE_JDBC_URL valueFrom: secretKeyRef: name: db-secret key: jdbc-url resources: requests: memory: "64Mi" cpu: "50m" limits: memory: "128Mi" cpu: "200m" livenessProbe: httpGet: path: /q/health/live port: 8080 initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: /q/health/ready port: 8080 initialDelaySeconds: 5 periodSeconds: 10 --- apiVersion: v1 kind: Service metadata: name: supersonic-api spec: selector: app: supersonic-api ports: - port: 80 targetPort: 8080

Key Benefits Demonstrated

  1. Fast Startup: Native compilation starts in milliseconds
  2. Low Memory: Minimal footprint with ahead-of-time compilation
  3. Developer Productivity: Live coding with instant feedback
  4. Reactive First: Built on Vert.x and Mutiny for non-blocking I/O
  5. Cloud Native: Optimized for Kubernetes and serverless
  6. Unified Config: Single configuration file for all environments
  7. Standards Based: Built on Jakarta EE and MicroProfile standards

Quarkus represents the next evolution of Java frameworks, delivering truly supersonic performance while maintaining developer productivity and enterprise capabilities.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper