There are a lot of ways to build a nice web application with a frontend, backend, and a database. The technology stack can have a huge variety nowadays. One can pick almost any modern language for one of the three layers (presentation layer (frontend), logic layer (backend), data layer (database)) or use only one programming language for all of them.
Being a Java full stack developer means that one can build the entire application using only one programming language (except version control, package manager, and CI/CD). Over the past two decades, Java has undergone many transformations.
If one had to jump back in time to the year 1997, the options would be very limited, but it was still possible to be a full stack Java developer. Sockets could be used as a server or HTTP listener, the JDBC (Java Database Connectivity) driver could be used to connect to the database, and the graphical web interface could be made using plain HTML. This stack is marked in red in Figure 1. 
With the release of J2EE 1.4 and later the release of Java EE 5, the more advanced Java servlets and JSP (Java Server Pages) as well as JPA (Java Persistence API) were introduced. Thanks to these new libraries, a much more powerful web app could be built using XML and EL (Expression Language). The new Java Persistence API provided a new and easy way to map POJOs (Plain Old Java Objects) to the database using an OR (Object Relational) mapper. If the application uses servlets or JSP, a servlet or JSP container is required. A lightweight option was Jetty. This stack is marked in orange in Figure 1. 
Although JSF (Java or nowadays called Jakarta Server Faces) was released already in Java EE 5, it became really valuable since Jakarta EE and the application server Wildfly. JSF is more advanced than JSP but still somewhat similar and JSF can be programmed using XML or Java. This stack is marked in yellow in Figure 1. 
An alternative way can be Vaadin in combination with a Spring Boot backend, Spring Data with a NoSQL database like MongoDB as the persistence layer, and an embedded Tomcat as the application server. This is personally my most favorite Java stack to use. In Spring Boot, it has always been convention over configuration, so if one keeps things at default, no configuration is needed at all. This keeps development fast. Creating a new project is fast, too. Spring Boot CLI or the Spring Initializr let one create a project in about a minute. 
Of course, this is only my personal favorite. Nowadays, the opportunities of technologies are very high, especially if one works with Jakarta EE or Spring Boot. So, picking the right libraries can depend on requirements or personal taste. Knowing what options Java offers might help pick the most fitting tools for the project if one wants to build an application fully covered by Java technologies.