Skip to content

[Native Image] System.loadLibrary("awt") failed #12148

@YagodinArtem

Description

@YagodinArtem

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.

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

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.(ColorModel.java:221)

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:

Image

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

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions