OpenAPITools / openapi-diff

Utility for comparing two OpenAPI specifications.
Apache License 2.0
787 stars 152 forks source link

Unexpected exception. Reason: class io.swagger.v3.oas.models.media.Schema cannot be cast to class io.swagger.v3.oas.models.media.ArraySchema #423

Closed KaiSuchomel closed 1 year ago

KaiSuchomel commented 1 year ago

Hey, with the attached yamls (see yamls.zip) we get the following Exception:

Unexpected exception. Reason: class io.swagger.v3.oas.models.media.Schema cannot be cast to class io.swagger.v3.oas.models.media.ArraySchema (io.swagger.v3.oas.models.media.Schema and io.swagger.v3.oas.models.media.ArraySchema are in unnamed module of loader 'app')
java.lang.ClassCastException: class io.swagger.v3.oas.models.media.Schema cannot be cast to class io.swagger.v3.oas.models.media.ArraySchema (io.swagger.v3.oas.models.media.Schema and io.swagger.v3.oas.models.media.ArraySchema are in unnamed module of loader 'app')
    at org.openapitools.openapidiff.core.compare.schemadiffresult.ArraySchemaDiffResult.diff(ArraySchemaDiffResult.java:26)
    at org.openapitools.openapidiff.core.compare.SchemaDiff.computeDiffForReal(SchemaDiff.java:354)
    at org.openapitools.openapidiff.core.compare.SchemaDiff.computeDeferredDiff(SchemaDiff.java:330)
    at org.openapitools.openapidiff.core.compare.SchemaDiff.diff(SchemaDiff.java:309)
    at org.openapitools.openapidiff.core.compare.SchemaDiff.diff(SchemaDiff.java:301)
    at org.openapitools.openapidiff.core.compare.ContentDiff.lambda$diff$1(ContentDiff.java:44)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
    at org.openapitools.openapidiff.core.compare.ContentDiff.diff(ContentDiff.java:32)
    at org.openapitools.openapidiff.core.compare.ResponseDiff.computeDiff(ResponseDiff.java:60)
    at org.openapitools.openapidiff.core.compare.ResponseDiff.computeDiff(ResponseDiff.java:16)
    at org.openapitools.openapidiff.core.compare.ReferenceDiffCache.cachedDiff(ReferenceDiffCache.java:52)
    at org.openapitools.openapidiff.core.compare.ResponseDiff.diff(ResponseDiff.java:42)
    at org.openapitools.openapidiff.core.compare.ApiResponseDiff.diff(ApiResponseDiff.java:35)
    at org.openapitools.openapidiff.core.compare.OperationDiff.diff(OperationDiff.java:91)
    at org.openapitools.openapidiff.core.compare.PathDiff.diff(PathDiff.java:39)
    at org.openapitools.openapidiff.core.compare.PathsDiff.lambda$diff$3(PathsDiff.java:89)
    at java.base/java.util.LinkedHashMap$LinkedKeySet.forEach(LinkedHashMap.java:589)
    at org.openapitools.openapidiff.core.compare.PathsDiff.diff(PathsDiff.java:47)
    at org.openapitools.openapidiff.core.compare.OpenApiDiff.compare(OpenApiDiff.java:96)
    at org.openapitools.openapidiff.core.compare.OpenApiDiff.compare(OpenApiDiff.java:64)
    at org.openapitools.openapidiff.core.OpenApiCompare.fromSpecifications(OpenApiCompare.java:102)
    at org.openapitools.openapidiff.core.OpenApiCompare.fromLocations(OpenApiCompare.java:91)
    at org.openapitools.openapidiff.cli.Main.main(Main.java:175)

yamls.zip

Command: java -jar cli/target/openapi-diff-cli-2.1.0-SNAPSHOT-all.jar openapi_prev.yaml openapi.yaml

KaiSuchomel commented 1 year ago

see https://github.com/OpenAPITools/openapi-diff/issues/418#issue-1381915031

gituserjava commented 1 year ago

I am getting similar error; could you please let me know when the fix will be available?

joschi commented 1 year ago

@KaiSuchomel The issue in your specific case is that the old OpenAPI specification is invalid with regards to defining arrays (emphasize is mine):

Arrays are defined as:

type: array
items:
  type: string

Unlike JSON Schema, the items keyword is required in arrays. The value of items is a schema that describes the type and format of array items.

https://swagger.io/docs/specification/data-models/data-types/#array

Your OpenAPI specification contains something like this:

--- core/src/test/resources/issue-423_1.yaml    2023-02-26 00:02:52
+++ core/src/test/resources/issue-423_2.yaml    2023-02-25 23:55:36
@@ -26,8 +26,8 @@
             application/json:
               schema:
                 type: array
-                #items:
-                 # $ref: '#/components/schemas/OrganizationUnitCurrentConditionView'
+                items:
+                  $ref: '#/components/schemas/OrganizationUnitCurrentConditionView'

When adding a (rather generic) type for the array items, things are working as expected:


--- core/src/test/resources/issue-423_1.yaml    2023-02-26 00:02:52
+++ core/src/test/resources/issue-423_2.yaml    2023-02-25 23:55:36
@@ -26,8 +26,8 @@
             application/json:
               schema:
                 type: array
                 items:
-                  type: object
+                  $ref: '#/components/schemas/OrganizationUnitCurrentConditionView'
KaiSuchomel commented 1 year ago

@joschi Both Yamls seems to be valid. (https://apitools.dev/swagger-parser/online/) We are getting the yamls from the Quarkus Extension (https://quarkus.io/guides/openapi-swaggerui). We are not able to change the generation of the yamls.

joschi commented 1 year ago

@KaiSuchomel Could you please open a bug report in the upstream project https://github.com/swagger-api/swagger-parser for this?

The parser doesn't recognize it as an array schema but only as a generic schema in your "old" version of the spec.

This being said, the OpenAPI spec is clear in that the items property is required for array schemas.

I'd recommend opening a bug report in the Quarkus project and https://github.com/APIDevTools/swagger-parser, too.