原始 Axon 应用程序 运行,因为 Fat JAR 不会自动配置 Axon Bean
Primitive Axon App run as Fat JAR Doesn't Autoconfigure Axon Beans
问题:
研究:在 https://gitlab.com/ZonZonZon/simple-axon.git,我制作了一个简单的 Axon-app 来展示 JAR-artifact使用 Gradle-plugin com.github.johnrengelman.shadow
时(当 运行 为 JAR 时)不会自动配置 Axon bean。虽然它 运行 在 Intellij 下没问题。
从终端中的项目根目录:
run gradle clean build shadowJar;
java -jar build/simpleaxon.jar;
Stacktrace 已包含在内here。我希望 Axon Autoconfiguration 默认提供像 CommandBus、Snapshotter 和其他 bean。
问题:如何在 fat jar 中自动配置默认的 axon bean?
所以,这需要我进行一些调查才能预感到出了什么问题,但我知道问题出在哪里。
快速注意,这不是 Axon 特定的东西,而是您正在使用的插件。
我 运行 你的示例项目确实得到了相同的结果;从来没有连接过 Axon bean。这促使我逐步研究创建胖 JAR 的过程。首先是 Maven,然后 Spring 使用 Maven 引导,然后 Gradle 使用 Spring 引导,最后使用您所指的 Shadow 插件。
我的努力让我陷入了 this 问题,该问题与 "projects which require the use of META-INF files need to add this to the shadow plugin, and this should be documented" 一样多。
通过 this 引用的部分如下:
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
// Left out all other specifics from your 'build.gradle' file
shadowJar {
// Required for Spring
mergeServiceFiles()
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
transform(PropertiesFileTransformer) {
paths = ['META-INF/spring.factories' ]
mergeStrategy = "append"
}
setArchiveFileName("simpleaxon.jar")
getDestinationDirectory().set(new File(projectDir, "./build"))
}
将那段逻辑添加到您的 build.gradle
文件后,我可以运行 您的示例项目如预期的那样。
我在多模块 Gradle 项目中使用 Axon 时遇到了类似的问题。该应用程序在 IDE 中打包并运行良好时无法运行。我得到的确切错误是
org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 0 in handler
这是因为 ParameterResolverFactories
未加载,因为 META-INF/services
资源未在 shadow jar
插件中正确解析,正如@Steven 所暗示的。
我已经设法简单地修复了它(在 Gradle 中使用 Kotlin DSL):
tasks.shadowJar {
mergeServiceFiles()
}
@Steven 的解决方案是唯一对我有用的解决方案,在搜索了很长时间的其他解决方案之后。
Gradle Kotlin 版本看起来像这样 https://github.com/spring-projects/spring-boot/issues/1828#issuecomment-607352468:
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
plugins {
id("com.github.johnrengelman.shadow") version "7.1.2"
}
...
tasks.shadowJar {
// Required for Spring.
// The shadowJar plugin should merge the services correctly, but it doesn't!
mergeServiceFiles()
append("META-INF/spring.handlers")
append("META-INF/spring.schemas")
append("META-INF/spring.tooling")
transform(
PropertiesFileTransformer().apply {
paths = mutableListOf("META-INF/spring.factories")
mergeStrategy = "append"
})
}
问题:
研究:在 https://gitlab.com/ZonZonZon/simple-axon.git,我制作了一个简单的 Axon-app 来展示 JAR-artifact使用 Gradle-plugin com.github.johnrengelman.shadow
时(当 运行 为 JAR 时)不会自动配置 Axon bean。虽然它 运行 在 Intellij 下没问题。
从终端中的项目根目录:
run gradle clean build shadowJar;
java -jar build/simpleaxon.jar;
Stacktrace 已包含在内here。我希望 Axon Autoconfiguration 默认提供像 CommandBus、Snapshotter 和其他 bean。
问题:如何在 fat jar 中自动配置默认的 axon bean?
所以,这需要我进行一些调查才能预感到出了什么问题,但我知道问题出在哪里。 快速注意,这不是 Axon 特定的东西,而是您正在使用的插件。
我 运行 你的示例项目确实得到了相同的结果;从来没有连接过 Axon bean。这促使我逐步研究创建胖 JAR 的过程。首先是 Maven,然后 Spring 使用 Maven 引导,然后 Gradle 使用 Spring 引导,最后使用您所指的 Shadow 插件。
我的努力让我陷入了 this 问题,该问题与 "projects which require the use of META-INF files need to add this to the shadow plugin, and this should be documented" 一样多。
通过 this 引用的部分如下:
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
// Left out all other specifics from your 'build.gradle' file
shadowJar {
// Required for Spring
mergeServiceFiles()
append 'META-INF/spring.handlers'
append 'META-INF/spring.schemas'
append 'META-INF/spring.tooling'
transform(PropertiesFileTransformer) {
paths = ['META-INF/spring.factories' ]
mergeStrategy = "append"
}
setArchiveFileName("simpleaxon.jar")
getDestinationDirectory().set(new File(projectDir, "./build"))
}
将那段逻辑添加到您的 build.gradle
文件后,我可以运行 您的示例项目如预期的那样。
我在多模块 Gradle 项目中使用 Axon 时遇到了类似的问题。该应用程序在 IDE 中打包并运行良好时无法运行。我得到的确切错误是
org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 0 in handler
这是因为 ParameterResolverFactories
未加载,因为 META-INF/services
资源未在 shadow jar
插件中正确解析,正如@Steven 所暗示的。
我已经设法简单地修复了它(在 Gradle 中使用 Kotlin DSL):
tasks.shadowJar {
mergeServiceFiles()
}
@Steven 的解决方案是唯一对我有用的解决方案,在搜索了很长时间的其他解决方案之后。
Gradle Kotlin 版本看起来像这样 https://github.com/spring-projects/spring-boot/issues/1828#issuecomment-607352468:
import com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer
plugins {
id("com.github.johnrengelman.shadow") version "7.1.2"
}
...
tasks.shadowJar {
// Required for Spring.
// The shadowJar plugin should merge the services correctly, but it doesn't!
mergeServiceFiles()
append("META-INF/spring.handlers")
append("META-INF/spring.schemas")
append("META-INF/spring.tooling")
transform(
PropertiesFileTransformer().apply {
paths = mutableListOf("META-INF/spring.factories")
mergeStrategy = "append"
})
}