Error creating bean with name 'requestMappingHandlerMapping' with kotlin suspend function in spring-boot - spring-boot

spring-boot version : 2.2.6.RELEASE
kotlin version: 1.3.71
kotlin coroutine version: 1.3.5
I'm trying to used suspended function in a controller in spring boot. Here is the official doc that shows an example.
#RestController
#RequestMapping("/account/v1")
class UserAccountResourceV1 {
#GetMapping("/username-taken", produces = [MediaType.TEXT_PLAIN_VALUE])
suspend fun userNameTaken(): String {
return "yes"
}
}
I've added required dependencies in build.gradle.kts:
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-jersey")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
developmentOnly("org.springframework.boot:spring-boot-devtools")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(group = "org.junit.vintage", module = "junit-vintage-engine")
}
implementation(group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version = "1.3.2")
}
It breaks in runtime throwing this err:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Unsupported suspending handler method detected: public java.lang.Object com.example.user.service.resources.UserAccountResourceV1.userNameTaken(kotlin.coroutines.Continuation)
complete stderr is here.
Need some help in figuring out what is wrong with my implementation.

Figured out the solution.
implementation("org.springframework.boot:spring-boot-starter-web")
needed to be replaced with
implementation("org.springframework.boot:spring-boot-starter-webflux")
Basically spring-boot-starter-webflux brings support for suspened functions.

Related

GraphQLName annotation

I am creating a simple login app using spring boot with Kotlin + GraphQL. #GraphQLName("") is not working for me.
my graphql is
schema {
query: Query
mutation: Mutation
}
type Mutation{
requestOTP(credential: String!,authType: String!): String
}
and in my kotlin
#Controller
class ResetPassword(
#Autowired val userRepository: UserRepository
): GraphQLMutationResolver {
#GraphQLName("requestOTP")
fun reset(credential: String, authType: String): String{
//codes...
}
}
But It keep saying
Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message:
Error creating bean with name 'graphQLServletRegistrationBean' defined in class path resource [graphql/kickstart/autoconfigure/web/servlet/GraphQLWebAutoConfiguration.class]: Unsatisfied dependency expressed through method 'graphQLServletRegistrationBean' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'graphQLHttpServlet' defined in class path resource [graphql/kickstart/autoconfigure/web/servlet/GraphQLWebAutoConfiguration.class]: Unsatisfied dependency expressed through method 'graphQLHttpServlet' parameter 0;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'graphQLServletConfiguration' defined in class path resource [graphql/kickstart/autoconfigure/web/servlet/GraphQLWebAutoConfiguration.class]: Unsatisfied dependency expressed through method 'graphQLServletConfiguration' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'invocationInputFactory' defined in class path resource [graphql/kickstart/autoconfigure/web/servlet/GraphQLWebAutoConfiguration.class]:
Unsatisfied dependency expressed through method 'invocationInputFactory' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'graphQLSchemaProvider' defined in class path resource [graphql/kickstart/autoconfigure/web/servlet/GraphQLWebAutoConfiguration.class]:
Unsatisfied dependency expressed through method 'graphQLSchemaProvider' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'graphQLSchema' defined in class path resource [graphql/kickstart/autoconfigure/tools/GraphQLJavaToolsAutoConfiguration.class]: Unsatisfied dependency expressed through method 'graphQLSchema' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'schemaParser' defined in class path resource [graphql/kickstart/autoconfigure/tools/GraphQLJavaToolsAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [graphql.kickstart.tools.SchemaParser]: Factory method 'schemaParser' threw exception; nested exception is graphql.kickstart.tools.resolver.FieldResolverError: No method found as defined in schema <unknown>:44 with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment, class graphql.GraphQLContext] as the last argument), in priority order:
com.auth.test.presentation.ResetPassword.requestOTP(~credential, ~authType)
com.auth.test.presentation.ResetPassword.getRequestOTP(~credential, ~authType)
If I rename fun reset to fun requestOTP, the code compile even I put #GraphQLName("LOLnothingLOL")
. Kindly explain me why I am getting this error and how to fix it. I don't want to use requestOTP directly to have more readability.
Edit:
I am not using pom.xml instead build.gradle
Here is my gradle file.
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "2.7.6"
id("io.spring.dependency-management") version "1.1.0"
kotlin("jvm") version "1.7.21"
kotlin("plugin.spring") version "1.7.21"
kotlin("plugin.jpa") version "1.7.21"
}
group = "com.dagger"
version = "0.0.1"
java.sourceCompatibility = JavaVersion.VERSION_11
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-graphql")
implementation("com.graphql-java-kickstart:graphql-spring-boot-starter:14.1.0")
runtimeOnly("com.graphql-java-kickstart:graphiql-spring-boot-starter:11.1.0")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation ("org.springframework.boot:spring-boot-starter-log4j2")
modules {
module("org.springframework.boot:spring-boot-starter-logging") {
replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback")
}
}
//jwt token
implementation ("io.jsonwebtoken:jjwt:0.9.1")
implementation("com.expedia.graphql:graphql-kotlin-schema-generator:1.3.4")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.springframework.session:spring-session-core")
runtimeOnly("com.mysql:mysql-connector-j")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework:spring-webflux")
testImplementation("org.springframework.graphql:spring-graphql-test")
testImplementation("org.springframework.security:spring-security-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "11"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
Let's try to understand the issue.
Unsatisfied dependency expressed through method 'graphQLSchemaProvider' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'graphQLSchema' defined in class path resource [graphql/kickstart/autoconfigure/tools/GraphQLJavaToolsAutoConfiguration.class]: Unsatisfied dependency expressed through method 'graphQLSchema' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'schemaParser' defined in class path resource [graphql/kickstart/autoconfigure/tools/GraphQLJavaToolsAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [graphql.kickstart.tools.SchemaParser]: Factory method 'schemaParser' threw exception; nested exception is graphql.kickstart.tools.resolver.FieldResolverError: No method found as defined in schema <unknown>:44 with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment, class graphql.GraphQLContext] as the last argument), in priority order:
In above error message if you notice last statement, issue is very clear.
nested exception is graphql.kickstart.tools.resolver.FieldResolverError: No method found as defined in schema <unknown>:44 with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment, class graphql.GraphQLContext] as the last argument), in priority order:
So the issue is, in your Controller class, Mutation method name is reset() but in GraphQl schema file method name is requestOTP(). Both should be same.
schema {
query: Query
mutation: Mutation
}
type Mutation{
requestOTP(credential: String!,authType: String!): String
}
Also I can see you are using org.springframework.boot:spring-boot-starter-graphql dependency in your build.gradle file. This dependency is enough for GraphQL implementation with Spring Boot. Please remove other GraphQL related dependencies. They are creating confusion in Spring ECO system.
Also if you writing GraphQL schema file yourself then no need to use #GraphQLName annotation.

Error creating bean with name org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration (Using Gradle)

Building jar file works through the terminal computer path % ./gradlew build, and application runs computer path % java -jar name.jar.
Why not through IntelliJ?
*Secondary Issue -
When I try to upload the jar file built through the terminal to AWS Beanstalk I get a validation error.
*Primary Issue -
The application runs in IntelliJ.
After I have completed the Project Structure setup, and the Build Artifacts execution. The new .jar file fails to run,
throwing the exception below.
Error creating bean with name 'org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.zaxxer.hikari.HikariDataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class
build.gradle:
plugins {
id 'org.springframework.boot' version '2.6.2'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'application'
}
group = 'com.example'
version = 'api'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
runtimeOnly 'mysql:mysql-connector-java'
}
test {
useJUnitPlatform()
}
mainClassName = 'com.example.name.applicationame'
task fatJar(type: Jar) {
bootJar {
launchScript()
}
manifest {
attributes 'Main-Class': "${mainClassName}"
duplicatesStrategy = 'include'
}
archiveBaseName = "name"
from { configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
with jar
}
application.properties:
spring.datasource.url=jdbc:mysql://localhost:3306/name?useSSL=true
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
Thanks!

spring-cloud-stream sample projects raises NoSuchBeanDefinitionException of KafkaStreamsFunctionProcessor

I'm trying to touch spring-cloud-stream, and creating a sample project of the official blog.
Implementation is totally same as the article.
#SpringBootApplication
public class SimpleConsumerApplication {
#Bean
public java.util.function.Consumer<KStream<String, String>> process() {
return input ->
input.foreach((key, value) -> {
System.out.println("Key: " + key + " Value: " + value);
});
}
}
I've selected Cloud Stream and Spring for Apache Kafka Stream on Spring initializr, and added ShadowJar. Now my build.gradle is like this.
plugins {
id 'org.springframework.boot' version '2.4.4'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
id 'com.github.johnrengelman.shadow' version '6.1.0'
}
group = 'com.lipsum'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
jar {
manifest {
attributes('Main-Class': 'com.lipsum.kafkastream.KafkastreamApplication')
}
}
shadowJar {
archiveBaseName.set('kafka-stream-practice')
archiveClassifier.set('')
archiveVersion.set('')
}
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2020.0.2")
}
dependencies {
implementation 'org.apache.kafka:kafka-streams'
implementation 'org.springframework.cloud:spring-cloud-stream'
implementation 'org.springframework.cloud:spring-cloud-stream-binder-kafka-streams'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
test {
useJUnitPlatform()
}
I execute the uber jar, but springboot application fails to recognize the bean.
$ java -jar kafka-stream-practice.jar --spring.cloud.stream.bindings.process-in-0.destination=kafka-stream-practice
...
22:47:21.162 [main] ERROR org.springframework.boot.SpringApplication - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'kafkaStreamsFunctionProcessorInvoker' defined in class path resource [org/springframework/cloud/stream/binder/kafka/streams/function/KafkaStreamsFunctionAutoConfiguration.class]: Unsatisfied dependency expressed through method 'kafkaStreamsFunctionProcessorInvoker' parameter 1; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.stream.binder.kafka.streams.KafkaStreamsFunctionProcessor' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.stream.binder.kafka.streams.KafkaStreamsFunctionProcessor' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
I don't think the implementation has any problems. Do I miss some dependencies?
I tried a quick maven project from the initialize and it starts fine. There was a known bug on the last release (3.0.11) which was fixed since then on the snapshot. You can fix the issue by adding the boot actuator dependency to the project or by upgrading the binder to the latest snapshot. Could you try the maven approach? If the problem still persists, please share a reproducible sample, and then we will take a look.
It works after removing shadowJar and instead uses bootJar task of Spring Boot Gradle plugin.

Quarkus - Unsatisfied dependency for type org.eclipse.microprofile.jwt

I was trying to implement the JWT token for one my Quarkus application but somehow getting an exception - Unsatisfied dependency for type org.eclipse.microprofile.jwt.JsonWebToken and qualifiers [#Default]
My Quarkus application is fairly simple and having one rest endpoint -
#Path("/jwt")
#RequestScoped
public class JWTRestController {
#Inject
JsonWebToken jwt;
#GET()
#Path("permit-all")
#PermitAll
#Produces(MediaType.TEXT_PLAIN)
public String hello(#Context SecurityContext ctx) {
Principal caller = ctx.getUserPrincipal();
String name = caller == null ? "anonymous" : caller.getName();
String helloReply = String.format("hello + %s, isSecure: %s, authScheme: %s", name, ctx.isSecure(), ctx.getAuthenticationScheme());
return helloReply;
}
}
But when i try to run my quarkus application -
gradlew quarkusDev
Log stacktrace
> Task :quarkusDev
Port 5005 in use, not starting in debug mode
2020-04-05 15:57:49,789 INFO [org.jbo.threads] (main) JBoss Threads version 3.0.1.Final
2020-04-05 15:57:50,158 ERROR [io.qua.dev.DevModeMain] (main) Failed to start Quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.arc.deployment.ArcProcessor#validate threw an exception: javax.enterprise.inject.spi.DeploymentException: javax.enterprise.inject.UnsatisfiedResolutionException: Unsatisfied dependency for type org.eclipse.microprofile.jwt.JsonWebToken and qual
ifiers [#Default]
- java member: com.jhooq.JWTRestController#jwt
- declared on CLASS bean [types=[com.jhooq.JWTRestController, java.lang.Object], qualifiers=[#Default, #Any], target=com.jhooq.JWTRestController]
at io.quarkus.arc.processor.BeanDeployment.processErrors(BeanDeployment.java:910)
at io.quarkus.arc.processor.BeanDeployment.init(BeanDeployment.java:232)
at io.quarkus.arc.processor.BeanProcessor.initialize(BeanProcessor.java:130)
at io.quarkus.arc.deployment.ArcProcessor.validate(ArcProcessor.java:291)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
Am i really missing something here?
Here is my build.gradle
plugins {
id 'java'
id 'io.quarkus'
}
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
implementation enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}")
implementation 'io.quarkus:quarkus-resteasy'
testImplementation 'io.quarkus:quarkus-junit5'
testImplementation 'io.rest-assured:rest-assured'
testImplementation 'io.quarkus:quarkus-smallrye-jwt'
testImplementation 'io.quarkus:quarkus-resteasy-jsonb'
implementation 'org.eclipse.microprofile.jwt:microprofile-jwt-auth-api:1.1.1'
}
group 'com.jhooq'
version '1.0.0-SNAPSHOT'
compileJava {
options.compilerArgs << '-parameters'
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
The problem lies here:
testImplementation 'io.quarkus:quarkus-smallrye-jwt'
testImplementation 'io.quarkus:quarkus-resteasy-jsonb'
implementation 'org.eclipse.microprofile.jwt:microprofile-jwt-auth-api:1.1.1'
The quarkus-smallrye-jwt and quarkus-resteasy-jsonb dependencies are part of the application, not part of tests. These must be implementation, not testImplementation.
At the same time, you can remove implementation 'org.eclipse.microprofile.jwt:microprofile-jwt-auth-api:1.1.1', this it's brought in transitively by quarkus-smallrye-jwt.

Quarkus dependency injection failing with bean from Gradle Library Module

I´m trying to get dependency injection working in my multi-module project where I want to inject a bean from a library module. However, it´s failing because it cannot find the bean.
project root settings.gradle
pluginManagement {
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
}
plugins {
id 'io.quarkus' version "${quarkusPluginVersion}"
}
}
include ':service-module'
include ':library-module'
service-module build.gradle
Tried compile, as well as implementation
dependencies {
compile project(":library-module")
// implementation project(":library-module")
}
Bean from library-module
import javax.enterprise.context.ApplicationScoped;
#ApplicationScoped
public class LibraryBean {
public void hello() {
System.out.println("Hello");
}
}
service-module where injection happens
#ApplicationScoped
public class Application {
#Inject
LibraryBean libraryBean;
}
Stacktrace
Unsatisfied dependency for type com.mylibrary.LibraryBean and
qualifiers [#Default]
- java member: com.myservice.Application#LibraryBean
- declared on CLASS bean [types=[com.myservice.Application, java.lang.Object], qualifiers=[#Default, #Any],
target=com.myservice.Application]
I´m not sure if this issue is Quarkus-related or a general problem that exists with CDI and Gradle modules.
How can I make the DI working accross modules?
Do you have a beans.xml file in your library module? See this question/answer for more info: https://stackoverflow.com/a/55513723/742081

Resources