For reference, here is the minimal Maven project structure for a Quarkus 3 application using Faces 4, OmniFaces 4, and CDI 4.
This is an alternative to the Smallest Working Quarkus 3 Application with Faces 4, OmniFaces 4, and CDI 4.
pom.xml
Below is the minimal Maven configuration, including the quarkus-maven-plugin
setup required to produce a JAR:
<?xml version="1.0" encoding="UTF-8"?>
<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>quarkus3-omnifaces4</artifactId>
<version>1.0.0</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-bom</artifactId>
<version>3.26.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.myfaces.core.extensions.quarkus</groupId>
<artifactId>myfaces-quarkus</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>io.quarkiverse.omnifaces</groupId>
<artifactId>quarkus-omnifaces</artifactId>
<version>4.6.5</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>3.26.0</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Currently, only MyFaces provides a Quarkus-compatible Faces 4.x implementation. Mojarra still has issue 5442 open on this. OmniFaces 4.x can be used via the Quarkus OmniFaces extension. CDI 4.x is already natively supported by Quarkus.
src/main/java/com/example/backing/ExampleBacking.java
The CDI managed bean representing a Jakarta Faces backing bean utilizing OmniFaces powerful @ViewScoped
annotation with its memory-saving unload feature:
package com.example.backing;
import java.io.Serializable;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import org.omnifaces.cdi.ViewScoped;
import com.example.service.ExampleService;
@Named
@ViewScoped
public class ExampleBacking implements Serializable {
private static final long serialVersionUID = 1L;
private String input;
private String output;
@Inject
private ExampleService service;
public void submit() {
output = service.process(input);
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public String getOutput() {
return output;
}
}
src/main/java/com/example/service/ExampleService.java
The CDI service:
package com.example.service;
import jakarta.enterprise.context.ApplicationScoped;
@ApplicationScoped
public class ExampleService {
public String process(String input) {
return "Hello! You have typed: " + input;
}
}
src/main/resources/META-INF/resources/index.xhtml
The Facelet file with a basic Jakarta Faces form:
<!DOCTYPE html>
<html lang="en"
xmlns:f="jakarta.faces.core"
xmlns:h="jakarta.faces.html"
>
<h:head>
<title>Hello!</title>
</h:head>
<h:body>
<h1>Hello!</h1>
<h:form>
<h:outputLabel for="input" value="Type something: " />
<h:inputText id="input" value="#{exampleBacking.input}" />
<h:commandButton value="Submit" action="#{exampleBacking.submit}">
<f:ajax execute="@form" render=":output" />
</h:commandButton>
</h:form>
<h:outputText id="output" value="#{exampleBacking.output}" />
</h:body>
</html>
Note that web resources, such as Facelets files, must to be placed in the src/main/resources/META-INF/resources
folder as if it were a web fragment JAR project rather than src/main/webapp
as in a WAR project!
Unlike the Spring Boot 3 approach, you don't need a configuration class like ExampleApplication
or a beans.xml
file.
Build and run it!
First cd
into the folder where the pom.xml
is located.
Now create the Thin JAR:
mvn clean packageThen execute the Thin JAR:
java -jar target/quarkus-app/quarkus-run.jarFinally launch your default web browser on http://localhost:8080/index.xhtml:
browse http://localhost:8080/index.xhtmlHow about a Fat JAR?
In Quarkiverse, this is called an Uber JAR. You need to provide an additional build argument:
mvn clean package -Dquarkus.package.jar.type=uber-jarThen execute the Uber JAR:
java -jar target/quarkus3-omnifaces4-1.0.0-SNAPSHOT-runner.jarYou can add a property to the pom.xml
to make this the default behavior when running the mvn clean package command.
<properties>
<quarkus.package.jar.type>uber-jar</quarkus.package.jar.type>
</properties>