diff --git a/build.gradle.kts b/build.gradle.kts index 68ae096..47f050c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,11 +9,12 @@ plugins { id("com.github.ben-manes.versions") version "0.51.0" id("org.springframework.boot") version "3.5.6" id("io.spring.dependency-management") version "1.1.7" - id("net.thebugmc.gradle.sonatype-central-portal-publisher") version "1.2.3" id("maven-publish") + id("net.thebugmc.gradle.sonatype-central-portal-publisher") version "1.2.3" } group = "com.valensas" +version = "0.2.23" java.sourceCompatibility = JavaVersion.VERSION_21 @@ -28,10 +29,12 @@ tasks.getByName("jar") { dependencies { implementation("org.springframework.boot:spring-boot-starter") + implementation("org.springframework.data:spring-data-commons") implementation("org.jetbrains.kotlin:kotlin-reflect") testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit5") testRuntimeOnly("org.junit.platform:junit-platform-launcher") + implementation("com.valensas:graalvm-native-support:1.0.7") // Ftp implementation("commons-net:commons-net:3.12.0") @@ -69,7 +72,7 @@ publishing { publications { create("mavenJava") { from(components["java"]) - } + } } } @@ -90,14 +93,14 @@ centralPortal { description = "This library contains embedded ftp server and ftp factory which supports ftp, ftps, sftp." url = "https://valensas.com/" scm { - url = "https://github.com/Valensas/java-ftp" + url = "https://github.com/Valensas/java-ftp" } licenses { license { name.set("The Apache License, Version 2.0") url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") - } + } } developers { @@ -105,7 +108,8 @@ centralPortal { id.set("0") name.set("Valensas") email.set("info@valensas.com") - } + } } - } + } } + diff --git a/src/main/kotlin/com/valensas/ftp/autoconfigure/RuntimeHintsAutoConfiguration.kt b/src/main/kotlin/com/valensas/ftp/autoconfigure/RuntimeHintsAutoConfiguration.kt new file mode 100644 index 0000000..f7f634c --- /dev/null +++ b/src/main/kotlin/com/valensas/ftp/autoconfigure/RuntimeHintsAutoConfiguration.kt @@ -0,0 +1,13 @@ +package com.valensas.ftp.autoconfigure + +import com.valensas.ftp.hints.CustomRuntimeHintsRegistrar +import com.valensas.ftp.hints.JschRuntimeHintsRegistrar +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.ImportRuntimeHints + +@Configuration +@ImportRuntimeHints( + CustomRuntimeHintsRegistrar::class, + JschRuntimeHintsRegistrar::class, +) +class RuntimeHintsAutoConfiguration diff --git a/src/main/kotlin/com/valensas/ftp/hints/CustomRuntimeHintsRegistrar.kt b/src/main/kotlin/com/valensas/ftp/hints/CustomRuntimeHintsRegistrar.kt new file mode 100644 index 0000000..91d57ea --- /dev/null +++ b/src/main/kotlin/com/valensas/ftp/hints/CustomRuntimeHintsRegistrar.kt @@ -0,0 +1,39 @@ +package com.valensas.ftp.hints + +import com.valensas.nativesupport.hints.HintUtils +import org.slf4j.LoggerFactory +import org.springframework.aot.hint.MemberCategory +import org.springframework.aot.hint.RuntimeHints +import org.springframework.aot.hint.RuntimeHintsRegistrar +import org.springframework.data.util.TypeScanner + +class CustomRuntimeHintsRegistrar : RuntimeHintsRegistrar { + private val logger = LoggerFactory.getLogger(javaClass) + + override fun registerHints( + hints: RuntimeHints, + classLoader: ClassLoader?, + ) { + val packages = listOf("com.valensas.ftp.model") + + logger.info( + "Setting reflection hints for classes in packages: {}", + packages.joinToString(", "), + ) + + TypeScanner + .typeScanner(requireNotNull(classLoader)) + .scanPackages(packages) + .forEach { clazz -> + hints + .reflection() + .registerType(clazz, *MemberCategory.entries.toTypedArray()) + + HintUtils.registerSerializationHints( + hints, + clazz, + classLoader, + ) + } + } +} diff --git a/src/main/kotlin/com/valensas/ftp/hints/JschRuntimeHintsRegistrar.kt b/src/main/kotlin/com/valensas/ftp/hints/JschRuntimeHintsRegistrar.kt new file mode 100644 index 0000000..49094fb --- /dev/null +++ b/src/main/kotlin/com/valensas/ftp/hints/JschRuntimeHintsRegistrar.kt @@ -0,0 +1,81 @@ +package com.valensas.ftp.hints + +import org.springframework.aot.hint.MemberCategory +import org.springframework.aot.hint.RuntimeHints +import org.springframework.aot.hint.RuntimeHintsRegistrar + +class JschRuntimeHintsRegistrar : RuntimeHintsRegistrar { + override fun registerHints( + hints: RuntimeHints, + classLoader: ClassLoader?, + ) { + val reflection = hints.reflection() + + hints.resources().registerPattern("com/jcraft/jsch/**") + + listOf( + "javax.crypto.Cipher", + "javax.crypto.Mac", + "javax.crypto.KeyAgreement", + "java.security.MessageDigest", + "java.security.KeyPairGenerator", + "java.security.Signature", + ).forEach { + reflection.registerTypeIfPresent( + classLoader, + it, + ::configureForReflection, + ) + } + + val jschClasses = + listOf( + "com.jcraft.jsch.JSch", + "com.jcraft.jsch.Session", + "com.jcraft.jsch.ChannelSftp", + "com.jcraft.jsch.UserAuth", + "com.jcraft.jsch.UserAuthPassword", + "com.jcraft.jsch.UserAuthPublicKey", + "com.jcraft.jsch.UserAuthKeyboardInteractive", + "com.jcraft.jsch.UserAuthNone", + "com.jcraft.jsch.UserAuthGSSAPIWithMIC", + "com.jcraft.jsch.jce.DH", + "com.jcraft.jsch.jce.Random", + "com.jcraft.jsch.jce.AES128CBC", + "com.jcraft.jsch.jce.AES256CBC", + "com.jcraft.jsch.jce.AES128CTR", + "com.jcraft.jsch.jce.TripleDESCBC", + "com.jcraft.jsch.jce.BlowfishCBC", + "com.jcraft.jsch.jce.HMACSHA1", + "com.jcraft.jsch.jce.HMACSHA256", + "com.jcraft.jsch.jce.HMACMD5", + "com.jcraft.jsch.jce.SHA1", + "com.jcraft.jsch.jce.SHA256", + "com.jcraft.jsch.jce.MD5", + "com.jcraft.jsch.jce.SignatureRSA", + "com.jcraft.jsch.jce.SignatureDSA", + "com.jcraft.jsch.jce.KeyPairGenRSA", + "com.jcraft.jsch.jce.KeyPairGenDSA", + "com.jcraft.jsch.DHG1", + "com.jcraft.jsch.DHG14", + "com.jcraft.jsch.DHGEX", + "com.jcraft.jsch.DHGEX256", + ) + + jschClasses.forEach { + reflection.registerTypeIfPresent( + classLoader, + it, + ::configureForReflection, + ) + } + } + + private fun configureForReflection(typeHint: org.springframework.aot.hint.TypeHint.Builder) { + typeHint.withMembers( + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, + MemberCategory.INVOKE_DECLARED_METHODS, + MemberCategory.DECLARED_FIELDS, + ) + } +} diff --git a/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..8070d18 --- /dev/null +++ b/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.valensas.ftp.autoconfigure.RuntimeHintsAutoConfiguration \ No newline at end of file