У меня довольно простое приложение Spring Boot. Один файл yaml с конфигурациями шлюза Spring, а затем один файл с основным классом приложения и основной функцией.
Я создаю файл jar следующим образом:
./gradlew clean bootJar -x test
Строится без проблем.
Файл build.gradle.kts выглядит следующим образом:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "3.3.2"
id("io.spring.dependency-management") version "1.1.6"
kotlin("jvm") version "1.9.24"
kotlin("plugin.spring") version "1.9.24"
application
}
application {
mainClass.set("com.example.reverseproxy.ReverseProxyApplicationKt")
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_17
}
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
extra["springCloudVersion"] = "2023.0.3"
dependencies {
/* kotlin co-routines */
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
/* kotlin reflection */
implementation("org.jetbrains.kotlin:kotlin-reflect")
/* spring web */
// implementation("org.springframework.boot:spring-boot-starter-webflux")
/* spring cloud gateway */
implementation("org.springframework.cloud:spring-cloud-starter-gateway")
implementation("org.springframework.boot:spring-boot-starter-actuator")
/* test - dependencies */
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
// testImplementation("io.projectreactor:reactor-test")
// testRuntimeOnly("org.junit.platform:junit-platform-launcher")
// implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation(kotlin("stdlib-jdk8"))
}
dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "17"
}
}
tasks.withType<Test> {
enabled = false
useJUnitPlatform()
}
tasks.withType<Jar> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes["Main-Class"] = "com.example.reverseproxy.ReverseProxyApplicationKt"
}
archiveBaseName.set("ReverseProxy")
archiveVersion.set("0.0.1-SNAPSHOT")
from(sourceSets.main.get().output)
// Include dependencies in the JAR file
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get()
.filter { it.name.endsWith("jar") }
.map { zipTree(it) }
})
// exclude specific signed files from being included in the final JAR
exclude("META-INF/*.SF")
exclude("META-INF/*.DSA")
exclude("META-INF/*.RSA")
}
tasks.named("bootJar") {
dependsOn("jar")
}
tasks.named("bootJar") {
mustRunAfter("jar")
}
tasks.named("bootDistZip") {
dependsOn("jar")
}
tasks.named("bootDistZip") {
mustRunAfter("jar")
}
tasks.named("bootDistTar") {
dependsOn("jar")
}
tasks.named("bootDistTar") {
mustRunAfter("jar")
}
tasks.named("startScripts") {
dependsOn("bootJar")
}
tasks.named("startScripts") {
mustRunAfter("bootJar")
}
Однако, когда я запускаю это
java -jar build/libs/ReverseProxy-0.0.1-SNAPSHOT.jar
Я продолжаю получать:
19:35:51.003 [main] WARN org.springframework.context.annotation.AnnotationConfigApplicationContext -- Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'httpClientSslConfigurer' defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration$NettyConfiguration.class]: Unsatisfied dependency expressed through method 'httpClientSslConfigurer' parameter 0: No qualifying bean of type 'org.springframework.boot.autoconfigure.web.ServerProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
19:35:51.006 [main] ERROR org.springframework.boot.SpringApplication -- Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'httpClientSslConfigurer' defined in class path resource [org/springframework/cloud/gateway/config/GatewayAutoConfiguration$NettyConfiguration.class]: Unsatisfied dependency expressed through method 'httpClientSslConfigurer' parameter 0: No qualifying bean of type 'org.springframework.boot.autoconfigure.web.ServerProperties' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Я не совсем уверен, где я ошибаюсь?
Может ли кто-нибудь помочь?
Репо (минимально воспроизводимый пример):
https://github.com/dreamstar-enterprises/docs/tree/master/Spring%20BFF/ReverseProxy
ОБНОВЛЯТЬ
Ниже не помогло. Есть идеи?
// ensure that both compiled classes and resources are included in the JAR file
from(sourceSets.main.get().output)
sourceSets.main.configure {
resources.srcDirs("src/main").includes.addAll(arrayOf("**/*.*"))
}
ОБНОВЛЕНИЕ 2
Если я закомментирую это из файла Gradle,
implementation("org.springframework.cloud:spring-cloud-starter-gateway")
Оно работает. Единственная проблема в том, что, поскольку это обратный прокси-сервер, мне очень нужна его зависимость.
Вы не включаете ресурсы в банку. Включая только основной исходный набор -
from(sourceSets.main.get().output)
Обратитесь к этому Добавьте файлы в исходные наборы Gradle в Kotlin DSL
Сообщение «Нет подходящего bean-компонента типа org.springframework.boot.autoconfigure.web.ServerProperties» указывает на то, что bean-компонент ServerProperties
@ConfigurationProperties
не был создан. Для реактивных приложений его обычно создает ReactiveWebServerFactoryAutoConfiguration
.
Судя по предоставленному вами образцу, проблема, похоже, вызвана вашим необычным build.gradle.kts
файлом.
Обычно для проверки того, почему не была применена автоконфигурация. Я бы использовал -Ddebug
, однако ваша банка неправильно упакована, поэтому это не работает.
Если вы запустите unzip -l build/libs/ReverseProxy-0.0.1-SNAPSHOT.jar
с вашим текущим приложением, вы увидите, что оно содержит как файлы .class
, так и .jar
из Spring. Это основная причина вашей проблемы.
Чтобы это исправить, вы можете удалить src/main/resources/META-INF/MANIFEST.MF
и упростить build.gradle.kts
файл до следующего:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "3.3.2"
id("io.spring.dependency-management") version "1.1.6"
kotlin("jvm") version "1.9.24"
kotlin("plugin.spring") version "1.9.24"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java {
sourceCompatibility = JavaVersion.VERSION_17
}
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
extra["springCloudVersion"] = "2023.0.3"
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.springframework.boot:spring-boot-autoconfigure")
implementation("org.springframework.cloud:spring-cloud-starter-gateway")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation(kotlin("stdlib-jdk8"))
}
dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:${property("springCloudVersion")}")
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xjsr305=strict"
jvmTarget = "17"
}
}
С этими изменениями банка выглядит нормально и будет работать.