Repository: jooby-project/jooby
Pull request #3398 (2024-03-31 18:47:07)

[openapi] Fix parsing avaje bean scope controllers
closes https://github.com/jooby-project/jooby/issues/3397


Patch:
diff --git a/modules/jooby-openapi/pom.xml b/modules/jooby-openapi/pom.xml
index 3e21f334f..f8cfc53c5 100644
--- a/modules/jooby-openapi/pom.xml
+++ b/modules/jooby-openapi/pom.xml
@@ -90,6 +90,13 @@
       <scope>test</scope>
     </dependency>
 
+    <dependency>
+      <groupId>io.avaje</groupId>
+      <artifactId>avaje-inject</artifactId>
+      <version>9.11</version>
+      <scope>test</scope>
+    </dependency>
+
     <dependency>
       <groupId>org.jacoco</groupId>
       <artifactId>org.jacoco.agent</artifactId>
diff --git a/modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/AnnotationParser.java b/modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/AnnotationParser.java
index 96c37d5c9..5962aca40 100644
--- a/modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/AnnotationParser.java
+++ b/modules/jooby-openapi/src/main/java/io/jooby/internal/openapi/AnnotationParser.java
@@ -206,6 +206,10 @@ public class AnnotationParser {
           // mvc(new Controller(...));
           Type type = Type.getObjectType(methodInsnNode.owner);
           return parse(ctx, prefix, type);
+        } else if (methodInsnNode.getOpcode() == Opcodes.INVOKEINTERFACE) {
+          // mvc(beanScope.get(...));
+          Type type = (Type) ((LdcInsnNode) methodInsnNode.getPrevious()).cst;
+          return parse(ctx, prefix, type);
         } else {
           // mvc(some.myController());
           Type type = Type.getReturnType(methodInsnNode.desc);


Test patch:
diff --git a/modules/jooby-openapi/src/test/java/issues/i3397/App3397.java b/modules/jooby-openapi/src/test/java/issues/i3397/App3397.java
new file mode 100644
index 000000000..b93b4b1ae
--- /dev/null
+++ b/modules/jooby-openapi/src/test/java/issues/i3397/App3397.java
@@ -0,0 +1,16 @@
+package issues.i3397;
+
+import io.avaje.inject.BeanScope;
+import io.jooby.Jooby;
+import io.jooby.OpenAPIModule;
+
+public class App3397 extends Jooby {
+    {
+        install(new OpenAPIModule());
+
+        BeanScope beanScope = BeanScope.builder().build();
+
+        mvc(beanScope.get(Controller3397.class));
+
+    }
+}
diff --git a/modules/jooby-openapi/src/test/java/issues/i3397/Controller3397.java b/modules/jooby-openapi/src/test/java/issues/i3397/Controller3397.java
new file mode 100644
index 000000000..8167e8249
--- /dev/null
+++ b/modules/jooby-openapi/src/test/java/issues/i3397/Controller3397.java
@@ -0,0 +1,14 @@
+package issues.i3397;
+
+import io.jooby.annotation.GET;
+import io.jooby.annotation.Path;
+
+@Path("/")
+public class Controller3397 {
+
+    @GET("/welcome")
+    public String sayHi() {
+        return "hi";
+    }
+
+}
diff --git a/modules/jooby-openapi/src/test/java/issues/i3397/Issue3397.java b/modules/jooby-openapi/src/test/java/issues/i3397/Issue3397.java
new file mode 100644
index 000000000..deeec8fc7
--- /dev/null
+++ b/modules/jooby-openapi/src/test/java/issues/i3397/Issue3397.java
@@ -0,0 +1,32 @@
+package issues.i3397;
+
+import io.jooby.openapi.OpenAPIResult;
+import io.jooby.openapi.OpenAPITest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class Issue3397 {
+
+  @OpenAPITest(value = App3397.class)
+  public void shouldParseAvajeBeanScopeControllers(OpenAPIResult result) {
+   var s = result.toYaml();
+    assertEquals(
+        "openapi: 3.0.1\n"
+            + "info:\n"
+            + "  title: 3397 API\n"
+            + "  description: 3397 API description\n"
+            + "  version: \"1.0\"\n"
+            + "paths:\n"
+            + "  /welcome:\n"
+            + "    get:\n"
+            + "      operationId: sayHi\n"
+            + "      responses:\n"
+            + "        \"200\":\n"
+            + "          description: Success\n"
+            + "          content:\n"
+            + "            application/json:\n"
+            + "              schema:\n"
+            + "                type: string\n",
+        result.toYaml());
+  }
+}