How to run Vaadin in Jakarta EE Containers
source link: https://www.mastertheboss.com/web/vaadin/how-to-run-vaadin-in-jakarta-ee-containers/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
In this tutorial we will learn how to create a Vaadin Flow project that we can run on any Jakarta EE Container such as WildFly or TomEE. We will start from a starter template and we will adapt it to create a sample Customer Form that binds its fields into the Database.
Setting up the Vaadin Flow Jakarta EE project
Firstly, if you are new to Vaadin Flow, we recommend heading first to this introduction article: Vaadin Tutorial: Building Modern Web Applications with Ease
In order to bootstrap a Vaadin Flow project which contains the right dependencies for a Jakarta EE container (WildFly), you can surf to the project initializer at: https://start.vaadin.com/app
Expand the options by clicking on Edit and choose as Architecture “Jakarta EE“. Then, download the project.
A quick look at the project
pom.xml
reveals that, besides the Jakarta EE 10 dependencies and the general
vaadin
dependency, our project contains the
vaadin-cdi
dependency. This is essential to bridge the world of Vaadin Flow with Jakarta EE that is based on CDI:
<dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-web-api</artifactId> <version>10.0.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.vaadin</groupId> <!-- Replace artifactId with vaadin-core to use only free components --> <artifactId>vaadin</artifactId> </dependency> <dependency> <groupId>com.vaadin</groupId> <artifactId>vaadin-cdi</artifactId> </dependency>
Besides, the project also includes WildFly Maven plugin, therefore will deploy our application to WildFly in a snap.
Coding our Vaadin Flow Route
The built-in project already contains a couple of example Classes:
src ├── main │ ├── java │ │ └── org │ │ └── vaadin │ │ └── example │ │ ├── AppShell.java │ │ ├── GreetService.java │ │ └── MainView.java
- The
AppShell
Class is essential for defining and configuring the Progressive Web App aspects of a Vaadin application. It sets up PWA-related metadata and defines the theme to be used for styling UI components across the application. - The MainView
MainView
Class defines a Vaadin Flow Route with a minimal set of Components in it, to print an Hello Message.
In order to customize our project, we will customize the
MainView
Class. The new implementation will contain a Form with some fields that will be submitted to the back-end Service:
@Route("") @CdiComponent public class MainView extends VerticalLayout { @Inject private CustomerService service; private Binder<Customer> binder = new Binder<>(Customer.class); @PostConstruct public void init() { TextField firstName = new TextField("First Name"); TextField lastName = new TextField("Last Name"); TextField email = new TextField("Email"); ComboBox<String> countryComboBox = new ComboBox<>("Country"); countryComboBox.setItems("USA", "Canada"); // Add your country options here binder.bind(firstName, Customer::getFirstName, Customer::setFirstName); binder.bind(lastName, Customer::getLastName, Customer::setLastName); binder.bind(email, Customer::getEmail, Customer::setEmail); binder.bind(countryComboBox, Customer::getCountry, Customer::setCountry); Button registerButton = new Button("Register", event -> { Customer customer = new Customer(); binder.writeBeanIfValid(customer); service.register(customer); // Perform registration logic here String message = "Registration successful for: " + firstName.getValue() + " " + lastName.getValue() + ", Email: " + email.getValue(); Notification.show(message); // Clear all fields after registration is completed binder.removeBean(); // Remove current bean from the binder binder.setBean(new Customer()); // Set a new instance of Customer to the binder }); registerButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY); registerButton.addClickShortcut(Key.ENTER); addClassName("centered-content"); add(firstName, lastName, email, countryComboBox, registerButton); } }
The most interesting addition is the use of the Binder
Class. The Binder
class in Vaadin is a crucial component used for binding data between UI components and Java objects. It plays a pivotal role in simplifying the process of synchronizing and validating data entered in UI components (like text fields, checkboxes, etc.) with corresponding data objects in Java.
In our example, by executing
binder.writeBeanIfValid(customer),
we copy the Form Components in a new Customer Object.
Here is the Customer definition:
@Entity public class Customer { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String firstName; private String lastName; private String email; // Getters / setters }
Finally, once that we have all Customer properties in place, we can call the
service.register(customer)
that will persist the Customer in the Database:
@ApplicationScoped public class CustomerService { @PersistenceContext EntityManager em; @Transactional public void register(Customer customer) { em.persist(customer); } }
Running our Flow
Since the WildFly plugin is available, we can start WildFly and deploy the application as follows:
mvn install wildfly:deploy
The application will register on the root Web Context. Therefore we can access it at: http://localhost:8080:
You can experiment, by filling up the Form and clicking on the Register button. Verify that the operation completes successfully. For the sake of brevity, we didn’t discuss here the persistence.xml configuration of our application which uses just the H2 database. You can check the full source code at the end of this article.
Fixing the Error NoClassDefFoundError: com/sun/nio/file/ExtendedWatchEventModifier
By deploying the Vaadin starter on WildFly 30, I have hit the following error:
19:54:47,193 ERROR [com.vaadin.base.devserver.FileWatcher] (ForkJoinPool.commonPool-worker-18) Error starting file watcher: java.lang.NoClassDefFoundError: com/sun/nio/file/ExtendedWatchEventModifier
As discussed in this issue, this is related to a defect in the File Watcher when you are deploying a multi module project on WildFly. Until the issue is fixed, the workaround is to is to add com.sun.nio.file
as a dependency.
Therefore, add the following configuration to your
maven.war.plugin
:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <archive> <manifestEntries> <Dependencies>jdk.unsupported</Dependencies> </manifestEntries> </archive> </configuration> </plugin>
Conclusion
This article was a complete walkthrough the set up and creation of a complete Vaadin Flow project. We have covered the key aspects related to the creation of a Form with some components and how to bind them so that we can use as DTO for a Service Class. We also have discussed how to fix an issue related to the deployment on WildFly of the Vaadin Flow Jakarta EE project.
Source code: https://github.com/fmarchioni/mastertheboss/tree/master/web/vaadin/jakartaee
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK