GoogleCloudPlatform / GoogleCloudPlatform/kotlin-samples
ClassNotFoundException when running jar file
- 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
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