[Native Image] System.loadLibrary("awt") failed
Describe the Issue
Hello guys! First of all thank you for graal technology it is realy fast and powerful, but iam struggling with confusing problem, i am using open cv lib to work with rtsp video stream, which uses java.awt inside, when i try to use BufferedImage, which uses java.awt.image.ColorModel it calls:
static void loadLibraries() {
if (!loaded) {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("awt");
return null;
}
});
loaded = true;
}
}
And this System.loadLibrary("awt"); cause to error (see below)
What am i missing?
Using the latest version of GraalVM can resolve many issues.
- [ ] I tried with the latest version of GraalVM.
GraalVM Version
java version "21.0.8" 2025-07-15 LTS Java(TM) SE Runtime Environment Oracle GraalVM 21.0.8+12.1 (build 21.0.8+12-LTS-jvmci-23.1-b72) Java HotSpot(TM) 64-Bit Server VM Oracle GraalVM 21.0.8+12.1 (build 21.0.8+12-LTS-jvmci-23.1-b72, mixed mode, sharing)
Operating System and Version
Ubuntu 25.04
Troubleshooting Confirmation
- [x] I tried the suggestions in the troubleshooting guide.
Run Command
tried:
./gradlew :pkuback:nativeCompile -PgraalvmNativeImage=true --no-daemon --info -Dnative-image.show-build-time=true --console=verbose
also tried:
./gradlew :pkuback:nativeBuild -PgraalvmNativeImage=true --no-daemon --info -Dnative-image.show-build-time=true --console=verbose
also i build jni and reflect configs with:
java -agentlib:native-image-agent=config-output-dir=META-INF/native-image
-Dhibernate.bytecode.provider=none
-jar ./pkuback/build/libs/pkuback-all-optimized.jar
they are pretty big, so if it necessary i could provide it fully or partial
Expected Behavior
private fun loadNativeLibraries() {
try {
System.loadLibrary("awt")
} catch (e: Exception) {
println("Failed to load native libraries: ${e.message}")
throw e
}
}
cause no exception
Actual Behavior
Stacktrace for the failing thread 0x00007f6c3c000b80 (A=AOT compiled, J=JIT compiled, D=deoptimized, i=inlined):
A SP 0x00007f6c1bfed2a0 IP 0x00005a42a6cf09b9 size=80 com.oracle.svm.core.code.IsolateEnterStub.JNIFunctions_FatalError_2d6e7de51007501356372d87ae0cc671dc9d1a91(IsolateEnterStub.java:0)
i SP 0x00007f6c1bfee350 IP 0x00005a42a6dca1e0 size=64 com.oracle.svm.core.jni.JNIOnLoadFunctionPointer.invoke(JNILibraryInitializer.java)
A SP 0x00007f6c1bfee350 IP 0x00005a42a6dca1e0 size=64 com.oracle.svm.core.jni.JNILibraryInitializer.callOnLoadFunction(JNILibraryInitializer.java:71)
A SP 0x00007f6c1bfee390 IP 0x00005a42a6dca083 size=32 com.oracle.svm.core.jni.JNILibraryInitializer.initialize(JNILibraryInitializer.java:132)
A SP 0x00007f6c1bfee3b0 IP 0x00005a42a6d407f5 size=96 com.oracle.svm.core.jdk.NativeLibrarySupport.addLibrary(NativeLibrarySupport.java:204)
A SP 0x00007f6c1bfee410 IP 0x00005a42a6d40cb8 size=32 com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibrary0(NativeLibrarySupport.java:160)
A SP 0x00007f6c1bfee430 IP 0x00005a42a6d412ba size=144 com.oracle.svm.core.jdk.NativeLibrarySupport.loadLibraryRelative(NativeLibrarySupport.java:123)
i SP 0x00007f6c1bfee4c0 IP 0x00005a42a906eb65 size=16 java.lang.ClassLoader.loadLibrary(ClassLoader.java:106)
i SP 0x00007f6c1bfee4c0 IP 0x00005a42a906eb65 size=16 java.lang.Runtime.loadLibrary0(Runtime.java:916)
i SP 0x00007f6c1bfee4c0 IP 0x00005a42a906eb65 size=16 java.lang.System.loadLibrary(System.java:2063)
i SP 0x00007f6c1bfee4c0 IP 0x00005a42a906eb65 size=16 java.awt.image.ColorModel$1.run(ColorModel.java:211)
A SP 0x00007f6c1bfee4c0 IP 0x00005a42a906eb65 size=16 java.awt.image.ColorModel$1.run(ColorModel.java:209)
i SP 0x00007f6c1bfee4d0 IP 0x00005a42a906f096 size=32 java.security.AccessController.executePrivileged(AccessController.java:129)
i SP 0x00007f6c1bfee4d0 IP 0x00005a42a906f096 size=32 java.security.AccessController.doPrivileged(AccessController.java:319)
i SP 0x00007f6c1bfee4d0 IP 0x00005a42a906f096 size=32 java.awt.image.ColorModel.loadLibraries(ColorModel.java:208)
A SP 0x00007f6c1bfee4d0 IP 0x00005a42a906f096 size=32 java.awt.image.ColorModel.
But the actual lib is created during native build nearly native image is beign:
zeus@zeus-aorus16x9sg:~/zeus/PKU_backend/pkuback/build/native/nativeCompile$ ls -la total 585852 drwxrwxr-x 3 zeus zeus 4096 Sep 11 11:38 . drwxrwxr-x 5 zeus zeus 4096 Sep 10 22:56 .. -rwxrwxr-x 1 zeus zeus 595710120 Sep 11 11:38 app -rw-rw-r-- 1 zeus zeus 42584 Sep 11 11:38 libawt_headless.so -rw-rw-r-- 1 zeus zeus 895608 Sep 11 11:38 libawt.so -rw-rw-r-- 1 zeus zeus 584272 Sep 11 11:38 libawt_xawt.so -rw-rw-r-- 1 zeus zeus 1849272 Sep 11 11:38 libfontmanager.so -rw-rw-r-- 1 zeus zeus 235872 Sep 11 11:38 libjavajpeg.so -rwxrwxr-x 1 zeus zeus 14944 Sep 11 11:38 libjava.so -rwxrwxr-x 1 zeus zeus 14944 Sep 11 11:38 libjvm.so -rw-rw-r-- 1 zeus zeus 528544 Sep 11 11:38 liblcms.so drwxrwxr-x 2 zeus zeus 4096 Sep 11 11:37 reports
Documentation says clearly:
Steps to Reproduce
could run in sample project which use any class of awt package:
private fun loadNativeLibraries() {
try {
System.loadLibrary("awt")
} catch (e: Exception) {
println("Failed to load native libraries: ${e.message}")
throw e
}
}
Additional Context
Main app gradle build:
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
id("buildsrc.convention.kotlin-jvm")
id("com.google.devtools.ksp") version "2.1.21-2.0.1"
id("io.micronaut.application") version "4.5.4"
id("io.micronaut.aot") version "4.5.4"
id("io.micronaut.docker") version "4.5.4"
id("com.gradleup.shadow") version "8.3.7"
id("org.jetbrains.kotlin.kapt")
application
}
java {
sourceCompatibility = JavaVersion.toVersion("21")
}
ksp {
arg("jvmTarget", "21")
}
val kotlinVersion = project.properties["kotlinVersion"]
repositories {
mavenCentral()
}
dependencies {
ksp("io.micronaut:micronaut-http-validation")
ksp("io.micronaut.serde:micronaut-serde-processor")
ksp("io.micronaut.data:micronaut-data-processor")
implementation(project(":videomodule"))
implementation("io.micronaut.kotlin:micronaut-kotlin-runtime")
implementation("io.micronaut.serde:micronaut-serde-jackson")
implementation("io.micronaut:micronaut-http-client")
implementation("io.micronaut:micronaut-runtime")
implementation("io.micronaut.cache:micronaut-cache-core")
implementation("io.micronaut.cache:micronaut-cache-caffeine")
implementation("io.micronaut.redis:micronaut-redis-lettuce")
implementation("jakarta.validation:jakarta.validation-api:${libs.versions.jakartaV}")
implementation("io.micronaut.validation:micronaut-validation:${libs.versions.micronautValidationV}")
annotationProcessor("io.micronaut.validation:micronaut-validation-processor:${libs.versions.micronautValidationV}")
implementation("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:${kotlinVersion}")
implementation("ch.qos.logback:logback-classic:${libs.versions.logback}")
implementation("ch.qos.logback:logback-core:${libs.versions.logback}")
//TODO move to libs.versions
implementation("io.micronaut.data:micronaut-data-processor")
implementation("io.micronaut.data:micronaut-data-jdbc")
implementation("io.micronaut.sql:micronaut-jdbc-hikari")
implementation("com.mysql:mysql-connector-j:8.4.0")
implementation("io.projectreactor:reactor-core:3.8.0-M5")
implementation("commons-codec:commons-codec:1.15")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor:1.10.2")
implementation("net.java.dev.jna:jna:5.17.0")
runtimeOnly("org.yaml:snakeyaml")
compileOnly("io.micronaut:micronaut-http-client")
runtimeOnly("ch.qos.logback:logback-classic")
//TODO move to libs.version
testImplementation("io.micronaut.testresources:micronaut-test-resources-extensions-core")
testImplementation("org.testcontainers:testcontainers:1.19.0")
testImplementation("org.testcontainers:mysql:1.19.0")
testImplementation("org.testcontainers:junit-jupiter:1.19.0")
testImplementation("io.micronaut.test:micronaut-test-junit5")
testImplementation("org.junit.jupiter:junit-jupiter-api")
testImplementation("org.junit.jupiter:junit-jupiter-engine")
testImplementation("org.junit.jupiter:junit-jupiter-params")
testImplementation("org.mockito:mockito-core:5.18.0")
testImplementation(kotlin("test"))
}
application {
mainClass = "ru.zeus.app.AppKt"
}
configurations {
nativeImageCompileOnly {
isCanBeResolved = true
}
}
graalvmNative {
binaries {
named("main") {
imageName.set("app")
mainClass.set("ru.zeus.app.AppKt")
buildArgs.addAll(listOf(
"-Djava.awt.headless=true",
"--initialize-at-run-time=org.bytedeco",
"--enable-url-protocols=http,https,rtsp,rtmp,tcp",
"-H:EnableURLProtocols=rtsp,rtmp,tcp,http,https",
"-H:IncludeResources=libjava\\.so",
"-H:IncludeResources=libjvm\\.so",
"-H:IncludeResources=libawt\\.so",
"-H:IncludeResources=libawt_headless\\.so",
"-H:IncludeResources=libawt_xawt\\.so",
"-H:IncludeResources=libjawt\\.so",
"-H:IncludeResourceBundles=com.sun.jna",
"-H:+ReportExceptionStackTraces",
"-H:+AddAllCharsets",
"--verbose",
"-H:+PrintClassInitialization"
))
}
}
}
micronaut {
runtime("netty")
testRuntime("junit5")
processing {
incremental(true)
annotations("ru.zeus.*")
}
aot {
optimizeServiceLoading = true
convertYamlToJava = true
precomputeOperations = true
cacheEnvironment = true
optimizeClassLoading = true
deduceEnvironment = true
optimizeNetty = true
replaceLogbackXml = false
}
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_21)
}
}
tasks.named<io.micronaut.gradle.docker.NativeImageDockerfile>("dockerfileNative") {
jdkVersion = "21"
}
tasks.test {
useJUnitPlatform()
reports {
html.required = true
junitXml.required = false
}
testLogging {
events("passed", "skipped", "failed")
showStandardStreams = true
}
}
tasks.withType<Copy> {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.optimizedNativeJar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.optimizedJitJar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.jar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
tasks.runnerJar {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
videomodule gradle build:
plugins {
id("buildsrc.convention.kotlin-jvm")
id("com.google.devtools.ksp") version "2.1.21-2.0.1"
id("org.jetbrains.kotlin.kapt")
}
dependencies {
// video module deps
implementation("org.bytedeco:javacv:1.5.12")
implementation("org.bytedeco:ffmpeg-platform:7.1.1-1.5.12")
implementation("org.yaml:snakeyaml:2.5")
}
Run-Time Log Output and Error Messages
No response
Thank you for reaching out about this, we will take a look into this shortly
Hi all. I have the exact same issue and struggle since 3 weeks to get this work in vain. The code works in JIT mode but fails to load library awt in native.
I don't think this is an issue at all. Using AWT merely requires some reflective access, JNI access etc., so native tracing agent is needed to assess what json config your app needs.
Hi Karm,
Thanks for your response. I just succeeded to make it works 10 mn ago by compiling the native image with the option --static-nolibc / -H:+StaticExecutableWithDynamicLibC, copying the shared libraries (.so) alongside the executable (same directory). The list is provided by the native-image console output (see below my particular case) and by providing the -Djava.library.path=./ as arg of the executable (not sure yet that the later is mandatory).
#46 166.4 12.9s (9.1% of total time) in 1854 GCs | Peak RSS: 4.40GB | CPU load: 7.61
#46 166.4 ------------------------------------------------------------------------------------------------------------------------
#46 166.4 Build artifacts:
#46 166.4 /
Thanks a lot for your help and the great work provided by the GraalVM squad. Cheers. J-Hugues
thank`s for your response guys, i am already get rid of this dependency, so that issue is no more affecting my project.