quarkusio/quarkus · error · UnsupportedOperationException

Add AWT Quarkus extension to enable Java2D/ImageIO. Addition

Error message

Add AWT Quarkus extension to enable Java2D/ImageIO. Additional system libraries such as `freetype' and `fontconfig' might be needed.

What it means

When the AWT/Java2D classes are absent from the native image (IsAWTAbsent condition), Quarkus substitutes GraphicsEnvironment.getLocalGraphicsEnvironment() with a stub that throws UnsupportedOperationException with a hint to add the AWT extension. This is a Graal @Substitute placeholder, not a bug in user code.

Source

Thrown at core/runtime/src/main/java/io/quarkus/runtime/graal/AwtImageIO.java:45

     */
    static final class IsAWTAbsent implements BooleanSupplier {
        @Override
        public boolean getAsBoolean() {
            try {
                Class.forName("io.quarkus.awt.runtime.JDKSubstitutions");
                return false;
            } catch (ClassNotFoundException e) {
                return true;
            }
        }
    }
}

@TargetClass(className = "java.awt.GraphicsEnvironment", onlyWith = AwtImageIO.IsAWTAbsent.class)
final class Target_java_awt_GraphicsEnvironment {
    @Substitute
    public static GraphicsEnvironment getLocalGraphicsEnvironment() {
        throw new UnsupportedOperationException(AwtImageIO.AWT_EXTENSION_HINT);
    }

    @Substitute
    public static boolean isHeadless() {
        throw new UnsupportedOperationException(AwtImageIO.AWT_EXTENSION_HINT);
    }
}

@TargetClass(className = "java.awt.Toolkit", onlyWith = AwtImageIO.IsAWTAbsent.class)
final class Target_java_awt_Toolkit {
    @Substitute
    public static synchronized Toolkit getDefaultToolkit() {
        throw new UnsupportedOperationException(AwtImageIO.AWT_EXTENSION_HINT);
    }
}

@TargetClass(className = "java.awt.Color", onlyWith = AwtImageIO.IsAWTAbsent.class)
final class Target_java_awt_Color {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add the AWT extension: ./mvnw quarkus:add-extension -Dextensions="io.quarkus:quarkus-awt" (or add io.quarkus:quarkus-awt to pom.xml) and rebuild the native image.
  2. Ensure the container/base image used for the native build and runtime includes freetype and fontconfig system libraries.
  3. Avoid code paths that initialize AWT (e.g. headless graphics, font metrics) if images are not actually needed.

Example fix

// before (pom.xml)
<dependencies>...</dependencies>
// after
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-awt</artifactId>
</dependency>
Defensive patterns

Strategy: try-catch

Validate before calling

// At startup, fail fast if AWT is needed but absent:
static {
    try {
        Class.forName("java.awt.GraphicsEnvironment");
    } catch (ClassNotFoundException e) {
        throw new IllegalStateException("AWT classes missing: add the quarkus-awt extension");
    }
}

Try / catch

try {
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
} catch (UnsupportedOperationException e) {
    if (e.getMessage() != null && e.getMessage().contains("AWT Quarkus extension")) {
        throw new IllegalStateException("Add io.quarkus:quarkus-awt and rebuild the native image", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling GraphicsEnvironment.getLocalGraphicsEnvironment() at runtime in a native executable built without AWT support (the io.quarkus:quarkus-awt extension not present).

Common situations: Libraries using ImageIO, fonts, or BufferedImage (PDF generation, barcode/captcha rendering) that touch GraphicsEnvironment during native execution; works on JVM mode but fails in native-image because AWT was excluded.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/80917799acdc2f0d. Report an issue: GitHub.