【发布时间】:2021-10-13 16:15:48
【问题描述】:
我有一个包含以下内容的 Dockerfile:
FROM gradle:6.9.1-jdk17 as builder
COPY services/api/build.gradle.kts ./
COPY services/api/src ./
COPY services/api/settings.gradle.kts ./
RUN gradle build --no-daemon
FROM openjdk:8-jre-slim
COPY --from=builder /home/* /home
ENTRYPOINT [ "java", "-jar", "./home/build/libs/api.jar" ]
当我使用COPY --from=builder /home/* /home 从构建器复制时,它没有问题,如果我将sh 放入图像中,我可以看到home 文件夹内有一个文件夹结构,包括build/libs/api.jar。但是我只想复制 JAR 文件,所以我想运行 COPY --from=builder /home/build/libs/api.jar . 这应该允许我简单地调用 ENTRYPOINT [ "java", "-jar", "./api.jar" ] 而不是完全限定的 ENTRYPOINT [ "java", "-jar", "./home/build/libs/api.jar" ]。
其次,当我尝试运行图像时,容器会显示Error: Could not find or load main class com.library.api.MainKt。所以我尝试使用在我的dockerfile 中运行的gradle build --no-daemon 命令在本地构建api.jar 文件并减少dockerfile 的内容以简单地从本地构建文件夹中复制该文件(完全省略gradle build ) 并且完美运行。
我在这个问题上大发雷霆。我的直觉说它在 dockerfile 中构建 jar 的方式与在我的机器上的方式不同,但版本是相同的,我正在努力看看还有什么不同。
供参考,我的build.gradle.kts内容如下:
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm") version "1.4.31"
kotlin("plugin.serialization") version "1.4.31"
}
group "com.cabanta"
repositories {
mavenCentral()
}
dependencies {
...
}
tasks.withType<KotlinCompile>() {
kotlinOptions.jvmTarget = "15"
}
tasks.withType<Jar> {
manifest {
attributes["Main-Class"] = "com.library.api.MainKt"
}
exclude("META-INF/*.RSA", "META-INF/*.SF", "META-INF/*.DSA")
// To add all of the dependencies otherwise a "NoClassDefFoundError" error
from(sourceSets.main.get().output)
dependsOn(configurations.runtimeClasspath)
from({
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
})
}
如果您需要其他任何可以回答的问题,请告诉我。
提前感谢您提供的任何帮助。
最后一条相关信息可能是我的主类没有类,它只是有一个 main() 作为函数(在 Kotlin 中应该允许,就像我说的那样,它在运行时构建并工作通过本地机器上的gradle)
【问题讨论】:
-
您是否尝试过二进制比较 docker 内部和您机器上构建的 jar 文件?
-
我没有,但后来学会了 cp 出 jar 文件并检查它。事实证明 com 文件夹是空的,所以最初的副本是实际问题。我没有将其更改为复制整个
src文件夹,然后从那里构建。这会给出正确的.jar文件,我可以自己复制它,而不是复制整个构建文件夹。
标签: java docker api kotlin gradle