Quarkus: SmallRye GraphQL and Hibernate Validator not works together in native

Created on 9 Dec 2020  路  12Comments  路  Source: quarkusio/quarkus

Describe the bug
add hibernate-validator and smallrye-graphql
Set quarkus.smallrye-graphql.validation.enabled to true
observe that hibernate validations doesnot runs and native app fails with exceptions

Expected behavior
Expect that 'smallrye-graphql' use 'hibernate-validator' and native app not fail

Actual behavior
hibernate validations not runs

To Reproduce

https://drive.google.com/file/d/1TzqBt3o7EYiK9l0jWba9SNBG2wkG-AgQ/view?usp=sharing

Steps to reproduce the behavior:

  1. add 'hibernate-validator' and 'smallrye-graphql'
  2. Set 'quarkus.smallrye-graphql.validation.enabled' to true
  3. Create entity and pass it to mutations
class RegistrationRequest {
    @NotNull @Email lateinit var email: String
    @NotNull lateinit var password: String
    @NotNull lateinit var fistName: String
    @NotNull lateinit var lastName: String
    @Pattern(regexp = "^\\+(?:[0-9] ?){6,14}[0-9]\$")
    var phone: String? = null
}
    @Mutation
    fun register(@NotNull request: RegistrationRequest): Person {
        return personService.register(request)
    }
  1. observe that hibernate validations does not runs and native app fails with exceptions

Configuration

quarkus:
  smallrye-graphql:
    validation:
      enabled: true

Screenshots

__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2020-12-09 15:18:20,355 INFO  [io.quarkus] (main) accounts 1.0.0-SNAPSHOT native (powered by Quarkus 1.10.3.Final) started in 0.026s. Listening on: http://0.0.0.0:8080
2020-12-09 15:18:20,355 INFO  [io.quarkus] (main) Profile prod activated. 
2020-12-09 15:18:20,355 INFO  [io.quarkus] (main) Installed features: [agroal, cdi, config-yaml, hibernate-validator, jdbc-postgresql, kotlin, mutiny, narayana-jta, security, smallrye-context-propagation, smallrye-graphql, smallrye-health, smallrye-jwt, vertx, vertx-web]
2020-12-09 15:18:26,489 ERROR [io.sma.graphql] (vert.x-worker-thread-0) SRGQL012000: Data Fetching Error: javax.validation.NoProviderFoundException: Unable to create a Configuration, because no Jakarta 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)
        at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:103)
        at io.smallrye.graphql.cdi.validation.ValidationService.beforeInvoke(ValidationService.java:28)
        at io.smallrye.graphql.execution.event.EventEmitter.fireBeforeMethodInvoke(EventEmitter.java:91)
        at io.smallrye.graphql.execution.datafetcher.helper.ReflectionHelper.invoke(ReflectionHelper.java:80)
        at io.smallrye.graphql.spi.datafetcher.DefaultWrapperHandlerService.invokeAndTransform(DefaultWrapperHandlerService.java:42)
        at io.smallrye.graphql.spi.datafetcher.AbstractWrapperHandlerService.getData(AbstractWrapperHandlerService.java:59)
        at io.smallrye.graphql.execution.datafetcher.PlugableDataFetcher.get(PlugableDataFetcher.java:34)
        at graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentation.lambda$instrumentDataFetcher$0(DataLoaderDispatcherInstrumentation.java:86)
        at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:270)
        at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:203)
        at graphql.execution.ExecutionStrategy.resolveField(ExecutionStrategy.java:177)
        at graphql.execution.AsyncSerialExecutionStrategy.lambda$execute$1(AsyncSerialExecutionStrategy.java:43)
        at graphql.execution.Async.eachSequentiallyImpl(Async.java:80)
        at graphql.execution.Async.eachSequentially(Async.java:69)
        at graphql.execution.AsyncSerialExecutionStrategy.execute(AsyncSerialExecutionStrategy.java:38)
        at graphql.execution.Execution.executeOperation(Execution.java:165)
        at graphql.execution.Execution.execute(Execution.java:104)
        at graphql.GraphQL.execute(GraphQL.java:557)
        at graphql.GraphQL.parseValidateAndExecute(GraphQL.java:482)
        at graphql.GraphQL.executeAsync(GraphQL.java:446)
        at graphql.GraphQL.execute(GraphQL.java:377)
        at io.smallrye.graphql.execution.ExecutionService.execute(ExecutionService.java:122)
        at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLExecutionHandler.doRequest(SmallRyeGraphQLExecutionHandler.java:169)
        at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLExecutionHandler.doRequest(SmallRyeGraphQLExecutionHandler.java:162)
        at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLExecutionHandler.handlePost(SmallRyeGraphQLExecutionHandler.java:105)
        at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLExecutionHandler.doHandle(SmallRyeGraphQLExecutionHandler.java:86)
        at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLExecutionHandler.handle(SmallRyeGraphQLExecutionHandler.java:63)
        at io.quarkus.smallrye.graphql.runtime.SmallRyeGraphQLExecutionHandler.handle(SmallRyeGraphQLExecutionHandler.java:36)
        at io.vertx.ext.web.impl.BlockingHandlerDecorator.lambda$handle$0(BlockingHandlerDecorator.java:48)
        at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$2(ContextImpl.java:313)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.lang.Thread.run(Thread.java:834)
        at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:519)
        at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:192)

Environment (please complete the following information):

  • Output of uname -a or ver: Linux andrii-PC 5.4.0-56-generic #62-Ubuntu SMP Mon Nov 23 19:20:19 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
  • Output of java -version:
openjdk 11.0.9 2020-10-20
OpenJDK Runtime Environment GraalVM CE 20.3.0 (build 11.0.9+10-jvmci-20.3-b06)
OpenJDK 64-Bit Server VM GraalVM CE 20.3.0 (build 11.0.9+10-jvmci-20.3-b06, mixed mode, sharing)
  • GraalVM version (if different from Java):
  • Quarkus version or git rev: 1.10.3
  • Build tool (ie. output of mvnw --version or gradlew --version):
------------------------------------------------------------
Gradle 6.5.1
------------------------------------------------------------

Build time:   2020-06-30 06:32:47 UTC
Revision:     66bc713f7169626a7f0134bf452abde51550ea0a

Kotlin:       1.3.72
Groovy:       2.5.11
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          11.0.9 (GraalVM Community 11.0.9+10-jvmci-20.3-b06)
OS:           Linux 5.4.0-56-generic amd64
aregraphql arehibernate-validator arekotlin aresmallrye kinbug

Most helpful comment

@phillip-kruger please add the backport label when you create the PR. I might release a 1.10.4.Final at some point.

All 12 comments

/cc @evanchooly, @gsmet, @jmartisk, @phillip-kruger

Small additional. Native app not fail on qurkus version 1.9.2

Hi @Andro999b - Thanks for this. So it does work fine in jvm mode ?

@phillip-kruger Yes JVM not fail with javax.validation.NoProviderFoundException. But i dont see that hibernate validations runs at at all. I see that smallrey-grapthql use @NotNull for schema generation. But other looks totally ignored.

Can you share your pom.xml ?

I am using gradle kotlin extension for this project:

plugins {
    val kotlinVersion = "1.3.72"
    kotlin("jvm") version kotlinVersion
    kotlin("plugin.allopen") version kotlinVersion
    kotlin("plugin.noarg") version kotlinVersion
    id("io.quarkus")
}

repositories {
    mavenLocal()
    mavenCentral()
}

val quarkusPlatformGroupId: String by project
val quarkusPlatformArtifactId: String by project
val quarkusPlatformVersion: String by project

dependencies {
    implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
    implementation("io.quarkus:quarkus-hibernate-validator")
    implementation("io.quarkus:quarkus-config-yaml")
    implementation("io.quarkus:quarkus-smallrye-jwt")
    implementation("io.quarkus:quarkus-smallrye-health")
    implementation("io.quarkus:quarkus-kotlin")
    implementation("io.quarkus:quarkus-smallrye-graphql")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("io.quarkus:quarkus-arc")
    testImplementation("io.quarkus:quarkus-junit5")
}

group = "com.letsgo"
version = "1.0.0-SNAPSHOT"

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

quarkus {
    setOutputDirectory("$projectDir/build/classes/kotlin/main")
}

tasks.withType<io.quarkus.gradle.tasks.QuarkusDev> {
    setSourceDir("$projectDir/src/main/kotlin")
}

allOpen {
    annotation("javax.ws.rs.Path")
    annotation("javax.enterprise.context.ApplicationScoped")
    annotation("io.quarkus.test.junit.QuarkusTest")
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions.jvmTarget = JavaVersion.VERSION_11.toString()
    kotlinOptions.javaParameters = true
}

also theris a link in description on archive with small project to reproduce this.

Thanks. I will look at this a.s.a.p

@phillip-kruger on Quarkus, you shouldn't build a ValidatorFactory yourself. You need to use either the Validator or the ValidatorFactory created by the HV extension.

You can get them via CDI injection: they are proper beans.

@gsmet - Thanks for the tip. I'll have a look a.s.a.p

Ok I have changed the smallrye code to do a lookup rather than building it. see https://github.com/smallrye/smallrye-graphql/pull/565

I will release a new version of SmallRye and pull it into Quarkus

Thanks @phillip-kruger!

@phillip-kruger please add the backport label when you create the PR. I might release a 1.10.4.Final at some point.

Was this page helpful?
0 / 5 - 0 ratings