Ошибка при сборке Fatjar с использованием Kotlin DSL
Я пытаюсь построить фиджар, используя ShadowJar. Мое приложение и код Gradle ниже. Я использую Gradle 5.0 для сборки. Когда я запускаю./gradlew run, код работает. Когда я запускаю 'gradle shadowjar' и запускаю fatjar, используя 'java -jar' в папке 'build / lib', я получаю следующую ошибку.
Я предполагаю, что зависимости не загружаются в фиджар? Я также использовал Groovy для создания файла Gradle, и я получаю ту же ошибку.
Правильно ли я в том, что я не включаю все зависимости в файл FATJAR? Если это так, есть идеи, как изменить файл Gradle, чтобы он был включен?
Gradle Kotlin DSL
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
// Apply the Kotlin JVM plugin to add support for Kotlin on the JVM.
id("org.jetbrains.kotlin.jvm").version("1.3.21")
id("com.github.johnrengelman.shadow") version "5.0.0"
// Apply the application plugin to add support for building a CLI application.
application
}
repositories {
// Use jcenter for resolving your dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}
dependencies {
// Use the Kotlin JDK 8 standard library.
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
// Use the Kotlin test library.
testImplementation("org.jetbrains.kotlin:kotlin-test")
// Use the Kotlin JUnit integration.
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
implementation("org.http4k:http4k-core:3.143.1")
implementation("org.http4k:http4k-server-jetty:3.143.1")
implementation("org.http4k:http4k-client-okhttp:3.143.1")
implementation("org.http4k:http4k-client-apache:3.143.1")
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "1.8"
}
application {
// Define the main class for the application.
mainClassName = "com.benito.AppKt"
}
tasks.withType<ShadowJar> {
archiveBaseName.set("${project.name}-all")
}
Код Котлина
import org.http4k.core.HttpHandler
import org.http4k.core.Method
import org.http4k.core.Request
import org.http4k.core.Response
import org.http4k.core.Status.Companion.OK
import org.http4k.routing.bind
import org.http4k.routing.path
import org.http4k.routing.routes
import org.http4k.server.Jetty
import org.http4k.server.asServer
fun main(args: Array<String>) {
println("Starting")
val app: HttpHandler = routes(
"/ping" bind Method.GET to { _: Request -> Response(OK).body("pong!") },
"/greet/{name}" bind Method.GET to { req: Request ->
val path: String? = req.path("name")
Response(OK).body("hello ${path ?: "anon!"}")
}
)
app.asServer(Jetty(8080)).start()
}
Сообщение об ошибке
2019-05-15 11:15:13.925:INFO::main: Logging initialized @287ms to org.eclipse.jetty.util.log.StdErrLog
2019-05-15 11:15:14.039:INFO:oejs.Server:main: jetty-9.4.z-SNAPSHOT; built: 2019-04-29T20:42:08.989Z; git: e1bc35120a6617ee3df052294e433f3a25ce7097; jvm 1.8.0_211-b12
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.eclipse.jetty.http.MimeTypes$Type.<init>(MimeTypes.java:103)
at org.eclipse.jetty.http.MimeTypes$Type.<clinit>(MimeTypes.java:58)
at org.eclipse.jetty.http.MimeTypes.<clinit>(MimeTypes.java:191)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:836)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:278)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:167)
at org.eclipse.jetty.server.Server.start(Server.java:418)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:110)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113)
at org.eclipse.jetty.server.Server.doStart(Server.java:382)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
at org.http4k.server.Jetty$toServer$3.start(jetty.kt:33)
at com.benito.AppKt.main(App.kt:38)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
at org.eclipse.jetty.http.PreEncodedHttpField.<clinit>(PreEncodedHttpField.java:70)
... 14 more
0 ответов
Проблема здесь в том, что в процессе объединения всех JAR в один FatJAR содержимое папки META-INF в http4k-core JAR (который содержит файл mime.types, используемый для сопоставления запроса с типом контента) каким-то образом опускается или отменяется процессом слияния.
Это не специфично для http4k и является (довольно) распространенной проблемой при использовании плагина gradle shadow-jar. Но это легко решить, просто правильно настроив плагин, как показано ниже:
shadowJar {
mergeServiceFiles() // <-- this!
}
Со стороны http4k сгенерированное сообщение об исключении было изменено, чтобы выделить эту проблему.