После обновления с Spring Boot 2.0.6
/ Spring Cloud Finchley.RELEASE
до Spring Boot 2.1.3
/ Spring Cloud Greenwich.SR1
возникла очень странная проблема конфигурации / сканирования компонентов.
Приложение имеет следующую структуру:
- основного приложения
- сообщениями Пб
- Обще Пб
Основное приложение помечено @SpringBootApplication(scanBasePackages = {"com.app.libs", "com.app"})
, где пакеты com.app
соответствуют пакетам main-application
, а com.app.libs
- пакеты библиотек.
Конфигурация commons-lib
, которая является просто библиотекой framework-esque, имеет следующую основную точку входа в конфигурацию:
package com.app.libs.commons
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(CommonsConfiguration.class)
public @interface EnableCommons {
}
С CommonsConfiguration
, имеющим:
package com.app.libs.commons.config
@Configuration
@ConditionalOnProperty(value = "com.app.config.commons", matchIfMissing = true)
@ComponentScan(basePackages = "com.app.libs.commons")
public class FrameworkConfiguration {
Таким образом, я могу в основном аннотировать один класс конфигурации в моем main-application
и получать от него общие компоненты.
Конфигурация messaging-lib
, которая использует Spring Cloud Stream, имеет следующие конфигурации:
@Configuration
@Import({ CustomBinding.class })
@PropertySource("classpath:kafka.properties")
@EnableBinding(Source.class)
@EnableAutoConfiguration
public class BindingConfiguration {
}
Конфигурация облачного потока выглядит следующим образом:
spring.cloud.stream.bindings.output.destination=${spring.application.name}
spring.cloud.stream.kafka.bindings.output.producer.sync=true
spring.cloud.stream.default.group=${spring.application.name}
spring.cloud.stream.default.producer.partitionCount=9
spring.cloud.stream.default.producer.partitionKeyExpression=headers.entityId
spring.cloud.stream.kafka.binder.autoAddPartitions=true
spring.cloud.stream.kafka.binder.autoCreateTopics=false
При запуске приложения выдается следующее сообщение об ошибке:
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under 'spring.cloud.stream.default.producer.partition-key-expression' to org.springframework.expression.Expression:
Property: spring.cloud.stream.default.producer.partitionkeyexpression
Value: headers.entityId
Origin: "spring.cloud.stream.default.producer.partitionKeyExpression" from property source "class path resource [kafka.properties]"
Reason: No converter found capable of converting from type [java.lang.String] to type [@com.fasterxml.jackson.databind.annotation.JsonSerialize org.springframework.expression.Expression]
Action:
Update your application's configuration
После просмотра исходного кода я заметил, что рассматриваемый SpelConverter
- это тот, который должен быть инициализирован в SpelExpressionConverterConfiguration
. Действительно, если я добавлю @Import({ SpelExpressionConverterConfiguration.class })
или @Import({ BindingServiceConfiguration })
(класс @Configuration
, который импортирует SpelExpressionConverterConfiguration
) к моему BindingConfiguration
, преобразователь, похоже, инициализируется. Однако тогда возникает другая ошибка:
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean of type 'org.springframework.messaging.core.DestinationResolver' that could not be found.
The following candidates were found but could not be injected:
- Bean method 'binderAwareChannelResolver' in 'BindingServiceConfiguration' not loaded because @ConditionalOnBean (types: org.springframework.cloud.stream.binder.BinderTypeRegistry; SearchStrategy: current) did not find any beans of type org.springframework.cloud.stream.binder.BinderTypeRegistry
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.messaging.core.DestinationResolver' in your configuration.
Я не совсем уверен, что происходит. При отладке кажется, что загружены и BindingBeansRegistrar
, и BinderFactoryConfiguration
(классы, импортированные с помощью @EnableBinding
), но сканирование не выполняется, а сканирование остальных компонентов просто не выполняется.
Я пытался импортировать классы конфигурации и / или сканировать пакеты самостоятельно, но в обоих случаях мне все еще не хватает компонента DestinationResolver
, хотя он должен был быть инициализирован.
Я заметил, что до обновления также были некоторые проблемы: мне пришлось импортировать BindingServiceConfiguration
, BinderFactoryConfiguration
и SpelExpressionConverterConfiguration
также вручную.
У кого-нибудь есть указания относительно того, что может быть причиной этой проблемы?
РЕДАКТИРОВАТЬ : Вот файлы build.grade
(некоторые из них для краткости опущены):
Заявка build.gradle
apply from: new File(project(':scripts').projectDir, '/service-impl.gradle')
dependencies {
implementation project(':dependency-A')
implementation project(':dependency-B')
implementation project(':messaging-library')
testImplementation 'org.springframework.cloud:spring-cloud-stream-test-support'
}
service-impl.gradle
содержание:
buildscript {
apply from: new File(project(':buildscripts').projectDir, '/repositories.gradle') // Repository definitions
apply from: new File(project(':buildscripts').projectDir, '/dm-boot.gradle') // DM via spring boot plugin
apply from: new File(project(':buildscripts').projectDir, '/dm-versions.gradle') // DM versions
}
configurations {
all*.exclude module: 'spring-boot-starter-tomcat'
all*.exclude group: 'org.apache.bval'
}
artifacts {
archives bootJar
}
dependencies {
compileOnly 'org.projectlombok:lombok'
compile 'org.springframework.boot:spring-boot-starter'
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-jetty'
compile 'org.springframework.boot:spring-boot-starter-actuator'
compile 'org.springframework.boot:spring-boot-starter-cache'
compile 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
compile 'org.springframework.cloud:spring-cloud-starter-config'
testCompile 'junit:junit'
testCompile 'org.springframework.boot:spring-boot-starter-test'
testCompileOnly 'org.projectlombok:lombok'
compile 'net.logstash.logback:logstash-logback-encoder'
}
Библиотека общин build.gradle
apply from: new File(project(':buildscripts').projectDir, '/repositories.gradle') // Repository definitions
apply from: new File(project(':buildscripts').projectDir, '/dm-plain.gradle') // DM via spring boot plugin
apply from: new File(project(':buildscripts').projectDir, '/dm-versions.gradle') // DM versions
dependencies {
api 'com.restfb:restfb:2.3.0'
api 'commons-io:commons-io'
implementation 'com.jcraft:jsch:0.1.54'
//lombok
compileOnly 'org.projectlombok:lombok'
//spring
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-jetty'
implementation 'org.springframework.boot:spring-boot-starter-security'
api 'org.springframework.security:spring-security-core'
api 'org.springframework.security:spring-security-web'
api 'org.springframework:spring-jdbc'
api 'org.springframework.boot:spring-boot-starter-actuator'
//thrift modules
compileOnly 'com.facebook.swift:swift-codec'
compileOnly 'com.facebook.swift:swift-service'
//db modules
api 'org.postgresql:postgresql'
api 'org.flywaydb:flyway-core'
api 'com.zaxxer:HikariCP'
api 'org.jooq:jooq'
//embedded pg modules
compileOnly 'com.opentable.components:otj-pg-embedded'
api group: 'net.minidev', name: 'json-smart', version: '2.2.1'
api group: 'org.json', name: 'json', version: '20140107'
//tests
testImplementation 'junit:junit'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'com.opentable.components:otj-pg-embedded'
testImplementation 'org.springframework.security:spring-security-core'
testImplementation 'org.springframework.security:spring-security-web'
testImplementation 'org.springframework.security:spring-security-config'
testImplementation 'org.springframework:spring-jdbc'
testImplementation 'org.springframework.boot:spring-boot-starter-actuator'
testImplementation 'org.apache.sshd:sshd-core:1.7.0' // sftpFileTransfer testing - embedded sftp server
testCompileOnly 'org.projectlombok:lombok'
testCompileOnly 'javax.servlet:javax.servlet-api'
}
Messaging Lib build.gradle
(используется как автономная библиотека, поэтому не использует вышеуказанные .gradle
файлы)
buildscript {
ext {
springBootVersion = '2.1.3.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply from: new File(rootDir.parentFile, 'buildscripts/publish.gradle')
apply from: new File(rootDir.parentFile, 'buildscripts/coverage.gradle')
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.app.libs.messaging'
version = '0.0.3'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
ext {
springCloudVersion = 'Greenwich.SR1'
jacksonVersion = '2.9.6'
lombokVersion = '1.16.18'
jooqVersion = '3.11.2'
flywayVersion = '5.2.1'
}
dependencies {
compile 'org.aspectj:aspectjweaver'
compile 'org.springframework:spring-tx'
compile 'org.springframework.cloud:spring-cloud-stream'
compile 'org.springframework.cloud:spring-cloud-stream-binder-kafka'
compile 'org.apache.commons:commons-lang3:3.5'
compile 'org.javassist:javassist:3.22.0-GA'
compile "org.flywaydb:flyway-core:${flywayVersion}"
compileOnly "org.jooq:jooq:${jooqVersion}"
compileOnly "org.projectlombok:lombok:${lombokVersion}"
testCompileOnly "org.projectlombok:lombok:${lombokVersion}"
testCompile 'org.springframework.boot:spring-boot-starter-test'
testCompile 'org.springframework.boot:spring-boot-starter-json'
testCompile 'org.springframework.cloud:spring-cloud-stream-test-support'
testCompile "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}"
testCompile "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}"
testCompile 'junit:junit:4.12'
testCompile "org.jooq:jooq:${jooqVersion}"
testCompile "org.flywaydb:flyway-core:${flywayVersion}"
testCompile 'org.postgresql:postgresql:42.2.2'
testCompile 'com.opentable.components:otj-pg-embedded:0.13.0'
testCompile 'org.springframework:spring-jdbc'
}
dependencyManagement {
// disable maven exclusion to enhance gradle import performance
// https://github.com/spring-gradle-plugins/dependency-management-plugin/issues/153
applyMavenExclusions = false
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
jar.enabled = true
bootJar.enabled = false
Я пытался опустить все файлы, которые, по моему мнению, не должны быть связаны.