ani
ani

Reputation: 11

multi-module bean not found

I am developing a service by combining Kotlin, Spring Boot, multi-module, and hexagonal architecture.

While implementing the login logic, I encountered the following error:

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 1 of constructor in shop.hyeonme.global.jwt.JwtAdapter required a bean of type 'shop.hyeonme.domain.auth.spi.RefreshTokenPort' that could not be found.


Action:

Consider defining a bean of type 'shop.hyeonme.domain.auth.spi.RefreshTokenPort' in your configuration.

directory structure and files:

|- me
    |- me-api
        |- build.gradle.kts
        |- src
            |- main
                |- kotlin
                    |- shop
                        |- hyeonme
                            |- MeServerApplication.kt
                            |- domain
                                |- auth
                                    |- model
                                        |- RefreshToken.kt
                                    |- spi
                                        |- JwtPort.kt
                                        |- CommandRefreshTokenPort.kt
                                        |- RefreshTokenPort.kt
                            |- global
                                |- jwt
                                    |- JwtAdapter.kt
                                    |- properties
                                        |- JwtProperties.kt
                                |- config
                                    |- ComponentScanConfig.kt
    |- me-domain
        |- build.gradle.kts
        |- src
            |- main
                |- kotlin
                    |- shop
                        |- hyeonme
                            |- domain
                                |- auth
                                    |- entity
                                        |- RefreshTokenEntity.kt
                                    |- repository
                                        |- RefreshTokenRepository.kt
                                    |- RefreshTokenPersistenceAdapter.kt
package shop.hyeonme.domain.auth.spi

import shop.hyeonme.domain.auth.model.RefreshToken


interface CommandRefreshTokenPort {
    fun saveRefreshToken(refreshToken: RefreshToken): RefreshToken
}
package shop.hyeonme.domain.auth.spi

interface RefreshTokenPort : CommandRefreshTokenPort
package shop.hyeonme.domain.auth

import org.springframework.stereotype.Component
import shop.hyeonme.domain.auth.mapper.toEntity
import shop.hyeonme.domain.auth.mapper.toModel
import shop.hyeonme.domain.auth.model.RefreshToken
import shop.hyeonme.domain.auth.repository.RefreshTokenRepository
import shop.hyeonme.domain.auth.spi.RefreshTokenPort

@Component
class RefreshTokenPersistenceAdapter(
    private val refreshTokenRepository: RefreshTokenRepository
) : RefreshTokenPort {
    override fun saveRefreshToken(refreshToken: RefreshToken): RefreshToken =
        refreshTokenRepository.save(refreshToken.toEntity()).toModel()
}
package shop.hyeonme.global.config

import org.springframework.context.annotation.ComponentScan.Filter
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.FilterType
import shop.hyeonme.common.annotation.*

@Configuration
@ComponentScan(
    basePackages = ["shop.hyeonme"],
    includeFilters = [
        Filter(
            type = FilterType.ANNOTATION,
            classes = [
                UseCase::class,
                ReadOnlyUseCase::class,
                Service::class,
                QueryService::class,
                CommandService::class
            ]
        )
    ]
)
class ComponentScanConfig

me- api build.gradle.kts

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-validation")
    implementation("org.springframework.boot:spring-boot-starter-security")
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")

    annotationProcessor("org.springframework.boot:spring-boot-configuration-processor")
    kapt("org.springframework.boot:spring-boot-configuration-processor")

    runtimeOnly ("com.mysql:mysql-connector-j")

    implementation("io.jsonwebtoken:jjwt-api:0.11.2")
    runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.2")
    runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.2")

    implementation(kotlin("stdlib-jdk8"))
}

kapt {
    arguments {
        arg("mapstruct.defaultComponentModel", "spring")
        arg("mapstruct.unmappedTargetPolicy", "ignore")
    }
}

me-domain build.gradle.kts

import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
    kotlin("plugin.jpa") version "1.8.10"
    kotlin("plugin.spring") version "1.8.10"
}

val jar: Jar by tasks
val bootJar: BootJar by tasks

jar.enabled = true
bootJar.enabled = false

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-data-jpa")
    implementation("org.springframework.boot:spring-boot-starter-data-redis:2.7.5")
    runtimeOnly ("com.mysql:mysql-connector-j")

    implementation("com.querydsl:querydsl-jpa:5.0.0")
    kapt("com.querydsl:querydsl-apt:5.0.0:jpa")

    implementation(project(":me-api"))
}

allOpen {
    annotation("javax.persistence.Entity")
    annotation("javax.persistence.MappedSuperclass")
    annotation("javax.persistence.Embeddable")
}

noArg {
    annotation("javax.persistence.Entity")
    annotation("javax.persistence.MappedSuperclass")
    annotation("javax.persistence.Embeddable")
}

I made numerous attempts, such as changing the directory structure and renaming files, but 'me-api' couldn't retrieve the bean from 'me-domain'.

Upvotes: 1

Views: 88

Answers (0)

Related Questions