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

ResolveFully fails on internal references when the initial spec is read from a file URL

Open klease opened this issue 2 years ago • 1 comments

Hi, While testing the new 3.1.0 feature of a pathItem in components, I found that resolveFully is not replacing internal references such as $ref: "#/components/pathItems/getPet" when the initial URL to the spec is a file:// URL. There is an exception in the log like this:

java.io.FileNotFoundException: file:/...../target/test-classes/petstore-3.1.yaml (Aucun fichier ou dossier de ce type)
        at java.io.FileInputStream.open0(Native Method) ~[?:?]
        at java.io.FileInputStream.open(FileInputStream.java:216) ~[?:?]
        at java.io.FileInputStream.<init>(FileInputStream.java:157) ~[?:?]
        at java.io.FileInputStream.<init>(FileInputStream.java:111) ~[?:?]
        at io.swagger.v3.parser.reference.Visitor.readFile(Visitor.java:66) ~[swagger-parser-v3-2.1.13.jar:2.1.13]
        at io.swagger.v3.parser.reference.Visitor.readURI(Visitor.java:84) ~[swagger-parser-v3-2.1.13.jar:2.1.13]
        at io.swagger.v3.parser.reference.ReferenceVisitor.parse(ReferenceVisitor.java:279) ~[swagger-parser-v3-2.1.13.jar:2.1.13]

This is true for any internal reference from the initial specification. The Visitor.readFile() method needs to transform the file URL to a valid path. I've never contributed to swagger before but I could create a test case and PR for this issue.

klease avatar May 07 '23 16:05 klease

Yup, same here, Swagger Parser 2.1.22. I have a very basic OpenAPI 3.1 file without any external references and when I use options.setResolve(), the FileNotFoundException is logged and SwaggerParseResult contains the caught exception message.

Interestingly the issue only happens with OpenAPI 3.1 (not with OpenAPI 3.0, or Swagger 2.0).

Here's some more of the stack trace:

java.io.FileNotFoundException: file:/.../test-3.1.openapi.json (No such file or directory)
 	at java.base/java.io.FileInputStream.open0(Native Method)
 	at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
 	at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
 	at java.base/java.io.FileInputStream.<init>(FileInputStream.java:112)
 	at io.swagger.v3.parser.reference.Visitor.readFile(Visitor.java:66)
 	at io.swagger.v3.parser.reference.Visitor.readURI(Visitor.java:84)
 	at io.swagger.v3.parser.reference.ReferenceVisitor.parse(ReferenceVisitor.java:305)
 	at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef(ReferenceVisitor.java:241)
 	at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema(ReferenceVisitor.java:141)

Should Visitor.readURI() maybe strip the file: prefix before calling Visitor.readFile() or use File(URI) rather than File(String)?

edit

Workaround: strip the file: scheme from the URI before passing it to parseLocation(). Instead of using getResource( "x" ).toURI(), you can use URI.create( getResource( "x" ).toString().replaceFirst( "^file:", "" )

jpommerening avatar Jul 11 '24 14:07 jpommerening