Swagger 2.x JaxrsAnnotationScanner 找不到位于 ear 中的资源类

Man*_*hek 7 resteasy swagger wildfly jakarta-ee

我目前正在尝试使用 swagger 核心来记录现有的 API。我使用swagger core 2.7和resteasy 3,因为我在wildfly 10上部署。我有一个war,其中包含我的rest servlet和一些位于耳朵中的模型类,其中也包含war。模型类使用 @Schema 进行注释,因此需要依赖于 swagger-annotations。我跟着教程https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---Integration-and-configuration

所以我将依赖添加到我的战争的 pom.xml 和注释模块依赖添加到我的包含模型类的模块。它会编译和部署,但是当我浏览到 /myapp/openapi.yaml 时,我会在 Wildfly 控制台中看到我在 web.xml 中定义的每个资源的以下警告(战争中包含的资源除外)

12:52:22,058 警告 [io.swagger.v3.jaxrs2.integration.JaxrsAnnotationScanner](默认任务 5)从资源类加载类时出错:at.prismasolutions.test.render.RPlotFormatParam 来自 [Module "deployment.rserve-test. ear.at.prismasolutions.test.rserve.web-0.0.1-wildfly-SNAPSHOT.war:main”来自服务模块加载器]:java.lang.ClassNotFoundException:at.prismasolutions.test.render.RPlotFormatParam来自[模块“部署.rserve-test.ear.at.prismasolutions.test.rserve.web-0.0.1-wildfly-SNAPSHOT.war:main" from Service Module Loader] at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:198 ) 在 org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363) 在 org.jboss.modules.ConcurrentClassLoader。performLoadClass(ConcurrentClassLoader.java:351) at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java: 264) 在 io.swagger.v3.jaxrs2.integration.JaxrsAnnotationScanner.classes(JaxrsAnnotationScanner.java:68) 在 io.swagger.v3.oas.integration.GenericOpenApiContext.read(GenericOpenApiContext.java:470) 在 io.swagger.v3 .jaxrs2.integration.resources.BaseOpenApiResource.getOpenApi(BaseOpenApiResource.java:49) 在 io.swagger.v3.jaxrs2.integration.resources.OpenApiResource.getOpenApi(OpenApiResource.java:32) 在 io.swagger.v3.jaxrs2.integration .resources.OpenApiResource$Proxy$_$$_WeldClientProxy.getOpenApi(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun。reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.resteasy .core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:139) at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295) at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(:ResourceMethodInvoker.java) ) 在 org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:236) 在 org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:402) 在 org.jboss.resteasy.core.SynchronousDispatcher在 org.jboss.resteasy.plugins.server.servlet 调用(SynchronousDispatcher.java:209)。ServletContainerDispatcher.service(ServletContainerDispatcher.java:221) 在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56) 在 org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service( HttpServletDispatcher.java:51) 在 javax.servlet.http.HttpServlet.service(HttpServlet.java:790) 在 io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) 在 io.undertow.servlet.handlers .security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociation) :78) 在 io.undertow。server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest( ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53) at io.undertow.security .handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) 在 io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) 在 io。undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:59) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticated handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)undertow .server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) 在 io.undertow.servlet.handlers .ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292) 在 io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81) 在 io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138) ) 在 io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) 在 io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) 在 io.undertow.servlet.core。 ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) 在 io。undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.WrapperThreadSet (LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44) at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetup:4javaActionWrapper) undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest( ServletInitialHandler.java:104) 在 io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) 在 io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor. java:1149) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) 在 java.lang.Thread.run(Thread.java:748)

我的 web.xml 配置:

    <servlet>
    <servlet-name>rserve-resteasy-servlet</servlet-name>
    <servlet-class>
        org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
    </servlet-class>
    <init-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/</param-value>
    </init-param>
    <!-- specify scanner implementation -->
    <init-param>
        <param-name>openApi.configuration.scannerClass</param-name>
        <param-value>io.swagger.v3.jaxrs2.integration.JaxrsAnnotationScanner</param-value>
    </init-param>
    <!-- pretty print -->
    <init-param>
        <param-name>openApi.configuration.prettyPrint</param-name>
        <param-value>true</param-value>
    </init-param>
    <!-- specify resource classes to scan -->
    <init-param>
        <param-name>openApi.configuration.resourceClasses</param-name>
        <param-value>
        rserve.web.RService,
        at.prismasolutions.test.RServeBean.evaluation.REvaluationObject,
        at.prismasolutions.test.RServeBean.evaluation.optima.REvaluationObservationObject,
        at.prismasolutions.test.render.RPlotFormatParam
        </param-value>
    </init-param>
</servlet>
Run Code Online (Sandbox Code Playgroud)

仅找到位于 war 文件中的 rserve.web.RService。有没有人使用包含耳朵的资源设置招摇的经验?

Man*_*hek 1

遗憾的是,我不记得实际上是哪些步骤解决了这个问题,但我最终从 web.xml 中删除了 resourcesClasses(战争中包含的服务端点类资源 RService 除外)

我没有使用 javax.ws.rs.Application 的任何衍生版本,而是使用参数resteasy.scan 注册资源

我的 web.xml 配置包含

<context-param>
    <param-name>resteasy.scan</param-name>
    <param-value>true</param-value>
</context-param>

    <listener>
    <listener-class>
        org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
    <servlet-name>rserve-resteasy-servlet</servlet-name>
    <servlet-class>
        org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    <init-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/</param-value>
    </init-param>
    <!-- specify scanner implementation -->
    <init-param>
        <param-name>openApi.configuration.scannerClass</param-name>
        <param-value>io.swagger.v3.jaxrs2.integration.JaxrsAnnotationScanner</param-value>
    </init-param>
    <!-- pretty print -->
    <init-param>
        <param-name>openApi.configuration.prettyPrint</param-name>
        <param-value>true</param-value>
    </init-param>
    <!-- specify resource classes to scan -->
    <init-param>
        <param-name>openApi.configuration.resourceClasses</param-name>
        <param-value> rweb.RService </param-value>
    </init-param>
</servlet>
Run Code Online (Sandbox Code Playgroud)

看一眼:

Resteasy swagger 核心示例

还要考虑检查依赖管理不善的常见错误,这可能是我当时的问题:

例如 jboss 类加载:ear 中的类无法引用由 war 类加载器加载的类

类依赖项引用不同的类,因为它们注册了两次(war 类加载器、ear 类加载器)