jvacaq
Estoy tratando de iniciar un proyecto Spring Boot usando OpenJDK 15, Spring Boot 2.6.0, Springfox 3.
Estamos trabajando en un proyecto que reemplazó Neto como servidor web y usé Jetty en su lugar, porque no necesitamos un entorno sin bloqueo.
En el código dependemos principalmente de Reactor API (Flux, Mono), por lo que no podemos eliminar org.springframework.boot:spring-boot-starter-webflux
dependencias
Repliqué el problema que tenemos en un nuevo proyecto: https://github.com/jvacaq/spring-zorro.
Descubrí que estas líneas en nuestro construir.gradle archivo son el origen del problema.
compile("org.springframework.boot:spring-boot-starter-web") {
exclude module: "spring-boot-starter-tomcat"
}
compile("org.springframework.boot:spring-boot-starter-jetty")
Aquí está el construir.gradle expediente:
plugins {
id 'org.springframework.boot' version '2.6.0'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
repositories {
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web") {
exclude module: "spring-boot-starter-tomcat"
}
compile("org.springframework.boot:spring-boot-starter-jetty")
implementation 'org.springframework.boot:spring-boot-starter-webflux'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'io.projectreactor:reactor-test'
implementation "io.springfox:springfox-boot-starter:3.0.0"
}
test {
useJUnitPlatform()
}
Emití el comando gradle clean bootrun
. El resultado es este error:
gradle clean bootrun
> Task :bootRun FAILED
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.0)
2021-11-19 09:41:06.665 INFO 16666 --- [ main] c.e.springfox.SpringFoxApplication : Starting SpringFoxApplication using Java 15.0.2 on advance-Inspiron-5379 with PID 16666 (/home/advance/projects/spring-fox/build/classes/java/main started by advance in /home/advance/projects/spring-fox)
2021-11-19 09:41:06.666 INFO 16666 --- [ main] c.e.springfox.SpringFoxApplication : No active profile set, falling back to default profiles: default
2021-11-19 09:41:07.294 INFO 16666 --- [ main] org.eclipse.jetty.util.log : Logging initialized @1132ms to org.eclipse.jetty.util.log.Slf4jLog
2021-11-19 09:41:07.396 INFO 16666 --- [ main] o.s.b.w.e.j.JettyServletWebServerFactory : Server initialized with port: 8080
2021-11-19 09:41:07.398 INFO 16666 --- [ main] org.eclipse.jetty.server.Server : jetty-9.4.44.v20210927; built: 2021-09-27T23:02:44.612Z; git: 8da83308eeca865e495e53ef315a249d63ba9332; jvm 15.0.2+7-27
2021-11-19 09:41:07.417 INFO 16666 --- [ main] o.e.j.s.h.ContextHandler.application : Initializing Spring embedded WebApplicationContext
2021-11-19 09:41:07.417 INFO 16666 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 713 ms
2021-11-19 09:41:07.474 INFO 16666 --- [ main] org.eclipse.jetty.server.session : DefaultSessionIdManager workerName=node0
2021-11-19 09:41:07.474 INFO 16666 --- [ main] org.eclipse.jetty.server.session : No SessionScavenger set, using defaults
2021-11-19 09:41:07.475 INFO 16666 --- [ main] org.eclipse.jetty.server.session : node0 Scavenging every 660000ms
2021-11-19 09:41:07.480 INFO 16666 --- [ main] o.e.jetty.server.handler.ContextHandler : Started o.s.b.w.e.j.JettyEmbeddedWebAppContext@6aa3bfc{application,/,[file:///tmp/jetty-docbase.8080.2024342829220941812/, jar:file:/home/advance/.gradle/caches/modules-2/files-2.1/io.springfox/springfox-swagger-ui/3.0.0/1e665fbe22148f7c36fa8a08e515a0047cd4390b/springfox-swagger-ui-3.0.0.jar!/META-INF/resources],AVAILABLE}
2021-11-19 09:41:07.480 INFO 16666 --- [ main] org.eclipse.jetty.server.Server : Started @1318ms
2021-11-19 09:41:07.920 INFO 16666 --- [ main] o.e.j.s.h.ContextHandler.application : Initializing Spring DispatcherServlet 'dispatcherServlet'
2021-11-19 09:41:07.920 INFO 16666 --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2021-11-19 09:41:07.921 INFO 16666 --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2021-11-19 09:41:07.931 INFO 16666 --- [ main] o.e.jetty.server.AbstractConnector : Started ServerConnector@2643d762{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-11-19 09:41:07.932 INFO 16666 --- [ main] o.s.b.web.embedded.jetty.JettyWebServer : Jetty started on port(s) 8080 (http/1.1) with context path "https://stackoverflow.com/"
2021-11-19 09:41:07.934 WARN 16666 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null
2021-11-19 09:41:07.949 INFO 16666 --- [ main] o.e.jetty.server.AbstractConnector : Stopped ServerConnector@2643d762{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2021-11-19 09:41:07.950 INFO 16666 --- [ main] org.eclipse.jetty.server.session : node0 Stopped scavenging
2021-11-19 09:41:07.951 INFO 16666 --- [ main] o.e.j.s.h.ContextHandler.application : Destroying Spring FrameworkServlet 'dispatcherServlet'
2021-11-19 09:41:07.951 INFO 16666 --- [ main] o.e.jetty.server.handler.ContextHandler : Stopped o.s.b.w.e.j.JettyEmbeddedWebAppContext@6aa3bfc{application,/,[file:///tmp/jetty-docbase.8080.2024342829220941812/, jar:file:/home/advance/.gradle/caches/modules-2/files-2.1/io.springfox/springfox-swagger-ui/3.0.0/1e665fbe22148f7c36fa8a08e515a0047cd4390b/springfox-swagger-ui-3.0.0.jar!/META-INF/resources],STOPPED}
2021-11-19 09:41:07.958 INFO 16666 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-11-19 09:41:07.970 ERROR 16666 --- [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-5.3.13.jar:5.3.13]
at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54) ~[spring-context-5.3.13.jar:5.3.13]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-5.3.13.jar:5.3.13]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-5.3.13.jar:5.3.13]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-5.3.13.jar:5.3.13]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935) ~[spring-context-5.3.13.jar:5.3.13]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586) ~[spring-context-5.3.13.jar:5.3.13]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.0.jar:2.6.0]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) ~[spring-boot-2.6.0.jar:2.6.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) ~[spring-boot-2.6.0.jar:2.6.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) ~[spring-boot-2.6.0.jar:2.6.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.0.jar:2.6.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290) ~[spring-boot-2.6.0.jar:2.6.0]
at com.example.springfox.SpringFoxApplication.main(SpringFoxApplication.java:10) ~[main/:na]
Caused by: java.lang.NullPointerException: Cannot invoke "org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null
at springfox.documentation.spring.web.WebMvcPatternsRequestConditionWrapper.getPatterns(WebMvcPatternsRequestConditionWrapper.java:56) ~[springfox-spring-webmvc-3.0.0.jar:3.0.0]
at springfox.documentation.RequestHandler.sortedPaths(RequestHandler.java:113) ~[springfox-core-3.0.0.jar:3.0.0]
at springfox.documentation.spi.service.contexts.Orderings.lambda$byPatternsCondition$3(Orderings.java:89) ~[springfox-spi-3.0.0.jar:3.0.0]
at java.base/java.util.Comparator.lambda$comparing$77a9974f$1(Comparator.java:469) ~[na:na]
at java.base/java.util.TimSort.countRunAndMakeAscending(TimSort.java:355) ~[na:na]
at java.base/java.util.TimSort.sort(TimSort.java:220) ~[na:na]
at java.base/java.util.Arrays.sort(Arrays.java:1306) ~[na:na]
at java.base/java.util.ArrayList.sort(ArrayList.java:1721) ~[na:na]
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:392) ~[na:na]
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:na]
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:na]
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:na]
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:258) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
at springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider.requestHandlers(WebMvcRequestHandlerProvider.java:81) ~[springfox-spring-webmvc-3.0.0.jar:3.0.0]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) ~[na:na]
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) ~[na:na]
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) ~[na:na]
at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.withDefaults(AbstractDocumentationPluginsBootstrapper.java:107) ~[springfox-spring-web-3.0.0.jar:3.0.0]
at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.buildContext(AbstractDocumentationPluginsBootstrapper.java:91) ~[springfox-spring-web-3.0.0.jar:3.0.0]
at springfox.documentation.spring.web.plugins.AbstractDocumentationPluginsBootstrapper.bootstrapDocumentationPlugins(AbstractDocumentationPluginsBootstrapper.java:82) ~[springfox-spring-web-3.0.0.jar:3.0.0]
at springfox.documentation.spring.web.plugins.DocumentationPluginsBootstrapper.start(DocumentationPluginsBootstrapper.java:100) ~[springfox-spring-web-3.0.0.jar:3.0.0]
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:178) ~[spring-context-5.3.13.jar:5.3.13]
... 14 common frames omitted
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':bootRun'.
> Process 'command '/home/advance/.sdkman/candidates/java/15.0.2-open/bin/java'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.
Use '--warning-mode all' to show the individual deprecation warnings.
See https://docs.gradle.org/6.9.1/userguide/command_line_interface.html#sec:command_line_warnings
BUILD FAILED in 2s
5 actionable tasks: 5 executed
¿Cómo puedo resolverlo?
andy wilkinson
Este problema es causado por un error en Springfox. Es hacer una suposición acerca de cómo se configura Spring MVC que no siempre es cierta. Específicamente, se supone que la coincidencia de rutas de MVC utilizará el comparador de rutas basado en Ant y no el comparador basado en PathPattern. La coincidencia basada en PathPattern ha sido una opción desde hace algún tiempo y es la opción predeterminada a partir de Spring Boot 2.6.
Como descrito en las notas de la versión de Spring Boot 2.6puede restaurar la configuración que Springfox supone que se usará configurando spring.mvc.pathmatch.matching-strategy
a ant-path-matcher
en tus application.properties
expediente. Tenga en cuenta que esto solo funcionará si no está utilizando el Actuador de Spring Boot. Actuator siempre utiliza el análisis basado en PathPattern, independientemente de la configuración matching-strategy
. Se requerirá un cambio a Springfox si desea usarlo con Actuator en Spring Boot 2.6 y versiones posteriores.
-
Gracias por tu respuesta. Pero agregar la siguiente línea en application.properties no funcionó. Y tengo la misma excepción.
spring.mvc.pathmatch.matching-strategy=ant_path_matcher
– Ubaid ur Rehman
20 de noviembre de 2021 a las 14:38
-
En la versión Swagger 2 (2.9.2), esta solución también funciona bien, muchas gracias.
– Smyhail
5 de diciembre de 2021 a las 18:46
-
He notado que esta solución EXCEPTO que no es compatible con
spring-boot-starter-actuator
. Una vez que se eliminó, todos mis submódulos trabajaron con la solución ant_path_matcher.–Paul Cuddihy
5 de enero a las 18:17
-
Como Pablo comentó anteriormente,
spring-boot-starter-actuator
también hay que echarlo.– Yang Liu
23 de enero a las 22:04
-
@gstackoverflow Creo que sí, sí. Hasta que haya una nueva versión de Springfox, debe cambiar a Spring Boot 2.5 o pasar de Springfox a una alternativa como Springdoc. Lamentablemente, Springfox no parece ser tan activo como antes, por lo que recomendaría considerar alternativas de todos modos.
–Andy Wilkinson
26 de enero a las 10:58
fuego helado
La solución alternativa mencionada en el siguiente comentario del problema parece funcionar también para las personas con actuador de resorte. Simplemente cambiar el comparador de ruta no funcionará para proyectos que usan actuador.
-
Establecer en
application.properties
expediente:spring.mvc.pathmatch.matching-strategy
aant_path_matcher
-
Añade el
@Bean
abajo:
@Bean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(
WebEndpointsSupplier webEndpointsSupplier,
ServletEndpointsSupplier servletEndpointsSupplier,
ControllerEndpointsSupplier controllerEndpointsSupplier,
EndpointMediaTypes endpointMediaTypes,
CorsEndpointProperties corsProperties,
WebEndpointProperties webEndpointProperties,
Environment environment) {
List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
allEndpoints.addAll(webEndpoints);
allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
String basePath = webEndpointProperties.getBasePath();
EndpointMapping endpointMapping = new EndpointMapping(basePath);
boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(
webEndpointProperties, environment, basePath);
return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints,
endpointMediaTypes, corsProperties.toCorsConfiguration(),
new EndpointLinksResolver(allEndpoints, basePath),
shouldRegisterLinksMapping, null);
}
private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties,
Environment environment, String basePath) {
return webEndpointProperties.getDiscovery().isEnabled() &&
(StringUtils.hasText(basePath) ||
ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
}
Referencia:
-
¡Gracias! Esta parece ser la mejor respuesta si no desea degradar Spring o es demasiado trabajo cambiar a SpringDoc.
– Steven K.
4 de febrero a las 17:27
-
La aplicación funciona después de agregar esto, pero swagger no funciona. Supongo que cambiaré a springdoc
– Rstar37
8 jun a las 21:46
-
La mejor respuesta en mi opinión! Especialmente si el requisito es no degradar springboot y resolver vulnerabilidades.
– Vinja Ninja
9 ago a las 8:47
ℛɑƒaeĿᴿᴹᴿ
solo agregando @EnableWebMvc
en la clase principal debería resolver el problema:
@EnableWebMvc
@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class);
}
}
-
TBH Lo acabo de intentar y no funcionó. Por eso voté negativo.
– Giorgio Vespucci
22 abr a las 14:56
-
Muchas gracias, muchos comentarios sobre la versión de Swagger o Spring que no solucionaban, solo añadían
@EnableWebMvc
¡trabajó para mi!– Renán Ribeiro
30 de mayo a las 19:20
-
Esto solucionó el problema para mí. Estoy usando Spring Boot versión 2.7.0
– Dinesh Arora
27 de julio a las 15:51
-
Funcionó en mi caso @GiorgioVespucci. Que no funcione en su caso no es en sí mismo una razón para votar a la baja.
– cometen
el dia de ayer
-
funcionó para mí
– Kumaresan Perumal
el dia de ayer
Eren
No es una solución pero…
he degradado spring-boot-starter-parent
versión de 2.6.0
a 2.5.6
y empezó a funcionar.
mauricio toledo
Completaré lo que Anatoly mencionó sobre el uso springdoc-openapi.
Primero agrega el springdoc-openapi
dependencia a su Gradle build.gradle
(o experto pom.xml
):
// build.gradle
implementation "org.springdoc:springdoc-openapi-ui:1.6.4"
Agregar OpenAPIDefinition
anotación a su clase principal:
@SpringBootApplication
@OpenAPIDefinition
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Ahora puedes ir a {URI}/swagger-ui/index.html
y funcionará mostrando la vista swagger.
-
¿La API abierta funciona igual que Swagger? IU y todo lo demás? ¿Necesitamos cambiar algo más?
– Naveen
26 de febrero a las 19:10
-
Sí, lo mismo que swagger.
–Mauricio Toledo
9 de marzo a las 18:45
-
Gracias por tu respuesta. Funciona de maravilla. fácil y práctico
– Lakshman
3 de septiembre a las 9:28
ℛɑƒaeĿᴿᴹᴿ
La solución popular que anula una definición de WebMvcEndpointHandlerMapping
no me funcionaba en algunos entornos con JDK 17, Boot+Actuator 2.6, Springfox 3.
Esto, sin embargo, funciona para mí en todos los lugares donde lo necesito (desarrollo local y contenedores de CloudFoundry):
@Bean
public WebMvcRequestHandlerProvider webMvcRequestHandlerProvider(
Optional<ServletContext> context,
HandlerMethodResolver methodResolver,
List<RequestMappingInfoHandlerMapping> handlerMappings) {
handlerMappings = handlerMappings.stream()
.filter(rh -> rh.getClass().getName().contains("RequestMapping")).toList();
return new WebMvcRequestHandlerProvider(context, methodResolver, handlerMappings);
}
Escribí un poco más sobre eso. en el hilo de GitHub.
-
¿La API abierta funciona igual que Swagger? IU y todo lo demás? ¿Necesitamos cambiar algo más?
– Naveen
26 de febrero a las 19:10
-
Sí, lo mismo que swagger.
–Mauricio Toledo
9 de marzo a las 18:45
-
Gracias por tu respuesta. Funciona de maravilla. fácil y práctico
– Lakshman
3 de septiembre a las 9:28
Indeciso
Simplemente agregue esto a su archivo application.properties:spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER.
-
no funciona como una solución … sigue siendo el mismo error
– Oleksandr Yefymov
31 ago a las 18:21
Considere la migración a springdoc
– Anatoli Shipov
25 de noviembre de 2021 a las 5:19
Gracias, migré a Springdoc. No puedo esperar una solución del equipo de Springfox.
– jvacaq
25 de noviembre de 2021 a las 15:24
Solo agregue @EnableWebMvc en la clase principal resolvió el problema. stackoverflow.com/a/70703081/5626568
– ℛɑƒæĿᴿᴹᴿ
13 ene a las 21:20
No es un esfuerzo trivial migrar una configuración de springfox a springdoc si tiene cierta complejidad en su configuración.
– IcedDante
18 de enero a las 18:14
También migró a springdoc. La complejidad de esa tarea probablemente dependerá de su proyecto, pero resolvió mi problema y me colocó en una biblioteca que se actualizó hace un mes en lugar de hace un año y medio.
– matt forsythe
18 de marzo a las 13:36