【问题标题】:Gradle Docker Build IssuesGradle Docker 构建问题
【发布时间】: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


【解决方案1】:

问题原来是我将文件从本地复制到 gradle 步骤的方式。

COPY services/api/build.gradle.kts ./
COPY services/api/src ./
COPY services/api/settings.gradle.kts ./

这个,我现在改成COPY services/api/* ./,它会复制所有需要的构建文件。

之前的 API 正在被创建,但是它被创建时没有任何内容,这意味着 Java 无法找到该类......因为它从一开始就不存在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-16
    • 2018-07-12
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多