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

File Path Issue on Windows with OAS 3.1 - Illegal character in opaque part at index

Open gexclaude opened this issue 1 year ago • 5 comments

We encountered the issue here, when using OpenAPITools Generator (Maven Plugin) after we switched from OAS 3.0.3 to 3.1.0: https://github.com/OpenAPITools/openapi-generator/issues/18161

As the Issue on OpenAPITools indicates, the error might be in the swagger-parser. At least we see in the stacktrace, that the error happens there. Is this a known issue?

Our full stack trace.

java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\repos\my-project\api/src/main/resources/oas31-api.yaml
at java.net.URI$Parser.fail (URI.java:2995)
at java.net.URI$Parser.checkChars (URI.java:3166)
at java.net.URI$Parser.parse (URI.java:3202)
at java.net.URI.<init> (URI.java:645)
at io.swagger.v3.parser.reference.ReferenceUtils.resolve (ReferenceUtils.java:29)
at io.swagger.v3.parser.reference.ReferenceVisitor.resolveSchemaRef (ReferenceVisitor.java:227)
at io.swagger.v3.parser.reference.ReferenceVisitor.visitSchema (ReferenceVisitor.java:141)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseSchema (OpenAPI31Traverser.java:790)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMediaType (OpenAPI31Traverser.java:603)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap (OpenAPI31Traverser.java:933)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseRequestBody (OpenAPI31Traverser.java:346)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOperation (OpenAPI31Traverser.java:229)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePathItem (OpenAPI31Traverser.java:424)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseMap (OpenAPI31Traverser.java:933)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traversePaths (OpenAPI31Traverser.java:197)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverseOpenApi (OpenAPI31Traverser.java:124)
at io.swagger.v3.parser.reference.OpenAPI31Traverser.traverse (OpenAPI31Traverser.java:65)
at io.swagger.v3.parser.reference.OpenAPIDereferencer31.dereference (OpenAPIDereferencer31.java:74)
at io.swagger.v3.parser.OpenAPIV3Parser.resolve (OpenAPIV3Parser.java:227)
at io.swagger.v3.parser.OpenAPIV3Parser.readContents (OpenAPIV3Parser.java:183)
at io.swagger.v3.parser.OpenAPIV3Parser.readLocation (OpenAPIV3Parser.java:97)
at io.swagger.parser.OpenAPIParser.readLocation (OpenAPIParser.java:16)
at org.openapitools.codegen.config.CodegenConfigurator.toContext (CodegenConfigurator.java:686)
at org.openapitools.codegen.config.CodegenConfigurator.toClientOptInput (CodegenConfigurator.java:744)
at org.openapitools.codegen.plugin.CodeGenMojo.execute (CodeGenMojo.java:940)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:126)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:328)
at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:316)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:212)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:174)
at org.apache.maven.lifecycle.internal.MojoExecutor.access$000 (MojoExecutor.java:75)
at org.apache.maven.lifecycle.internal.MojoExecutor$1.run (MojoExecutor.java:162)
at org.apache.maven.plugin.DefaultMojosExecutionStrategy.execute (DefaultMojosExecutionStrategy.java:39)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:159)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:105)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:73)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:53)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:118)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:261)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:173)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:101)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:903)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:280)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:203)
at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:103)
at java.lang.reflect.Method.invoke (Method.java:580)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:255)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:201)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:361)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:314)
at org.codehaus.classworlds.Launcher.main (Launcher.java:41)

gexclaude avatar Nov 04 '24 13:11 gexclaude

I'm experiencing this same issue with the file path having the wrong slashes

DaleGardner avatar Nov 08 '24 05:11 DaleGardner

I had the same issue in the same context as @gexclaude (same stack trace).

So you probably parse an openapi file with internal references like this :

schema:
  $ref: '#/components/schemas/Departement'

When the parser has to resolve relative location in $ref, it uses the baseUri of the openapi document to locate it. The problem is the parser is not supplied with an URI for the base document. When you use swagger parser with the openapi-generator, the base URI of the document is provided in the <inputSpec> element of the configuration of the openapi-generator-maven-plugin

So, in my context, I changed the <inputSpec> configuration element of the openapi-generator-maven-plugin to an URI and it solves the probelm :

<!-- path after ${project.baseUri} depends of the location of your openapi.yaml file and wether it is packaged or not at build -->
<inputSpec>${project.baseUri}/target/openapi.yaml</inputSpec>

Hope this helps

FBibonne avatar Feb 04 '25 06:02 FBibonne

My team hit the same issue, and moving to ${project.baseUri} corrects this specific error that we see on Windows machines. However, when we make that change to the input spec reference in pom.xml, the java classes generated using the same input spec file are now different

When using project.baseUri to reference the location of the spec, the output from the openapi generator now includes classes generated with the 'inner' postfix that duplicate the actual underlying class. This then breaks all of the interface contracts on the consumer side.

shavemi avatar Feb 28 '25 14:02 shavemi

@shavemi I observed too the issue with some classes generated with the inner prefix. In my case, classes which map items schema of arrays are impacted. I used the inlineSchemaNameMappings option of the openapi generator to solve this.

As an example, if you consider the following openapi piece of spec :

components:
  schemas:
        DepartementListeProjetesAvecChefLieu:
      description: 'Liste des départements projetés'
      type: array
      xml:
        wrapped: true
        name: ListeDepartementsProjetes
      items:
        $ref: '#/components/schemas/TerritoireBase_ChefLieu'

where DepartementListeProjetesAvecChefLieu is referred elsewhere in the spec with $ref: '#/components/schemas/DepartementListeProjetesAvecChefLieu' . When I used project.baseUri without inlineSchemaNameMappings, openapi generator generates a class ListeDepartementsProjetesInner which is used as a List<ListeDepartementsProjetesInner> in generated controller interfaces which is an unexpected behaviour.

If I changed the config of openapi generator maven plugin adding inside <configuration> element

<inlineSchemaNameMappings>DepartementListeProjetesAvecChefLieu_inner=TerritoireBase_ChefLieu</inlineSchemaNameMappings>

after generating, there is no more class ListeDepartementsProjetesInner and I get the expected List<TerritoireBaseChefLieu> in generated controller interfaces.

FBibonne avatar Mar 08 '25 13:03 FBibonne

We also encountered the same problem. In fact, the source of this error is not in the JSON, but in the file path.

java.net.URISyntaxException: Illegal character in opaque part at index 2: C:\repos\my-project\api/src/main/resources/oas31-api.yaml
at java.net.URI$Parser.fail (URI.java:2995)
at java.net.URI$Parser.checkChars (URI.java:3166)
at java.net.URI$Parser.parse (URI.java:3202)
at java.net.URI.<init> (URI.java:645)
at io.swagger.v3.parser.reference.ReferenceUtils.resolve (ReferenceUtils.java:29)

means \ in C:\repos\.... not valid.

Detail codes can see ReferenceUtils.java:29 in ReferenceUtils.resolve

How to reproduce:

Image

Change C:\repos\my-project\api/src/main/resources/oas31-api.yaml to C:/repos/my-project/api/src/main/resources/oas31-api.yaml

will resolve this bug.

dannyZhou avatar Mar 26 '25 06:03 dannyZhou

Hi everyone, Thanks a lot for the discussion and all the input on this issue! It looks like the problem has already been addressed in PR #2230, so I’m closing this ticket. If you notice any remaining edge cases or regressions, please feel free to open a new one.

djankows avatar Nov 07 '25 09:11 djankows