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(ReflectiveHierarchyBuildItemView on GitHub (pinned to e1c734241f)
Solutions
- Add the public modifier to the @Funq method
- If the method is meant to be internal, remove @Funq and call it from a public @Funq method
- 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
- Always declare @Funq methods public
- Pair the annotation with a checklist item: public method, registered name, supported signature
- Add unit tests that reflect over @Funq methods and assert public visibility
- Avoid refactoring visibility of annotated methods without rerunning the build
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
- Method '${info.name()} of class '${info.declaringClass().nam
- Failed to open path tree with root %s
- Dev services for ${request.getName()} requires a startable s
- Name cannot start with '/':${name}
- The class (${name}) cannot be created during deployment.
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/74406f22f29c536d.
Report an issue: GitHub.