GoogleCloudPlatform / GoogleCloudPlatform/kotlin-samples

ClassNotFoundException when running jar file

Open
#187 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
286
Forks
85
PR merge metrics
No merged PRs in 30d

Description

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() {
kotlinOptions.jvmTarget = "14"
}
```
The app is a very basic hello world app:

```
fun main(args: Array) {
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?

Contributor guide

Open the contributing guide

Research direction

Start with the build.gradle.kts configuration and Dockerfile, then run the Gradle build and inspect the generated gcppubsubtest.jar contents and manifest. Confirm that the packaged artifact includes the MainKt entry point and that java -jar run.jar starts the hello-world application without ClassNotFoundException.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, kotlin
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.