GoogleCloudPlatform / kotlin-samples

Apache License 2.0
285 stars 88 forks source link

ClassNotFoundException when running jar file #187

Open puja-jena opened 3 years ago

puja-jena commented 3 years ago

EDIT: Updated this with a more simplified example that should be much easier to debug.

I am trying to set up a pubsub POC with my current code (Kotlin) but we are not able to get the needed dependencies to run with it. I am following https://github.com/GoogleCloudPlatform/kotlin-samples/blob/master/pubsub/build.gradle as a guide. I am following the Gradle Kotlin DSL syntax for dependencies and I have added the dependencies to the build.gradle.kts, which now looks like this:

import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

application {
    mainClassName = "MainKt"
}

plugins {
    kotlin("jvm") version "1.4.0"
    application
}
group = "testinpubsublib"
version = "0.9.0"

repositories {
    mavenCentral()
    jcenter()
}
dependencies {
    implementation(platform("com.google.cloud:libraries-bom:20.4.0"))
    implementation("com.google.cloud:google-cloud-pubsub")
}

tasks.jar {
    // names the jar app.jar
    archiveFileName.set("gcppubsubtest.jar")
    manifest {
        // helps make the jar executable by telling where the entry method is
        attributes["Main-Class"] = "MainKt"
    }

    // adds all deps into the jar making it a "fat jar", runable on its own
    from { configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) } }
}

tasks.withType<KotlinCompile>() {
    kotlinOptions.jvmTarget = "14"
}

The app is a very basic hello world app:

fun main(args: Array<String>) {
    println("Hello World!")
}

I have the following in a Dockerfile that I'm using the build the app:

# first download all deps, allows for faster builds when only our code changed
FROM gradle:6.6-jdk14 as cacheRUN mkdir -p /home/gradle/cache_home
ENV GRADLE_USER_HOME /home/gradle/cache_home
COPY build.gradle.kts /home/gradle/kotlin-code/
WORKDIR /home/gradle/kotlin-code
RUN gradle clean build -i --stacktrace
# copy in the deps from the above image, and now pull in the code and build that, creating an executable fat jar
FROM gradle:6.6-jdk14 as builder
COPY --from=cache /home/gradle/cache_home /home/gradle/.gradle
COPY . /usr/src/kotlin-code/
WORKDIR /usr/src/kotlin-code
RUN gradle build -i --stacktrace
RUN ls /usr/src/kotlin-code /usr/src/kotlin-code/build/libs
# Slimmed down running env where we only copy in the jar. This is what actually would be run in prod.
FROM openjdk:14-jdk-alpine
COPY --from=builder /usr/src/kotlin-code/build/libs/gcppubsubtest.jar /bin/runner/run.jar
WORKDIR /bin/runner
CMD ["java","-jar","run.jar"]

When running and building the app as a jar file, I'm getting the following error: Error: Could not find or load main class MainKt Caused by: java.lang.ClassNotFoundException: MainKt

Can someone tell me whether the syntax I am using is incorrect?

bshaffer commented 3 years ago

What GCP product are you deploying to? Can you provide steps for me to reproduce the error? I can try deploying the sample here to the GCP product you're using to see if I encounter the same issue.

If you deploy using the sample build.gradle instead of your own build.gradle.kts, does it work as expected?

puja-jena commented 3 years ago

I am deploying to Kubernetes Engine. Here is a simplified version of the code we are trying to deploy: https://github.com/puja-jena/testingGCPpubsublib. You can reproduce the error by running the Dockerfile I have included in the sample. There will be an error like this: Error: Could not find or load main class MainKt Caused by: java.lang.ClassNotFoundException: MainKt. I have not tried it with a build.gradle file, but I can attempt that and let you know what happens.

puja-jena commented 3 years ago

After trying with build.gradle, I am getting the following error: Could not find com.google.cloud:google-cloud-pubsub:. Required by: project :