swagger-parser icon indicating copy to clipboard operation
swagger-parser copied to clipboard

Resolving relative refs broken with Spring Boot 3.2

Open david0 opened this issue 1 year ago • 4 comments

Parsing schemas with refs to other files fails with the following exception, when the jar file is run:

08:35:32.381 [main] WARN io.swagger.v3.parser.OpenAPIV3Parser -- Exception while resolving:
java.lang.RuntimeException: Unable to load RELATIVE ref: ./error.openapi.yaml path: /specs
        at io.swagger.v3.parser.util.RefUtils.readExternalRef(RefUtils.java:220)
        at io.swagger.v3.parser.ResolverCache.loadRef(ResolverCache.java:156)
        at io.swagger.v3.parser.processors.ExternalRefProcessor.processRefToExternalSchema(ExternalRefProcessor.java:89)
        at io.swagger.v3.parser.processors.SchemaProcessor.processReferenceSchema(SchemaProcessor.java:238)
        at io.swagger.v3.parser.processors.SchemaProcessor.processSchema(SchemaProcessor.java:59)
        at io.swagger.v3.parser.processors.ResponseProcessor.processResponse(ResponseProcessor.java:56)
        at io.swagger.v3.parser.processors.OperationProcessor.processOperation(OperationProcessor.java:86)
        at io.swagger.v3.parser.processors.PathsProcessor.processPaths(PathsProcessor.java:88)
        at io.swagger.v3.parser.OpenAPIResolver.resolve(OpenAPIResolver.java:72)
        at io.swagger.v3.parser.OpenAPIResolver.resolve(OpenAPIResolver.java:59)
        at io.swagger.v3.parser.OpenAPIV3Parser.resolve(OpenAPIV3Parser.java:240)
        at io.swagger.v3.parser.OpenAPIV3Parser.readContents(OpenAPIV3Parser.java:183)
        at io.swagger.v3.parser.OpenAPIV3Parser.readLocation(OpenAPIV3Parser.java:97)
        at io.swagger.v3.parser.OpenAPIV3Parser.read(OpenAPIV3Parser.java:124)
        at com.example.demo.DemoApplication.main(DemoApplication.java:17)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:91)
        at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:53)
        at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:58)
Caused by: java.lang.UnsupportedOperationException: null
        at jdk.zipfs/jdk.nio.zipfs.ZipPath.toFile(ZipPath.java:669)
        at io.swagger.v3.parser.util.RefUtils.readAll(RefUtils.java:228)
        at io.swagger.v3.parser.util.RefUtils.readExternalRef(RefUtils.java:191)
        ... 21 common frames omitted
08:35:32.383 [main] INFO io.swagger.v3.parser.OpenAPIV3Parser -- io.swagger.v3.parser.OpenAPIV3Parser@75c56eb9: attribute paths.'/pets'(get).responses.default.content.'application/json'.schema.#/components/schemas/Error is missing
08:35:32.384 [main] INFO io.swagger.v3.parser.OpenAPIV3Parser -- io.swagger.v3.parser.OpenAPIV3Parser@75c56eb9: attribute paths.'/pets'(post).responses.default.content.'application/json'.schema.#/components/schemas/Error is missing
08:35:32.384 [main] INFO io.swagger.v3.parser.OpenAPIV3Parser -- io.swagger.v3.parser.OpenAPIV3Parser@75c56eb9: Unable to load RELATIVE ref: ./error.openapi.yaml path: /specs

I'm using Spring Boot 3.2.x which has a nested jar and the loader has been re-written in Spring Boot 3.2: Spring Boot 3.2 Release Notes: Nested Jar Support. This seems to break the OpenAPI Parsers way of resolving $refs.

Small project to repoduce the problem can be found here: david0/swagger-parser-spring3.2-issue2080 Don't forget to run the jar and not via IDE to reproduce the problem.

david0 avatar Apr 26 '24 06:04 david0

Hi @david0 ,

I have came accross same problem for my project ,it is working with Springboot 3.1 but getting same error with SB version 3.2 onwards.

Have you found any workaround to solve this issue?

Thanks, Sachin

sjsachinrj avatar Jun 20 '24 11:06 sjsachinrj

Yes, as a workaround you can set the loaderImplementation back to CLASSIC: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.2-Release-Notes#nested-jar-support

david0 avatar Jun 20 '24 14:06 david0

I have tried that CLASSIC loader using spring-boot-maven-plugin, but when I checked generated manifest file in jar , it still uses new jar launcher loader class. Any idea, Have I missed anything?

sjsachinrj avatar Jun 20 '24 14:06 sjsachinrj

I have modified plugin slightly , just kept configuration tag before execution tag. It works for me.

<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <loaderImplementation>CLASSIC</loaderImplementation> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>

Any update from swagger parser team when they will fix this issue?

sjsachinrj avatar Jun 21 '24 05:06 sjsachinrj