Unable to create a Configuration, because no Bean Validation provider could be found - Vaadin 14 Spring Boot
Asked Answered
D

2

6

I'm trying to use CRUD-add-on with Vaadin 14. But when I try to run this view:

@Route("configuration")
@JsModule("./styles/shared-styles.js")
@CssImport("./styles/views/main/main-view.css")
public class ConfigurationView extends AppLayout {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public ConfigurationView(YoloObjectService yoloObjectService, ObjectNameService objectNameService) {
        
        System.out.println(yoloObjectService == null);
        System.out.println(objectNameService == null);
        // crud instance
        GridCrud<YoloObjectEntity> crud = new GridCrud<>(YoloObjectEntity.class);

        // grid configuration
        crud.getGrid().setColumns("email", "active", "objectName", "threshold");
        crud.getGrid().setColumnReorderingAllowed(true);

        // form configuration
        crud.getCrudFormFactory().setUseBeanValidation(true);
        crud.getCrudFormFactory().setVisibleProperties("email", "active", "threshold", "objectName");
        crud.getCrudFormFactory().setFieldProvider("objectName", new ComboBoxProvider<>("Object Name", objectNameService.findAll(), new TextRenderer<>(ObjectNameEntity::getName), ObjectNameEntity::getName));

        // layout configuration
        setContent(crud);
        crud.setFindAllOperationVisible(false);

        // logic configuration
        crud.setOperations(() -> yoloObjectService.findAll(),
                user -> yoloObjectService.save(user),
                user -> yoloObjectService.save(user),
                user -> yoloObjectService.delete(user)
        );
    }
}

I get this error because of crud.getCrudFormFactory().setUseBeanValidation(true); above.

    Caused by: javax.validation.NoProviderFoundException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.
    at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:291) ~[validation-api-2.0.1.Final.jar:na]
    at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:103) ~[validation-api-2.0.1.Final.jar:na]
    ... 83 common frames omitted

2020-09-22 13:59:37.019 ERROR 10778 --- [nio-8080-exec-3] c.v.flow.server.DefaultErrorHandler      : 

java.lang.IllegalStateException: BeanValidationBinder cannot be used because a JSR-303 Bean Validation implementation not found on the classpath or could not be initialized. Use Binder instead
    at com.vaadin.flow.data.binder.BeanValidationBinder.<init>(BeanValidationBinder.java:85) ~[flow-data-2.3.4.jar:2.3.4]
    at com.vaadin.flow.data.binder.BeanValidationBinder.<init>(BeanValidationBinder.java:61) ~[flow-data-2.3.4.jar:2.3.4]

Here is my pom.xml file:

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example.application</groupId>
    <artifactId>my-project</artifactId>
    <name>My Project</name>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <vaadin.version>14.3.4</vaadin.version>
        <dl4j-master.version>1.0.0-beta7</dl4j-master.version>
        <sarxos.version>0.3.12</sarxos.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
    </parent>

    <repositories>
        <!-- The order of definitions matters. Explicitly defining central here 
            to make sure it has the highest priority. -->

        <!-- Main Maven repository -->
        <repository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <!-- Repository used by many Vaadin add-ons -->
        <repository>
            <id>Vaadin Directory</id>
            <url>https://maven.vaadin.com/vaadin-addons</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <!-- Main Maven repository -->
        <pluginRepository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-bom</artifactId>
                <version>${vaadin.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>com.vaadin</groupId>
            <!-- Replace artifactId with vaadin-core to use only free components -->
            <artifactId>vaadin</artifactId>
            <exclusions>
                <!-- Webjars are only needed when running in Vaadin 13 compatibility 
                    mode -->
                <exclusion>
                    <groupId>com.vaadin.webjar</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.insites</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymer</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.polymerelements</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.vaadin</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.webjars.bowergithub.webcomponents</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-spring-boot-starter</artifactId>
            <exclusions>
                <!-- Excluding so that webjars are not included. -->
                <exclusion>
                    <groupId>com.vaadin</groupId>
                    <artifactId>vaadin-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.vaadin.artur</groupId>
            <artifactId>a-vaadin-helper</artifactId>
            <version>1.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.vaadin</groupId>
            <artifactId>vaadin-testbench</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Projekt Lombok för att slippa Getters and Setters -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- For Detection with DL4J -->
        <dependency>
            <groupId>org.deeplearning4j</groupId>
            <artifactId>deeplearning4j-datasets</artifactId>
            <version>${dl4j-master.version}</version>
        </dependency>
        <dependency>
            <groupId>org.deeplearning4j</groupId>
            <artifactId>deeplearning4j-zoo</artifactId>
            <version>${dl4j-master.version}</version>
        </dependency>

        <!-- Camera -->
        <dependency>
            <groupId>com.github.sarxos</groupId>
            <artifactId>webcam-capture</artifactId>
            <version>${sarxos.version}</version>
        </dependency>

        <!-- CRUD -->
        <dependency>
            <groupId>org.vaadin.crudui</groupId>
            <artifactId>crudui</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
    </dependencies>

    <build>
        <defaultGoal>spring-boot:run</defaultGoal>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <!-- Clean build and startup time for Vaadin apps sometimes may exceed 
                    the default Spring Boot's 30sec timeout. -->
                <configuration>
                    <wait>500</wait>
                    <maxAttempts>240</maxAttempts>
                </configuration>
            </plugin>

            <!-- Take care of synchronizing java dependencies and imports in package.json 
                and main.js files. It also creates webpack.config.js if not exists yet. -->
            <plugin>
                <groupId>com.vaadin</groupId>
                <artifactId>vaadin-maven-plugin</artifactId>
                <version>${vaadin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>prepare-frontend</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <!-- Production mode is activated using -Pproduction -->
            <id>production</id>
            <properties>
                <vaadin.productionMode>true</vaadin.productionMode>
            </properties>

            <dependencies>
                <dependency>
                    <groupId>com.vaadin</groupId>
                    <artifactId>flow-server-production-mode</artifactId>
                </dependency>
            </dependencies>

            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <configuration>
                            <jvmArguments>-Dvaadin.productionMode</jvmArguments>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>com.vaadin</groupId>
                        <artifactId>vaadin-maven-plugin</artifactId>
                        <version>${vaadin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>build-frontend</goal>
                                </goals>
                                <phase>compile</phase>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>it</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.springframework.boot</groupId>
                        <artifactId>spring-boot-maven-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>start-spring-boot</id>
                                <phase>pre-integration-test</phase>
                                <goals>
                                    <goal>start</goal>
                                </goals>
                            </execution>
                            <execution>
                                <id>stop-spring-boot</id>
                                <phase>post-integration-test</phase>
                                <goals>
                                    <goal>stop</goal>
                                </goals>
                            </execution>
                        </executions>
                    </plugin>

                    <!-- Runs the integration tests (*IT) after the server is started -->
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                            </execution>
                        </executions>
                        <configuration>
                            <trimStackTrace>false</trimStackTrace>
                            <enableAssertions>true</enableAssertions>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

    </profiles>
</project>

Reproduce issue:

To reproduce the issue, run the project and then go to http://localhost:8080 then to the configuration tab and press + sign. Now you will have two errors about Bean Validation.

https://github.com/DanielMartensson/Vaadin-DL4J-YOLO-Camera-Mail-Reporter

Question:

How can I find this Bean Validator?

Detestable answered 22/9, 2020 at 12:13 Comment(0)
M
16

Jakarta Bean Validation (previously Java Bean Validation) is an API, you need to provide an implementation of it in order to be able to use it. There are two, Hibernate Validator, and Apache BVal. You can add any of these to your pom.xml file. Depending on your runtime environment, you add these in different ways. Since it seems you are using Spring Boot, you can add the following dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

I recommend you read this tutorial to quickly get a better understanding of Jakarta Bean Validation. It's a very popular API and it's very likely that you'll find it in other projects in the future.

Miguelinamiguelita answered 22/9, 2020 at 12:35 Comment(7)
That's weird beacuse I did not use that in this project. Your library is excellent by the way! github.com/DanielMartensson/OpenSourceLoggerDetestable
I guess you generated the project at start.vaadin.com which by default includes Spring Boot in the pom.xml file. And just to be clear, if you are referring to Jakarta Bean Validation, it's not my library. It is excellent indeed!Miguelinamiguelita
I just realized you were probably referring to the Crud-ui add-on. I'll shamelessly take the credit then :) Thanks for the feedback.Miguelinamiguelita
By the way! I did build a new project with latest Vaadin version and it seems that your library have some issues with that. The validation only shows errors at the terminal, not at the UI interface for the Crud AddOn.. #67063172Detestable
Yes. It doesn't support the latest version yet.Miguelinamiguelita
Erik Lume solved that issue for me. :) Also I have some suggestions for the next update. Can I write it here?Detestable
Daniel, if you mean a suggestion for Crud UI, you can report it at github.com/alejandro-du/crudui/issuesMiguelinamiguelita
H
7

As is explained in a tutorial, you need to have an actual implementation class of a Jakarta Bean Validator available. In the linked tutorial there are a list of available dependencies shown that you can use, depending on your environment. I recommend reading the whole tutorial anyway.

So if you have a Java EE environment, add this to your pom:

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.5.Final</version>  /* check for the latest version at https://hibernate.org/validator/documentation/getting-started/ */
</dependency>

If you have Spring Boot, try this one:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

And in case of Java SE, try this:

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.1.5.Final</version>  /* check for the latest version at https://hibernate.org/validator/documentation/getting-started/ */
</dependency>

<dependency>
    <groupId>org.glassfish</groupId>
    <artifactId>jakarta.el</artifactId>
    <version>3.0.3</version>
</dependency>
Harkins answered 22/9, 2020 at 12:30 Comment(4)
Good to hear! Btw, I see that Alejandro Duarte, who is the author of the linked tutorial, also just made an answer. May I ask that you award the "accepted answer" to him, as I basically just repeated his words. ;) cheersHarkins
Sure! I will do that.Detestable
There's no need to, really. @kscherrer, you where faster and that has its merit. Thanks anyway :)Miguelinamiguelita
@AlejandroDuarte I know, and yet this is a great way for me to pay my respects to you. Have a great day!Harkins

© 2022 - 2024 — McMap. All rights reserved.