Swagger 2.x JaxrsAnnotationScanner не находит классы ресурсов, расположенные в ear

#jakarta-ee #swagger #wildfly #resteasy

#jakarta-ee #swagger #wildfly #resteasy

Вопрос:

В настоящее время я пытаюсь задокументировать существующий API с помощью swagger core. Я использую swagger core 2.7 и resteasy 3, поскольку я развертываю wildfly 10. У меня есть war, содержащий мой сервлет rest и некоторые классы моделей, расположенные в ear, который также содержит war. Классы моделей помечены с помощью @Schema и, следовательно, нуждаются в зависимости от аннотаций swagger. Я следовал руководству по https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X—Integration-and-configuration

Поэтому я добавил зависимость к моей war pom.xml и зависимость модуля аннотаций от моего модуля, содержащего классы моделей. Он компилируется и развертывается, но когда я просматриваю / myapp / openapi.yaml, я вижу следующие предупреждения в консоли wildfly для каждого ресурса, который я определил в web.xml (кроме тех, которые содержатся в war)

12:52:22,058 ПРЕДУПРЕЖДЕНИЕ [io.swagger.v3.jaxrs2.integration.JaxrsAnnotationScanner] (задача по умолчанию-5) ошибка при загрузке класса из классов ресурсов: at.prismasolutions.test.render.RPlotFormatParam из [Модуля «deployment.rserve-test.ear.at.prismasolutions.test.rserve.web-0.0.1-wildfly-SNAPSHOT.war:main» из загрузчика сервисного модуля]: java.lang.Исключение ClassNotFoundException: в.prismasolutions.test.render.RPlotFormatParam из [Модуля «deployment.rserve-test.ear.at.prismasolutions.test.rserve.web-0.0.1-wildfly-SNAPSHOT.war:main» из загрузчика сервисного модуля] в org.jboss.modules.ModuleClassLoader.FindClass(ModuleClassLoader.java:198) в org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:363) в org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:351) в org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:93) на java.lang.Class.forName0 (собственный метод) на java.lang.Class.forName(Class.java:264) в io.swagger.v3.jaxrs2.integration.JaxrsAnnotationScanner.classes(JaxrsAnnotationScanner.java:68) при вводе-выводе.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.Откройте исходный код $Proxy $_$$_WeldClientProxy.getOpenApi(неизвестный источник) в sun.reflect.NativeMethodAccessorImpl.invoke0 (собственный метод) в sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) в sun.reflect.Делегирование methodaccessorimpl.invoke(делегирование methodaccessorimpl.java:43) на java.lang.reflect.Метод.invoke(Method.java:498) в org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:139) в org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295) в org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249) в org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:236) в org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:402) в org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:209) в org.jboss.resteasy.plugins.server.servlet.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) в io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) в org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) в io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) при вводе-выводе.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) в io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) в io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) в io.undertow.security.handlers.Запрос AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:53) в 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) в io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) в io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) при вводе-выводе.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50 ) в io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43 ) в io.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.вызовите (ServletInitialHandler.java:138) в io.undertow.servlet.handlers.ServletInitialHandler$2.вызовите(ServletInitialHandler.java:135) при вводе-выводе.undertow.servlet.core.ServletRequestContextThreadSetupAction$ 1.вызовите (ServletRequestContextThreadSetupAction.java:48) в io.undertow.servlet.core.ContextClassLoaderSetupAction $ 1.вызов (ContextClassLoaderSetupAction.java:43) в io.undertow.servlet.api.LegacyThreadSetupActionWrapper$ 1.вызов (LegacyThreadSetupActionWrapper.java:44) в io.undertow.servlet.api. LegacyThreadSetupActionWrapper $ 1.вызовите (LegacyThreadSetupActionWrapper.java: 44) в io.undertow.servlet.api.LegacyThreadSetupActionWrapper $1.вызовите (LegacyThreadSetupActionWrapper.java:44) в io.undertow.servlet.api.LegacyThreadSetupActionWrapper $1.вызов (LegacyThreadSetupActionWrapper.java:44) в io .undertow.servlet.api.LegacyThreadSetupActionWrapper$1.вызовите (LegacyThreadSetupActionWrapper.java:44) в io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272) в io.undertow.servlet.handlers.ServletInitialHandler.access стоимостью $ 000 (ServletInitialHandler.java:81) в io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104) в io.undertow.server.Connectors.executeRootHandler(Connectors.java:202) при вводе-выводе.undertow.server.HttpServerExchange$1.запустите (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>
  

Найден только rserve.web.RService, который находится в файле war. Есть ли у кого-нибудь опыт настройки swagger с использованием ресурсов из содержащего ear?

Комментарии:

1. Привет! Вы нашли решение для этого?

2. У меня такая же проблема. У меня ограниченная настройка WAR и, похоже, вызывает эти проблемы с загрузкой классов. Нет идей, что еще попробовать. Заполнено каждой перестановкой конфигурации, доступной в web.xml , но пока безуспешно

Ответ №1:

К сожалению, я не могу вспомнить, какие шаги на самом деле привели к решению этой проблемы, но в итоге я удалил классы ресурсов из web.xml (за исключением ресурса класса конечной точки службы RService, который содержался в war)

Я не использую какой-либо производный от 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>
  

Взгляните на:

простой пример ядра swagger

Также рассмотрите возможность проверки распространенных ошибок при плохом управлении зависимостями, которые могли быть моей проблемой тогда:

например, загрузка классов jboss: классы в ear не могут ссылаться на классы, которые были загружены загрузчиком классов war

зависимости классов ссылаются на разные классы, поскольку они были зарегистрированы дважды (war classloader, ear classloader)