diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java index 58e9201f1f..2dffb33439 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/OpenAPIV3Parser.java @@ -197,19 +197,36 @@ public SwaggerParseResult readContents(String swaggerAsString, List getExtensions() { + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + List extensions = getExtensions(tccl); + ClassLoader cl = SwaggerParserExtension.class.getClassLoader(); + if (cl != tccl) { + extensions.addAll(getExtensions(cl)); + } + extensions.add(0, new OpenAPIV3Parser()); + return extensions; + } + + protected List getExtensions(ClassLoader cl) { List extensions = new ArrayList<>(); - ServiceLoader loader = ServiceLoader.load(SwaggerParserExtension.class); + ServiceLoader loader = ServiceLoader.load(SwaggerParserExtension.class, cl); Iterator itr = loader.iterator(); while (itr.hasNext()) { extensions.add(itr.next()); } - extensions.add(0, new OpenAPIV3Parser()); return extensions; } - /** + /** * Transform the swagger-model version of AuthorizationValue into a parser-specific one, to avoid * dependencies across extensions * diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java index 7e2eb2d52b..ab02650f62 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java @@ -1803,6 +1803,23 @@ public void shouldParseExternalSchemaModelHavingReferenceToItsLocalModel() { assertThat(((Schema) modelSchema.getProperties().get("id")).get$ref(), equalTo("#/components/schemas/ValueId")); } + + @Test(description = "Test that extensions can be found on the class classloader in addition to tccl.") + public void testIssue1003_ExtensionsClassloader() { + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + OpenAPI api = null; + try { + // Temporarily switch tccl to an unproductive cl + final ClassLoader tcclTemp = new java.net.URLClassLoader(new java.net.URL[] {}, + ClassLoader.getSystemClassLoader()); + Thread.currentThread().setContextClassLoader(tcclTemp); + api = new OpenAPIV3Parser().read("src/test/resources/test.yaml"); + } finally { + Thread.currentThread().setContextClassLoader(tccl); + } + assertNotNull(api); + } + @Test public void shouldParseApiWithMultipleParameterReferences() { // given @@ -1821,6 +1838,7 @@ public void shouldParseApiWithMultipleParameterReferences() { assertThat(parameters.get("NameParam").getName(), equalTo("name")); assertThat(result.getMessages(), equalTo(emptyList())); + } private static int getDynamicPort() {