Creating a Java JSF application with PrimeFaces in NetBeans
PrimeFaces gives JSF pages a broad set of polished interface components, including data tables, calendars, dialogs, validators and file uploads. In NetBeans, those components fit neatly into a Maven-based Java web application: the IDE supplies project navigation, completion and debugging, while Maven resolves the libraries that the browser-facing application needs.
The workflow is straightforward when the JSF API, Faces implementation, PrimeFaces release and Jakarta or javax namespace are aligned. A project can look correct in the editor yet fail at startup if one dependency still uses the older package names. Checking this combination before writing screens prevents most “unknown tag” and NoClassDefFoundError problems.
This guide creates a customer form, connects it to a managed backing bean and runs it in NetBeans. The key decision comes first: whether the target server speaks Jakarta Faces 3.x or the older JSF 2.3 API.
Choose the project and runtime
In NetBeans, choose New Project, then Java with Maven and Web App. Create a Maven WAR project, set the source package and choose a Java release supported by both NetBeans and the target server. JDK 17 or 21 provides a sensible baseline for a new Jakarta project.
The Australian software market includes long-lived javax.faces systems alongside newer Jakarta EE work, so the application type must follow the server rather than IDE defaults. Confirm whether the target uses Jakarta Faces 3.x or JSF 2.3. A distributed team in Sydney, Melbourne or Brisbane should also record its time-zone convention, since Brisbane remains on AEST while Sydney and Melbourne change to AEDT.
Add JSF and PrimeFaces dependencies
Right-click the project, choose Add Dependency and enter Maven coordinates, or edit pom.xml directly. For a Jakarta Faces 3.0 example, the relevant properties and dependencies are:
<properties>
<maven.compiler.release>17</maven.compiler.release>
<primefaces.version>13.0.7</primefaces.version>
</properties>
<dependencies>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>${primefaces.version}</version>
<classifier>jakarta</classifier>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.faces</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
The jakarta classifier on PrimeFaces is significant because its classes implement the Jakarta namespace. Importing the ordinary classifier into a Jakarta application can mix incompatible APIs. Replace the example versions with supported patches, while keeping the Jakarta Faces implementation, PrimeFaces and servlet runtime aligned.
For an existing JSF 2.3 server, use org.glassfish:javax.faces with a compatible PrimeFaces 12.x release and retain the javax.faces namespaces. NetBeans can highlight missing classes, but Maven’s dependency tree is the reliable place to detect duplicate JSF versions.
Build the form and backing bean
Create index.xhtml under src/main/webapp. Add the HTML, Faces and PrimeFaces namespaces, then use a PrimeFaces input, validation message and command button:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://jakarta.faces/html"
xmlns:f="jakarta.faces/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Customer details</title>
</h:head>
<h:body>
<h:form id="customerForm">
<p:inputText id="name" value="#{customerForm.name}">
<f:validateRequired/>
</p:inputText>
<p:commandButton value="Accept" action="#{customerForm.accept}"
update="messages @form"/>
<p:messages id="messages"/>
</h:form>
</h:body>
</html>
The p prefix exposes PrimeFaces components. f:validateRequired rejects an empty customer name before the action runs, while p:messages displays feedback. The button uses AJAX by default, allowing it to update the message area without reloading the whole page.
Create CustomerForm.java in the source package and expose it with jakarta.faces.bean.ManagedBean and jakarta.faces.bean.RequestScoped. Request scope avoids retaining form data after the request, while the getter and setter let JSF expression language read and write the name.
import jakarta.faces.application.FacesMessage;
import jakarta.faces.bean.ManagedBean;
import jakarta.faces.bean.RequestScoped;
import jakarta.faces.context.FacesContext;
@ManagedBean
@RequestScoped
public class CustomerForm {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void accept() {
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_INFO,
"Record accepted", name + " was received."));
}
}
In a JSF 2.3 project, change the managed-bean and Faces imports to their javax equivalents. Never mix the two API lines within one project.
Configure FacesServlet and deployment
Map the XHTML file to the Faces Servlet in src/main/webapp/WEB-INF/web.xml. A Jakarta setup uses jakarta.faces.webapp.FacesServlet, the jakarta.faces.PROJECT_STAGE context parameter and a mapping for *.xhtml:
<context-param>
<param-name>jakarta.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>jakarta.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
JSF 2.3 uses the corresponding javax.faces names. Add index.xhtml as the welcome file if the server does not open it automatically. NetBeans can run the WAR on GlassFish, Payara or Tomcat once that server has been registered. Tomcat still requires the appropriate Servlet and Faces libraries through Maven or its server configuration.
Use Maven’s clean package goal before deployment, then inspect the WAR to confirm that WEB-INF/lib contains one intended Faces implementation and the matching PrimeFaces JAR. Keep credentials in the server’s environment or secret store rather than source control.
Apply reliable build, privacy and release practices
Exercise keyboard navigation, validation, AJAX updates and error handling in the browser and NetBeans debugger. If the operator is covered by the Privacy Act 1988, customer records must be handled under the Australian Privacy Principles, with purpose, access, correction and retention controls reflected in the design; the OAIC provides practical guidance. Commercial email also requires consent, sender identification and a valid unsubscribe path under the Spam Act 2003.
For an Australian deployment, choose an appropriate cloud region such as Sydney or Melbourne when latency or data-location requirements point to a local hosted service, but confirm the provider’s data-handling terms. Store timestamps in UTC and convert them for users. Australian interfaces commonly use day-first dates such as 24/12/2025 and AUD amounts; a consumer checkout should also show GST treatment in line with the Australian Consumer Law.
These release practices keep the project portable as its screens and responsibilities grow:
- Pin the Java, JSF and PrimeFaces versions in
pom.xml, and record why the Jakarta or javax line was selected. - Keep every namespace, import and Faces Servlet class on the same API line.
- Keep sensitive values out of session scope, URL parameters and client-side logs.
- Add component tests for validation and AJAX updates, plus browser tests for critical workflows.
- Run
mvn clean verifyin a clean environment before every release. - Generate dependency reports and check for outdated, duplicated or unexpected JARs.
The resulting NetBeans project keeps dependency management in Maven, development tools in the IDE and presentation concerns in reusable PrimeFaces components.