quarkusio/quarkus · error · RuntimeException

Method '%s' annotated with '@Funq' declared in the class '%s

Error message

Method '%s' annotated with '@Funq' declared in the class '%s' is not public.

What it means

During deployment, FunctionScanner scans classes for methods annotated with @Funq. A @Funq method must be public so the framework can generate invokers; non-public methods are rejected with a build-time RuntimeException naming the method and its class.

Source

Thrown at extensions/funqy/funqy-server-common/deployment/src/main/java/io/quarkus/funqy/deployment/FunctionScannerBuildStep.java:68

            BuildProducer<BytecodeTransformerBuildItem> transformers,
            BuildProducer<AnnotationsTransformerBuildItem> annotationsTransformer,
            BuildProducer<UnremovableBeanBuildItem> unremovableBeans,
            BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
            BuildProducer<ReflectiveHierarchyBuildItem> reflectiveHierarchy,
            BuildProducer<FunctionBuildItem> functions) {
        IndexView index = beanArchiveIndexBuildItem.getIndex();
        Collection<AnnotationInstance> funqs = index.getAnnotations(FUNQ);
        Set<ClassInfo> classes = new HashSet<>();
        Set<String> classNames = new HashSet<>();
        for (AnnotationInstance funqMethod : funqs) {
            MethodInfo method = funqMethod.target().asMethod();
            String className = method.declaringClass().name().toString();
            classNames.add(className);
            classes.add(method.declaringClass());
            String methodName = method.name();

            if (!Modifier.isPublic(method.flags())) {
                throw new RuntimeException(
                        String.format("Method '%s' annotated with '@Funq' declared in the class '%s' is not public.",
                                methodName, className));
            }

            String functionName = null;
            if (funqMethod.value() != null) {
                functionName = funqMethod.value().asString();
            }
            if (functionName != null && functionName.isEmpty())
                functionName = null;
            functions.produce(new FunctionBuildItem(className, methodName, method.descriptor(), functionName));

            String source = FunctionScannerBuildStep.class.getSimpleName() + " > " + method.declaringClass() + "[" + method
                    + "]";

            Type returnType = method.returnType();
            if (returnType.kind() != Type.Kind.VOID) {
                reflectiveHierarchy.produce(ReflectiveHierarchyBuildItem

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add the public modifier to the @Funq method
  2. If the method is meant to be internal, remove @Funq and call it from a public @Funq method
  3. Rebuild; this is a deployment-time check so the fix is confirmed at compile of the extension

Example fix

// before
@Funq
String upper(String s) { return s.toUpperCase(); }
// after
@Funq
public String upper(String s) { return s.toUpperCase(); }
Defensive patterns

Strategy: validation

Validate before calling

// Build-time style check before annotating
if (!java.lang.reflect.Modifier.isPublic(MethodHandles.lookup()
        .reflectClass(MyBean.class).getDeclaredMethods()[0].flags))
    throw new IllegalStateException("@Funq methods must be public");

Prevention

When it happens

Trigger: Annotating a package-private, protected, or private method with @Funq, e.g. @Funq void handle(String s) in a bean class.

Common situations: Refactoring a public handler to a smaller visibility; writing helper-style functions without the public modifier; Kotlin/internal conventions mapping to default visibility.

Related errors


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