diff --git a/build.gradle.kts b/build.gradle.kts index 4dee9ed6..9d9447ff 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,13 +8,14 @@ val koin_version: String by project plugins { kotlin("jvm") version "1.8.10" id("io.ktor.plugin") version "2.2.4" + id("org.graalvm.buildtools.native") version "0.9.11" // id("org.jetbrains.kotlin.plugin.serialization") version "1.8.10" } group = "dev.usbharu" version = "0.0.1" application { - mainClass.set("io.ktor.server.netty.EngineMain") + mainClass.set("io.ktor.server.cio.EngineMain") val isDevelopment: Boolean = project.ext.has("development") applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment") @@ -52,7 +53,7 @@ dependencies { implementation("com.h2database:h2:$h2_version") implementation("org.xerial:sqlite-jdbc:3.40.1.0") implementation("io.ktor:ktor-server-websockets-jvm:$ktor_version") - implementation("io.ktor:ktor-server-netty-jvm:$ktor_version") + implementation("io.ktor:ktor-server-cio-jvm:$ktor_version") implementation("ch.qos.logback:logback-classic:$logback_version") implementation("io.insert-koin:koin-core:$koin_version") @@ -97,3 +98,26 @@ ktor { localImageName.set("hideout") } } + +graalvmNative { + binaries { + named("main") { + fallback.set(false) + verbose.set(true) + + + buildArgs.add("--initialize-at-build-time=io.ktor,kotlin,kotlinx") + buildArgs.add("--trace-class-initialization=ch.qos.logback.classic.Logger") + buildArgs.add("--trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase"+"$"+"Worker") + buildArgs.add("--trace-object-instantiation=ch.qos.logback.classic.Logger") + buildArgs.add("--initialize-at-build-time=org.slf4j.LoggerFactory,ch.qos.logback") + buildArgs.add("--trace-object-instantiation=kotlinx.coroutines.channels.ArrayChannel") + buildArgs.add("--initialize-at-build-time=kotlinx.coroutines.channels.ArrayChannel") + buildArgs.add("-H:+InstallExitHandlers") + buildArgs.add("-H:+ReportUnsupportedElementsAtRuntime") + buildArgs.add("-H:+ReportExceptionStackTraces") + + imageName.set("graal-server") + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/Application.kt b/src/main/kotlin/dev/usbharu/hideout/Application.kt index bd41e609..e4bca1fe 100644 --- a/src/main/kotlin/dev/usbharu/hideout/Application.kt +++ b/src/main/kotlin/dev/usbharu/hideout/Application.kt @@ -30,7 +30,7 @@ import kjob.core.kjob import org.jetbrains.exposed.sql.Database import org.koin.ktor.ext.inject -fun main(args: Array): Unit = io.ktor.server.netty.EngineMain.main(args) +fun main(args: Array): Unit = io.ktor.server.cio.EngineMain.main(args) val Application.property: Application.(propertyName: String) -> String get() = { diff --git a/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueParentService.kt b/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueParentService.kt index 6324fde7..0058638e 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueParentService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/job/KJobJobQueueParentService.kt @@ -13,7 +13,7 @@ class KJobJobQueueParentService(private val database: Database) : JobQueueParent private val logger = LoggerFactory.getLogger(this::class.java) val kjob: KJob = kjob(ExposedKJob) { - connectionDatabase = database + connectionDatabase = database isWorker = false }.start() @@ -21,8 +21,8 @@ class KJobJobQueueParentService(private val database: Database) : JobQueueParent } - override suspend fun schedule(job: J,block:ScheduleContext.(J)->Unit) { - logger.debug("schedule job={}",job.name) - kjob.schedule(job,block) + override suspend fun schedule(job: J, block: ScheduleContext.(J) -> Unit) { + logger.debug("schedule job={}", job.name) + kjob.schedule(job, block) } } diff --git a/src/main/resources/META-INF/native-image/jni-config.json b/src/main/resources/META-INF/native-image/jni-config.json new file mode 100644 index 00000000..80fe1b33 --- /dev/null +++ b/src/main/resources/META-INF/native-image/jni-config.json @@ -0,0 +1,31 @@ +[ + { + "name": "sun.management.VMManagementImpl", + "fields": [ + { + "name": "compTimeMonitoringSupport" + }, + { + "name": "currentThreadCpuTimeSupport" + }, + { + "name": "objectMonitorUsageSupport" + }, + { + "name": "otherThreadCpuTimeSupport" + }, + { + "name": "remoteDiagnosticCommandsSupport" + }, + { + "name": "synchronizerUsageSupport" + }, + { + "name": "threadAllocatedMemorySupport" + }, + { + "name": "threadContentionMonitoringSupport" + } + ] + } +] \ No newline at end of file diff --git a/src/main/resources/META-INF/native-image/predefined-classes-config.json b/src/main/resources/META-INF/native-image/predefined-classes-config.json new file mode 100644 index 00000000..c5962d22 --- /dev/null +++ b/src/main/resources/META-INF/native-image/predefined-classes-config.json @@ -0,0 +1,8 @@ +[ + { + "type": "agent-extracted", + "classes": [ + + ] + } +] \ No newline at end of file diff --git a/src/main/resources/META-INF/native-image/proxy-config.json b/src/main/resources/META-INF/native-image/proxy-config.json new file mode 100644 index 00000000..1610ea14 --- /dev/null +++ b/src/main/resources/META-INF/native-image/proxy-config.json @@ -0,0 +1,3 @@ +[ + +] \ No newline at end of file diff --git a/src/main/resources/META-INF/native-image/reflect-config.json b/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 00000000..c11cbd23 --- /dev/null +++ b/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,631 @@ +[ + { + "name": "[Lcom.fasterxml.jackson.databind.deser.Deserializers;" + }, + { + "name": "[Lcom.fasterxml.jackson.databind.deser.KeyDeserializers;" + }, + { + "name": "[Lcom.fasterxml.jackson.databind.deser.ValueInstantiators;" + }, + { + "name": "[Lcom.fasterxml.jackson.databind.ser.Serializers;" + }, + { + "name": "[Ljava.lang.String;" + }, + { + "name": "android.os.Build$VERSION" + }, + { + "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder", + "queryAllPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "ch.qos.logback.classic.pattern.DateConverter", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "ch.qos.logback.classic.pattern.LevelConverter", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "ch.qos.logback.classic.pattern.LineSeparatorConverter", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "ch.qos.logback.classic.pattern.LoggerConverter", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "ch.qos.logback.classic.pattern.MessageConverter", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "ch.qos.logback.classic.pattern.ThreadConverter", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "ch.qos.logback.core.ConsoleAppender", + "queryAllPublicMethods": true, + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "ch.qos.logback.core.OutputStreamAppender", + "methods": [ + { + "name": "setEncoder", + "parameterTypes": [ + "ch.qos.logback.core.encoder.Encoder" + ] + } + ] + }, + { + "name": "ch.qos.logback.core.encoder.LayoutWrappingEncoder", + "methods": [ + { + "name": "setParent", + "parameterTypes": [ + "ch.qos.logback.core.spi.ContextAware" + ] + } + ] + }, + { + "name": "ch.qos.logback.core.pattern.PatternLayoutEncoderBase", + "methods": [ + { + "name": "setPattern", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "com.fasterxml.jackson.databind.ext.Java7SupportImpl", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "com.ibm.icu.text.Collator" + }, + { + "name": "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "dev.usbharu.hideout.ApplicationKt", + "queryAllPublicMethods": true, + "methods": [ + { + "name": "main", + "parameterTypes": [ + ] + }, + { + "name": "parent", + "parameterTypes": [ + "io.ktor.server.application.Application" + ] + }, + { + "name": "worker", + "parameterTypes": [ + "io.ktor.server.application.Application" + ] + } + ] + }, + { + "name": "io.ktor.http.HttpStatusCode" + }, + { + "name": "io.ktor.http.Parameters" + }, + { + "name": "io.ktor.server.application.Application" + }, + { + "name": "javax.smartcardio.CardPermission" + }, + { + "name": "kotlin.Any" + }, + { + "name": "kotlin.Array" + }, + { + "name": "kotlin.ExtensionFunctionType" + }, + { + "name": "kotlin.Function2" + }, + { + "name": "kotlin.Metadata", + "queryAllDeclaredMethods": true, + "methods": [ + { + "name": "bv", + "parameterTypes": [ + ] + }, + { + "name": "d1", + "parameterTypes": [ + ] + }, + { + "name": "d2", + "parameterTypes": [ + ] + }, + { + "name": "k", + "parameterTypes": [ + ] + }, + { + "name": "mv", + "parameterTypes": [ + ] + }, + { + "name": "pn", + "parameterTypes": [ + ] + }, + { + "name": "xi", + "parameterTypes": [ + ] + }, + { + "name": "xs", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "kotlin.ParameterName" + }, + { + "name": "kotlin.String" + }, + { + "name": "kotlin.Unit" + }, + { + "name": "kotlin.internal.jdk8.JDK8PlatformImplementations", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "kotlin.jvm.internal.DefaultConstructorMarker" + }, + { + "name": "kotlin.reflect.jvm.internal.ReflectionFactoryImpl", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "kotlin.reflect.jvm.internal.impl.resolve.scopes.DescriptorKindFilter", + "allPublicFields": true + }, + { + "name": "org.h2.Driver", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.mvstore.db.LobStorageMap$BlobMeta$Type", + "fields": [ + { + "name": "INSTANCE" + } + ] + }, + { + "name": "org.h2.mvstore.db.LobStorageMap$BlobReference$Type", + "fields": [ + { + "name": "INSTANCE" + } + ] + }, + { + "name": "org.h2.mvstore.db.NullValueDataType", + "fields": [ + { + "name": "INSTANCE" + } + ] + }, + { + "name": "org.h2.mvstore.db.RowDataType$Factory", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.mvstore.tx.VersionedValueType$Factory", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.mvstore.type.ByteArrayDataType", + "fields": [ + { + "name": "INSTANCE" + } + ] + }, + { + "name": "org.h2.mvstore.type.LongDataType", + "fields": [ + { + "name": "INSTANCE" + } + ] + }, + { + "name": "org.h2.store.fs.async.FilePathAsync", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.disk.FilePathDisk", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.mem.FilePathMem", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.mem.FilePathMemLZF", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.niomapped.FilePathNioMapped", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.niomem.FilePathNioMem", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.niomem.FilePathNioMemLZF", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.retry.FilePathRetryOnInterrupt", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.split.FilePathSplit", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.h2.store.fs.zip.FilePathZip", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "org.locationtech.jts.geom.Geometry" + }, + { + "name": "sun.security.provider.DRBG", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "sun.security.provider.SHA", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "sun.security.provider.SHA2$SHA256", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "sun.security.rsa.RSAKeyPairGenerator$Legacy", + "methods": [ + { + "name": "", + "parameterTypes": [ + ] + } + ] + }, + { + "name": "kotlin.reflect.jvm.internal.ReflectionFactoryImpl", + "allDeclaredConstructors": true + }, + { + "name": "kotlin.KotlinVersion", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "kotlin.KotlinVersion[]" + }, + { + "name": "kotlin.KotlinVersion$Companion" + }, + { + "name": "kotlin.KotlinVersion$Companion[]" + }, + { + "name": "kotlin.internal.jdk8.JDK8PlatformImplementations", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "kotlin", + "allPublicMethods": true, + "allDeclaredFields": true, + "allDeclaredMethods": true, + "allDeclaredConstructors": true + }, + { + "name": "io.igx.kotlin.model.Driver", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "fields": [ + { + "name": "id" + }, + { + "name": "firstName" + }, + { + "name": "lastName" + }, + { + "name": "nationality" + } + ] + }, + { + "name": "java.lang.Integer", + "methods": [ + { + "name": "parseInt", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "java.lang.Long", + "methods": [ + { + "name": "parseLong", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "java.lang.Boolean", + "methods": [ + { + "name": "parseBoolean", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "java.lang.Byte", + "methods": [ + { + "name": "parseByte", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "java.lang.Short", + "methods": [ + { + "name": "parseShort", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "java.lang.Float", + "methods": [ + { + "name": "parseFloat", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + }, + { + "name": "java.lang.Double", + "methods": [ + { + "name": "parseDouble", + "parameterTypes": [ + "java.lang.String" + ] + } + ] + } +] diff --git a/src/main/resources/META-INF/native-image/resource-config.json b/src/main/resources/META-INF/native-image/resource-config.json new file mode 100644 index 00000000..5c30b1ba --- /dev/null +++ b/src/main/resources/META-INF/native-image/resource-config.json @@ -0,0 +1,54 @@ +{ + "resources": { + "includes": [ + { + "pattern": "\\QMETA-INF/services/ch.qos.logback.classic.spi.Configurator\\E" + }, + { + "pattern": "\\QMETA-INF/services/io.ktor.server.config.ConfigLoader\\E" + }, + { + "pattern": "\\QMETA-INF/services/java.sql.Driver\\E" + }, + { + "pattern": "\\QMETA-INF/services/kotlin.reflect.jvm.internal.impl.builtins.BuiltInsLoader\\E" + }, + { + "pattern": "\\QMETA-INF/services/kotlin.reflect.jvm.internal.impl.resolve.ExternalOverridabilityCondition\\E" + }, + { + "pattern": "\\QMETA-INF/services/org.jetbrains.exposed.sql.DatabaseConnectionAutoRegistration\\E" + }, + { + "pattern": "\\QMETA-INF/services/org.slf4j.spi.SLF4JServiceProvider\\E" + }, + { + "pattern": "\\Qapplication.conf\\E" + }, + { + "pattern": "\\Qlogback.xml\\E" + }, + { + "pattern": "\\Qorg/fusesource/jansi/internal/native/Windows/x86_64/jansi.dll\\E" + }, + { + "pattern": "\\Qorg/fusesource/jansi/jansi.properties\\E" + }, + { + "pattern": "\\Qorg/h2/util/data.zip\\E" + }, + { + "pattern": "\\Qstatic/assets/index-c7cbea7a.js\\E" + }, + { + "pattern": "\\Qstatic/index.html\\E" + }, + { + "pattern":"\\Qkotlin/kotlin.kotlin_builtins\\E" + } + ] + }, + "bundles": [ + + ] +} diff --git a/src/main/resources/META-INF/native-image/serialization-config.json b/src/main/resources/META-INF/native-image/serialization-config.json new file mode 100644 index 00000000..f63da041 --- /dev/null +++ b/src/main/resources/META-INF/native-image/serialization-config.json @@ -0,0 +1,11 @@ +{ + "lambdaCapturingTypes": [ + + ], + "types": [ + + ], + "proxies": [ + + ] +} \ No newline at end of file