Quarkus Camel File组件相对路径读取失效问题排查
Apache Camel + Quarkus 相对路径读取文件失效问题
我用Apache Camel + Quarkus + Kotlin + Gradle开发一个简单的文件复制集成服务,基于Quarkus Camel启动页下载的code-with-quarkus示例代码。目前遇到的问题:绝对路径能正常读取文件,但用项目相对路径时完全没反应,既不报错也不输出日志。
可用的绝对路径代码
import org.apache.camel.builder.RouteBuilder class Route : RouteBuilder() { override fun configure() { from("file:///Users/john/Downloads/code-with-quarkus/files/input") .convertBodyTo(String::class.java) .log("${body()}") .to("file:///Users/john/Downloads/code-with-quarkus/files/input") } }
失效的相对路径代码
import org.apache.camel.builder.RouteBuilder class Route : RouteBuilder() { override fun configure() { from("file:files/input") .convertBodyTo(String::class.java) .log("${body()}") .to("file:files/output") } }
项目结构
项目根目录下直接存在files文件夹,内部包含input和output两个子文件夹。
运行日志
2023-03-06 16:03:39,643 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Apache Camel 3.20.1 (camel-1) is starting 2023-03-06 16:03:39,655 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Routes startup (started:1) 2023-03-06 16:03:39,655 INFO [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Started route1 (file://files/input)
build.gradle.kt 配置
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { java id("io.quarkus") kotlin("jvm") version "1.8.20-Beta" } repositories { mavenCentral() mavenLocal() } val quarkusPlatformGroupId: String by project val quarkusPlatformArtifactId: String by project val quarkusPlatformVersion: String by project dependencies { implementation( enforcedPlatform( "${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}" ) ) implementation( enforcedPlatform( "${quarkusPlatformGroupId}:quarkus-camel-bom:${quarkusPlatformVersion}" ) ) implementation("org.apache.camel.quarkus:camel-quarkus-file") implementation("org.apache.camel.quarkus:camel-quarkus-quartz") implementation("io.quarkus:quarkus-arc") testImplementation("io.quarkus:quarkus-junit5") implementation(kotlin("stdlib-jdk8")) } group = "org.acme" version = "1.0.0-SNAPSHOT" java { sourceCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17 } tasks.withType<Test> { systemProperty("java.util.logging.manager", "org.jboss.logmanager.LogManager") } tasks.withType<JavaCompile> { options.encoding = "UTF-8" options.compilerArgs.add("-parameters") } val compileKotlin: KotlinCompile by tasks compileKotlin.kotlinOptions { jvmTarget = "1.8" } val compileTestKotlin: KotlinCompile by tasks compileTestKotlin.kotlinOptions { jvmTarget = "1.8" }
问题原因及解决方案
核心问题
Quarkus运行时的工作目录不是项目根目录:
- 开发模式(
quarkusDev)下工作目录是build/dev-app - 生产构建(
quarkusBuild)下工作目录是build/quarkus-app
你写的files/input是相对于运行时工作目录,而非项目根目录下的files文件夹,所以Camel找不到文件。
方案1:通过配置指定绝对路径(推荐)
在src/main/resources/application.properties添加路径配置:
camel.file.input.dir=${project.root}/files/input camel.file.output.dir=${project.root}/files/output
修改路由代码,通过配置注入路径:
import org.apache.camel.builder.RouteBuilder import javax.inject.Inject import org.eclipse.microprofile.config.inject.ConfigProperty class Route : RouteBuilder() { @ConfigProperty(name = "camel.file.input.dir") lateinit var inputDir: String @ConfigProperty(name = "camel.file.output.dir") lateinit var outputDir: String override fun configure() { from("file:$inputDir") .convertBodyTo(String::class.java) .log("${body()}") .to("file:$outputDir") } }
在build.gradle.kt中给Quarkus任务传递项目根目录参数:
tasks.named<io.quarkus.gradle.tasks.QuarkusDev>("quarkusDev") { systemProperty("project.root", project.rootDir.absolutePath) } tasks.named<io.quarkus.gradle.tasks.QuarkusBuild>("quarkusBuild") { systemProperty("project.root", project.rootDir.absolutePath) }
方案2:复制files目录到运行时工作目录
在build.gradle.kt添加复制任务,将项目根目录的files同步到运行目录:
// 开发模式下复制 tasks.named<io.quarkus.gradle.tasks.QuarkusDev>("quarkusDev") { doFirst { copy { from(project.rootDir.resolve("files")) into("build/dev-app/files") } } } // 生产构建时复制 tasks.named<io.quarkus.gradle.tasks.QuarkusBuild>("quarkusBuild") { doLast { copy { from(project.rootDir.resolve("files")) into("build/quarkus-app/files") } } }
这样运行时files/input就能找到对应目录了。
额外提示
你绝对路径代码里的to路径和from一致,会把文件复制回原目录,应该是笔误,建议改成output目录。
内容的提问来源于stack exchange,提问作者Jorge
相关产品推荐
相关产品推荐

