quarkusio/quarkus · error · IllegalStateException

Cannot write service provider file '${resourceName}': this G

Error message

Cannot write service provider file '${resourceName}': this GeneratedClassGizmo2Adaptor was created without a GeneratedServiceProviderBuildItem producer

What it means

GeneratedClassGizmo2Adaptor can emit GeneratedClassBuildItem for .class resources and GeneratedServiceProviderBuildItem for META-INF/services/ files, but the latter requires a producer build item supplied at construction. If the adaptor was created without one and bytecode attempts to write a service-provider file, writing is refused with IllegalStateException.

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/GeneratedClassGizmo2Adaptor.java:87

        };
    }

    @Deprecated
    public GeneratedClassGizmo2Adaptor(BuildProducer<GeneratedClassBuildItem> generatedClasses,
            final BuildProducer<GeneratedResourceBuildItem> generatedResources,
            Function<String, String> generatedToBaseNameFunction) {
        this(generatedClasses, generatedResources, null, generatedToBaseNameFunction);
    }

    @Override
    public void write(String resourceName, byte[] bytes) {
        if (resourceName.endsWith(".class")) {
            String className = resourceName.substring(0, resourceName.length() - 6).replace('/', '.');
            generatedClasses.produce(
                    new GeneratedClassBuildItem(applicationClassPredicate.test(className), className, bytes));
        } else if (resourceName.startsWith("META-INF/services/")) {
            if (generatedServiceProviders == null) {
                throw new IllegalStateException(
                        "Cannot write service provider file '" + resourceName
                                + "': this GeneratedClassGizmo2Adaptor was created without a GeneratedServiceProviderBuildItem producer");
            }
            String serviceInterfaceName = resourceName.substring("META-INF/services/".length());
            for (String line : new String(bytes, StandardCharsets.UTF_8).split("\\r?\\n")) {
                line = line.trim();
                if (!line.isEmpty() && !line.startsWith("#")) {
                    generatedServiceProviders.produce(new GeneratedServiceProviderBuildItem(serviceInterfaceName, line));
                }
            }
        } else {
            generatedResources.produce(
                    new GeneratedResourceBuildItem(resourceName, bytes));
        }
    }

    public static boolean isApplicationClass(String className) {
        return QuarkusClassLoader.isApplicationClass(className);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Construct the adaptor passing a BuildProducer<GeneratedServiceProviderBuildItem> (inject it into the build step).
  2. Register the service provider directly via a ServicesFileBuildItem or @BuildStep producing GeneratedServiceProviderBuildItem instead of writing through this adaptor.
  3. Remove the META-INF/services write from generated code and register the implementation with Quarkus' own service-registration build items.

Example fix

// before
var adaptor = new GeneratedClassGizmo2Adaptor(generatedClasses, predicate, null);
// after
var adaptor = new GeneratedClassGizmo2Adaptor(generatedClasses, predicate, generatedServiceProviders);
// where generatedServiceProviders is an injected BuildProducer<GeneratedServiceProviderBuildItem>
Defensive patterns

Strategy: validation

Validate before calling

Objects.requireNonNull(generatedServiceProviders,
    "GeneratedClassGizmo2Adaptor needs a GeneratedServiceProviderBuildItem producer to write META-INF/services files");

Type guard

static boolean canWriteServiceProviders(GeneratedClassGizmo2Adaptor a) {
    return a != null && a.hasServiceProviderProducer();
}

Try / catch

try {
    adaptor.write(resourceName, bytes);
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Cannot write service provider file")) {
        // register via GeneratedServiceProviderBuildItem instead
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Code generated via Gizmo2 calls write() with a resource named META-INF/services/<Interface> while the adaptor instance was constructed with generatedServiceProviders == null (no GeneratedServiceProviderBuildItem producer passed to the constructor).

Common situations: A build step generates classes plus service provider files but only injects GeneratedClassBuildItem (not the provider producer); copy-pasting adaptor construction between steps; adding SPI registration to existing generated-class code.

Related errors


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